-
New Feature
-
Resolution: Unresolved
-
Critical
-
Powered by SuggestiMate
Currently CpsScmFlowDefinition enforces sandbox mode on the grounds that whole-script approval is unrealistic (an administrator would need to approve every SCM revision, and Jenkins cannot automatically approve revisions like it could from GUI changes to a CpsFlowDefinition by an administrator).
There should however be an option to simply trust the script as it comes from the SCM. This could be checked by default if Jenkins were unsecured; for a secured Jenkins, the default should remain to use the sandbox, though you could switch to trusted mode with a stern warning in form validation explaining that you are responsible for auditing all changes to that SCM repository, and noting that attackers with SCM access could take over control of Jenkins in ways that might make auditing difficult. (For example, someone with push access to a Git repository could push a script which obtains the API token of a legitimate Jenkins administrator, mails it to the attacker, then deletes the current build record; and finally force-push the attacking script out of existence except via the reflog.)
Pending such an option, the workaround is given by the tutorial here: define a CpsFlowDefinition with an approved script that checks out the SCM and uses load to run it. This has the same effect at the price of more awkward configuration.
- is related to
-
JENKINS-25784 Select sandbox mode by default if current user lacks RUN_SCRIPTS
-
- Resolved
-
[JENKINS-28178] Option to disable sandbox in CpsScmFlowDefinition
bilke well of course you would need to uncheck the sandbox option in the job configuration too.
No, currently multibranch does reuse CpsScmFlowDefinition including the forced sandbox=true.
Probably this needs to be handled in that case using a BranchProperty: while you may be comfortable permitting unsandboxed execution from Jenkinsfile contents in origin/master, you would not want to allow that in a pull request on a publicly visible repository. TBD what the policy should be: allowing a customized Jenkinsfile if run in the sandbox, or just pinning a Jenkinsfile from the base branch you control.
In other words, I consider the multibranch variant of this issue to be distinct.
jglick Is there a separate issue created for the multibranch variant of this issue?
We are using the global workflow library. The setup was working with a standard workflow, but getting a RejectedAccessException after switching to the multibranch workflow which I understand from your comment forces groovy sandbox mode.
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified field java.util.ArrayList name at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.rejectField(SandboxInterceptor.java:182) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:174)
How can I authorize the properties our workflow expects so that we can use the multibranch workflow?
PS - the lines that trigger RejectedAccessExceptions with our multibranch workflow are as follows:
// triggers RejectedAccessException: unclassified field java.util.ArrayList name def choices = skipDeploy + "\n" config.deployTargets*.name.join('\n')
and
// triggers RejectedAccessException: Scripts not permitted to use staticMethod def selectedTarget = config.deployTargets.findResult({ it.name == deployTarget ? it : null })
The ArrayList.name issue sounds like a bug in script-security which was already fixed; make sure you are running the latest version. It is possible you found a new corner case, of course. Best to report it in a separate issue with a standalone reproducible test case if you can come up with one.
findResult could be whitelisted but it is probably not going to work anyway (with or without the sandbox) due to JENKINS-26481. At least I am guessing that is the method you are talking about; the exception message was apparently truncated.
FWIW, we are running into the same multibranch RejectedAccessExceptions from simple string manipulation.
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method java.lang.String substring int
I almost think it could be useful to have the possibility of a whitelist extension file. I.e. methods that I feel are safe for my own Jenkins instance.
And perhaps a way to mark which branches require sandboxing, or a way to not sandbox a pull request, if the script hasn't changed? Its pretty tricky, as you say.
You mentioned that this is a unique issue. Is there already logged a ticket for this multibranch situation?
I almost think it could be useful to have the possibility of a whitelist extension file. I.e. methods that I feel are safe for my own Jenkins instance.
Manage Jenkins » In-process Script Approvals
just pinning a Jenkinsfile from the base branch you control
Already implemented in the case of the GitHub branch source, so I do not suppose anything special need be done for multibranch support other than a higher-level option to disable the sandbox that would get propagated down to the branch projects.
We develop Pipeline scripts (stored in SCM) using staging Jenkins instance and then use them on multiple production Jenkins instances. To do this we need to re-approve all methods one by one again on each of production Jenkins (including such non-harmful methods like "java.lang.String equalsIgnoreCase java.lang.String" or "java.util.Map containsKey java.lang.Object").
Would it be possible for the administrator user to export the list off all approvals from one Jenkins and import them to another instance (just copying scriptApproval.xml seems not to work because of hash)? If only administrator is allowed to do it, it would be secure since he could review the file before uploading and only previously approved methods would be allowed.
gitt You can update the whitelist with a plugin:
@Extension public static class MiscWhitelist extends ProxyWhitelist { /** * Methods to add to the script-security whitelist for this plugin to work. * * @throws IOException */ public MiscWhitelist() throws IOException { super(new StaticWhitelist( "method java.util.Map containsKey java.lang.Object", "method java.lang.Class isInstance java.lang.Object" } }
If you encapsulate your whitelist in a plugin then you simply need to install the plugin on each master where you want to apply it.
Hi I have some jenkinfiles which worked perfectly when I just copied them to a simple pipeline job. After shifting to a multibranch or jenkinsfile from scm all of them get a rejected access exception, which makes sense due to groovy sand boxing
ERROR: Failed: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.util.HashMap
on a command, which is just parsing an xml from a get with curl
13:55:28 + xmllint --xpath string(//action/cause/shortDescription) JENKINS_REST_API_RESULTS
[Pipeline] readFile
[Pipeline] error
[Pipeline] echo
My problem is I have admin privileges for jenkins. I also have permission to read/RunScripts in Overall, but I still don't see an approval request for "java.util.HashMap" in scriptApproval section.
At one point I had approvals due to my testing, which I accepted. But now what ever I try e.g. moving the job a simple pipeline enabling sandboxing, creating a multibranch, loading the jenkinsfile through scm, nothing triggers a script approval for "java.util.HashMap". To top it all I removed the previously approved requests and now even they are not triggered Interestingly, I am not even sure why I require approvals as I am the admin my self, who is creating these jobs.
And I see no way to whitelist certain methods my self, until or unless as hrmpw mentioned to create a plugin and install it.
Is there any solution for this currently. And I totally vote for a disabled or a limited sandboxed environment, with the choice easily accessible from the configuration.
I ended up recompiling the plugin with the sandbox option set to false. It's fragile, but it got the job done on my jenkins instance.
I published my fork along with instructions to https://github.com/danthegoodman/workflow-cps-plugin/tree/disable_scm_security if anyone else want to use it.
nikk699 whatever your issue is, it is not this.
Given JENKINS-31155 and its supported for trusted libraries which wrap otherwise unsafe calls, I am even less inclined to touch this.
So, I know I am late to the party on this one, but we have been struggling with similar issues, making choices whether or not to use CpsScmFlowDefinition or CpsFlowDefinition. And it comes down to forced sandbox. We considered rewriting the plugin, but we don't see that as a sustainable approach. There are a lot of additional functionality that we would like to use. I understand the security concerns around allowing sandbox behavior to be disabled at the job level. It's the tug-of-war between DEV and OPS. However, I would love to have this functionality.
Is toggling the sandbox behavior for CpsScmFlowDefinition being considered?
Yeah we have a very small team that manages builds for 400+ DEV & QA. Our scripts & servers are a locked down (2FA) environment to which only 5 people have access. If I can trust these 5 people with root access to a Fortune 500 company's production systems, I think I can trust them in Jenkins.
Having Jenkins in this locked down environment, we are obligated to provide data to developers via in house scripting. Sadly we must write apps that run outside Jenkins to get data via the REST API and process for display. With the capabilities of Java sitting there behind our Pipeline scripts, it's very frustrating I can't utilize said capabilities.
Another option: Allow wildcards in the exception list so I can just add .* as allowed.
Regarding the sandbox there are a few things I wanted to point out:
- The built in whitelist (and blacklist) for Script Security is available in GitHub and can be updated via a Pull Request to add more signatures. This is a great way to add common, safe functions to the sandbox that benefits everyone:
- If you create a Shared library at the Jenkins master level all functions in this library are assumed to be safe (users must have run_script access to create add these libraries) and will bypass the sandbox.
- As I mentioned in a previous comment above it is possible to append or override the Sandbox with a plugin. It would be possible to create a plugin that whitelisted everything automatically. It would not disable the sandbox but would make it allow everything. Creating this functionality as a separate plugin would be preferable to having it as part of the core functionality. This way users who want to disable the sandbox can actively do so but others aren't exposed to large security holes through misconfigurations. Can we get someone to volunteer to create such a plugin?
- Lastly, Andrew Bayer (abayer) presented the new Declarative Pipeline syntax at Jenkins World. This is installed with the pipeline-model-definition plugin. This plugin extends Pipeline to include a declarative syntax that does not allow imperative scripting but simplifies the construction of pipeline stages, notifications, docker images, etc to execute pipeline steps. Having end users build their Pipelines using the declarative model with no scripting also allows any syntax errors to be found during compilation, instead of runtime, and should not trigger any script security errors, any Groovy methods would be built into the step definitions themselves.
It would be possible to create a plugin that whitelisted everything automatically. It would not disable the sandbox but would make it allow everything. Creating this functionality as a separate plugin would be preferable to having it as part of the core functionality. This way users who want to disable the sandbox can actively do so but others aren't exposed to large security holes through misconfigurations. Can we get someone to volunteer to create such a plugin?
It appears someone may have created such a plugin: https://wiki.jenkins-ci.org/display/JENKINS/Permissive+Script+Security+Plugin
I haven't had a chance to try this plugin out for myself, but it looks promising.
Do not install that plugin unless as an admin you can verify that either all authenticated users are fully trusted, or there is no way anyone can either create jobs or edit Pipeline script. I really do not recommend it.
Just checking if the issue I'm seeing is the same as this one.
I have a global shared library setup that works fine, but when I try to run something from a branch using the Library('library@BranchName') notation I get the hudson.remoting.ProxyException: groovy.lang.MissingMethodException: exception
The thing is that I'm running the job with the admin user which has full permissions. Also, the exception is not logged in under In-process Script Approval so I can not whitelist it.
Is this another bug or is it the same? Do you need logs or something?
Since we do trust all the authenticated users and since we are using github enterprise as the backend for the global shared library, we have every branch created and every commit logged, so I gave the permissive plugin script a try, but did not work.
If the configuration toggle is not going to be implemented, I think my next step is to recompile this plugin with the sandbox disable?
Hi Sorry for the noise,
I got this working now. I re-read the documentation at https://jenkins.io/doc/book/pipeline/shared-libraries/ and found this piece of text which I think it was not there the first time I read it
For Shared Libraries which only define Global Variables (vars/), or a Jenkinsfile which only needs a Global Variable, the annotation pattern @Library('my-shared-library') _ may be useful for keeping code concise. In essence, instead of annotating an unnecessary import statement, the symbol _ is annotated.
Anyway, basically now (without using the permissive plugin script ) this is working by switching
@Library('library@BranchName')
import foo
where foo is a file in /var/foo.groovy
with the following notation:
@Library('library@BranchName') _
I bit anti-intuitive for me, but hey.. I'm happy that this is working
We're trying to build a conventional declarative pipeline for all of our repositories to share. Each repository would essentially have the same Jenkinsfile. As such, we've created a shared pipeline step that's basically just conventionalPipeline, so each repository's Jenkinsfile would be a single line to call this step.
We can trust conventionalPipeline and everything it does, but because it calls untrusted methods we can't call it within multibranch pipelines. We could whitelist all the methods it calls, but this would open up the security holes that the sandbox tries to close.
There are two options I see - curious if I've overlooked something
- Modify jenkins somehow to allow an untrusted method to become trusted and allow all subsequent method calls by that method to be implicitly trusted
- Allow multibranch pipeline definitions to be defined in the jenkins config for the repository rather than in SCM, and let this job run outside the sandbox
Would appreciate any guidance. Happy to take this question elsewhere if more appropriate.
Hi rtimmons ,
In theory (see https://jenkins.io/doc/book/pipeline/shared-libraries/#global-shared-libraries) , and in my experience, I can create steps that contain 'untrusted' method and put it in a global shared library (groovy file under "vars") and use it from a multi-branch pipeline without the need to approve any call.
happy to test it in my instance, if you a a minimal repro.
Cheers,
Fede
If jglick creates a way to disable all of the script approvals from SCM, I'll personally drive a dozen dunkin donuts to his office and drop them off to show my appreciation.
piratejohnny I hope it never comes to pass and will reject any change adding that feature unless its use is limited to multibranch only and comes with some serious extra security measures. This is because with sandbox off, anybody with access to the SCM can trivially compromise your master in just a few lines of code. Gone will be all notion of security on masters, because it'll be too tempting for people to push that button and forget about it until they're hacked.
Since Jenkins runs in many security-sensitive contexts, including big banks and government agencies, it would only take one major hack via that vector to create a public bad reputation for Pipeline and maybe Jenkins itself that pushes people to not use them, period.
The correct and safe way to do this is to use global shared libraries for code that needs special approval, which means you can safely provide limited, secured interfaces to use that functionality by invoking the library logic from Jenkinsfiles.
At both the last company and the current one I'm at, we are promoting developers do things in Pipeilne files .. but it seems like every other day someone comes to me to tell me features dont work.. simple features like subtraction of integers or throwing an exception.
The pitch I've made to the folks I work with is that they can implement things in a Jenkinsfile right at the surface of their repo.
The problem is that it seems if they hit one of these security landmines, everything just stops.
If there were at least some message that would be displayed that said that they are using a command which requires admin approval, they wouldn't be stranded. I think the way this works right now, it just sort of stops the pipeline and no message is provided.
If there WERE a way to disable it, at least significantly, we would almost certainly use that option since all of our engineers are trusted.
svanoort: Perhaps the "correct and safe way" is what you suggested - approvals all the way. But please allow me to give a couple real-life counter arguments. Do you agree that in the real world that we live in, there is a place for really-secure security (e.g. the SE Linux way of downright-reject-unless-approved security) as well as not-as-SE-Linux-secure level (read: all the linuxes out there) of security? And, if https was so great, why is it that every piece of server software in past/present/future that can talk that protocol will inevitably have a `--verify-ssl` flag to turn it off? If a checked-in `Jenkinsfile` is so important, but so easy for one to write code to compromise security severely, wouldn't one consider using a new minimal but secure programming language to write it, instead of full-fledged Java-superset Groovy, so that Jenkins administrators (read: not necessary Java API experts) can save some sweat and trust that any Jenkinsfile not written by them can't make them lose their jobs over some unpatched Java vuln?
I am not trying to preach to you that there are merits in being less secure. To me, security is a software feature. And right now, that feature is very difficult to work with in Jenkins. If Jenkins ships with a default massive set of pre-approved rules so a Jenkins admin don't have to approve every Java SDK method, it would be easier. Alternatively, have Jenkins give out a testing function/method/framework so that I can dry-run my shared library code in such sandboxed environment so I can guard myself from introducing unapproved/potentially dangerous Groovy, good to have. Disabling it altogether? In the absence of anything else, I'll take it. I'm sure there are many more good ideas.
As this issue/feature stands, IMHO it is only curing the symptoms (easing great inconveniences) and not fixing the root cause (hard to use security model for the average Jenkins admins). I do hope that there are other features in sight to truly make Jenkins a great piece of secure software that fits most of the needs.
A szenario to consider: Pipeline Jobs created via a Job DSL Seed jobs.
Admendum:
If i define the pipeline in the Job Dsl Job not via cpsScm , but for example as follows:
// definition { cps { script(readFileFromWorkspace('pipelinescript')) sandbox(false) } }
The pipeline script only has to be approved once resp. when it changes. So that works for me. In contrary. But there may be good reasons for having the pipeline script pulled seperately from vcs and there the Security requirements of Jenkins get difficult, if not impossible to fulfil. So i generally agree stephenchu
For small teams like in our company, where each of us is admin anyway and has access to all servers, this security feature is a hughe pain in the a..
We would be really happy if it's possible to disable it.. Please, this is absolutely unnecessary for us and wastes a lot of time :/
I'm in the same boat as fljenkins ... everybody at my company with access to Jenkins is a trusted engineer. When they try to do division in their Jenkins pipeline, it fails with a security exception leaving people wondering "Wait, why is this useful?" and "Can't we just use CircleCI"?
Me too... Like Peter L and Jon B we are working in a small team without rights management in Jenkins and the Jenkins server is not exposed to the internet - security is not much of a concern for us. A security-by-default design is a generally sound and commendable choice, but we ultimately gave up on Multibranch Pipelines because of the lack of the "Use Groovy Sandbox" checkbox.
Also it seems that the approval does not work at the moment, at least not for our system - whenever we approve something, it's added to the list, but during the next run it looks like the previous approvals are not taken into account and requested again (see screenshot).
So without this checkbox to disable the script-approval Jenkins is completely broken for us and we can't release/test anything with it
Why not just use the Permissive Script Security Plugin that Oliver created. That is probably much easier than trying to maintain a fork. Again, this is only recommended if you want to disable security on your master.
The Permissive script works for classified method signatures, but still fails to help with unclassified method signatures (like Math.ceil): https://issues.jenkins-ci.org/browse/JENKINS-37479
+1 for adding a feature to turn off the script security altogether. I spend a lot of time fighting with this even though everyone is admin on the team. "Permisssive Script Security" plugin is not the best solution as it introduces its own bugs doesn't help with "Script Security Plugin" related bugs, e.g. I've just stumbled upon JENKINS-37527.
I've opened a proposal to offer an audit mode as described in JENKINS-47392 to reduce the pain from the script approvals process.
Would some of the commenters in this thread like to hop on that and comment about how well that addresses pain points here?
I'll also mention that the longer-term plan is probably to find better ways to secure Pipeline without resorting to Script Security (we have some options, but need to do some investigation still).
+1 for adding a feature to turn off the script security altogether. I spend a lot of time fighting with this even though everyone is admin on the team. "Permisssive Script Security" plugin is not the best solution as it doesn't work for us! I think this feature must be disabled altogether as it performs very awful as for today.
As a Jenkins-admin with quite a few system groovy scripts, I would like to white-list certain paths (that contains my version controlled scripts) as 100% secure, so that I (once the change has been submitted) can use the latest and most up-to-date version of my script immediately.
May it be pipelines or groovy system scripts, if the Jenkins-admin approve the scripts (before they're executed), they should be allowed to run.
Suggesting to just use shared/trusted libraries is not enough IMHO, we need a switch to turn this stuff off. as an example, today I have a basic Jenkinsfile that's throwing errors with [].tail():
Scripts not permitted to use staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods tail java.lang.Object[].
Job console offers a link to go to the ScriptApproval URL to approve, but then it does not remember the approval.. I return to the job generating the error and then it happens again in exactly the same way, telling me to approve. There's nothing further I can even do here to debug that problem (which is just another distraction from the work I really want to do), so I get forced into rewrite `[].tail()` as different-but-equivalent groovy, something with `[].findAll{}`, which just works.
So why is Jenkins not remembering the approvals? Why is `findAll` safer than `tail`? Why does this plugin exist in the ecosystem if it doesn't work and can't work? https://wiki.jenkins.io/display/JENKINS/Permissive+Script+Security+Plugin
Like other users, our Jenkins is behind a VPN, and we have multiple Jenkins instances so that we don't have to deal with all the complexity of highly granular user/job/credential permissioning. Since all people who can login to a given instance are admins on that instance.. our experience is that none of script-security stuff adds security, it just degrades our stability.
Please, can we just get a config option to just turn this off everywhere?
+1 mvr
I've created jenkins.io account just to make this comment... You can imagine the pain
Can you please explain the workaround in more detail? I tried to use the method you mention in the tutorial:
But flow.groovy is still run in the sandbox.