154

I am Using Jenkins 2 for compiling Java Projects, I want to read the version from a pom.xml, I was following this example:

https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md

The example suggest:

Full Jenkins Pipeline with problematic function circled

It seems that there is some security problem accessing the File System but I can't figure out what it is giving (or why) that problem:

I am just doing a little bit different than the example:

def version() {
    String path = pwd();
    def matcher = readFile("${path}/pom.xml") =~ '<version>(.+)</version>'
    return matcher ? matcher[0][1] : null
}

The Error I am getting when running the 'version' method :

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (org.codehaus.groovy.runtime.GStringImpl call org.codehaus.groovy.runtime.GStringImpl)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectMethod(StaticWhitelist.java:165)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:117)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:103)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:149)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:146)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:15)
    at WorkflowScript.run(WorkflowScript:71)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:55)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:100)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)

I am using these versions: Plugin Pipeline 2.1 Jenkins 2.2

Oliver Gondža
  • 3,386
  • 4
  • 29
  • 49
Daniel Hernández
  • 4,078
  • 6
  • 27
  • 38
  • 1
    I had a similar error about `Scripts not permitted to use method`, but it happened because I wrote `scm 'checkout'` instead of `checkou scm`. Just in case someone falls on this, watch for bad syntax :). Doing as Maarten Kieft said allowed me to see a more clear error message about the bad command :) – GabLeRoux Jan 22 '17 at 21:33
  • 2
    I strongly recommend to _not_ use Regex for parsing XML. And it's not only me but 4413+ [_You can't parse \[X\]HTML with regex._](https://stackoverflow.com/a/1732454/1744774) plus 47+ [_Why is it such a bad idea to parse XML with regex?_](https://stackoverflow.com/a/8577108/1744774) others too. There are [better](https://stackoverflow.com/a/68957153/1744774) solutions [herein](https://stackoverflow.com/a/68408938/1744774) now, without the need for admin approval or even disabling security features completely. – Gerold Broser Aug 27 '21 at 23:35

8 Answers8

357

Quickfix Solution:

I had similar issue and I resolved it doing the following

  1. Navigate to jenkins > Manage jenkins > In-process Script Approval
  2. There was a pending command, which I had to approve.

In process approval link in Jenkins 2.61


Alternative 1: Disable sandbox

As this article explains in depth, groovy scripts are run in sandbox mode by default. This means that a subset of groovy methods are allowed to run without administrator approval. It's also possible to run scripts not in sandbox mode, which implies that the whole script needs to be approved by an administrator at once. This preventing users from approving each line at the time.

Running scripts without sandbox can be done by unchecking this checkbox in your project config just below your script: enter image description here

Alternative 2: Disable script security

As this article explains it also possible to disable script security completely. First install the permissive script security plugin and after that change your jenkins.xml file add this argument:

-Dpermissive-script-security.enabled=true

So you jenkins.xml will look something like this:

<executable>..bin\java</executable>
<arguments>-Dpermissive-script-security.enabled=true -Xrs -Xmx4096m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=80 --webroot="%BASE%\war"</arguments>

Make sure you know what you are doing if you implement this!

Neuron
  • 5,141
  • 5
  • 38
  • 59
Maarten Kieft
  • 6,806
  • 3
  • 29
  • 34
  • 2
    If approving the whole script is better, depends on the team structure. For a few developers with full access it's quite nice. But a setup with multiple teams would force admins to approve of every change in all pipeline scripts. – Roger Lehmann Jun 09 '17 at 12:42
  • 4
    Alternative 3 (should really be first suggestion) is to _alter problematic unwhitelisted code_. In this case, a simple use of `@NonCPS` for the `Matcher` usage would suffice. There is no need in this case to disable security for the entire pipeline, and especially the entire Jenkins installation. Evaluate each blocked call individually and decide if you really need to approve them. – mkobit Feb 27 '18 at 18:26
  • 1
    @mkobit doesn't work for me. `@NonCPS` doesn't help. – warvariuc Mar 20 '18 at 05:20
  • @warvariuc hmm, it could be if you are returning `Matcher` itself, because `Matcher` does not implement the `Serializable` interface. It might be worth asking a new question. I wish that the documentation referenced in the original question was maintained and not wrong to begin with. – mkobit Mar 20 '18 at 13:11
  • 2
    @mkobit I decorated with `NonCPS ` a function which uses `currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId()`. NonCPS doesn't help with security issues at all, from what I read. – warvariuc Mar 20 '18 at 20:36
  • 1
    @warvariuc thanks for the reply. You are right, `@NonCPS` will not help you with that as [that method is intentionally not whitelisted](http://javadoc.jenkins.io/plugin/workflow-support/org/jenkinsci/plugins/workflow/support/steps/build/RunWrapper.html#getRawBuild--). In some cases, you may want to only approve for a specific run, a single job, single folder, single method, etc. There are some other ways to address the limited security issue (like using a global shared library). I was trying to point out that disabling security for the whole instance is almost certainly not a good idea. – mkobit Mar 20 '18 at 20:50
  • Got same issue: Scripts not permitted to use method java.util.regex.Matcher find. But did not find it in pending list. – Addo Zhang Jun 19 '18 at 12:58
  • Alternative 2 was the way to go for us, it is to be noted that **I had to sandbox the script** to make things work. I posted our detailed setup on Jenkins' JIRA [here](https://issues.jenkins-ci.org/browse/JENKINS-32681?focusedCommentId=351583&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-351583) – mks-d Oct 18 '18 at 09:15
14

You have to disable the sandbox for Groovy in your job configuration.

Currently this is not possible for multibranch projects where the groovy script comes from the scm. For more information see https://issues.jenkins-ci.org/browse/JENKINS-28178

Andre
  • 475
  • 3
  • 6
  • 4
    Disabling the sandbox is a terrible idea. Doing so would allow a bad actor, or a clumsy one to exploit jenkins to do anything desired including circumventing security, stealing credentials... Just don't do it! – Steven the Easily Amused Apr 03 '21 at 15:01
10

I ran into this when I reduced the number of user-input parameters in userInput from 3 to 1. This changed the variable output type of userInput from an array to a primitive.

Example:

myvar1 = userInput['param1']
myvar2 = userInput['param2']

to:

myvar = userInput
Mark
  • 606
  • 7
  • 12
  • 4
    This is exactly the fix for the symptom I experienced. The error message was `org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object`. The method expected 2 parameters and was receiving 3. – TylerW Jul 23 '19 at 20:57
3

To get around sandboxing of SCM stored Groovy scripts, I recommend to run the script as Groovy Command (instead of Groovy Script file):

import hudson.FilePath
final GROOVY_SCRIPT = "workspace/relative/path/to/the/checked/out/groovy/script.groovy"

evaluate(new FilePath(build.workspace, GROOVY_SCRIPT).read().text)

in such case, the groovy script is transferred from the workspace to the Jenkins Master where it can be executed as a system Groovy Script. The sandboxing is suppressed as long as the Use Groovy Sandbox is not checked.

Stepan Vavra
  • 3,884
  • 5
  • 29
  • 40
  • 12
    This seems clunky, risky and bound to come back and bite you. – Simon Forsberg Jul 30 '17 at 10:29
  • 10
    Well, security is important especially when it protects user sensitive data but it also comes with a price such as a complication during the development process. When the security tooling is just half implemented it gets even worse. The Jenkins script sandboxing is a nice example of half implemented security tooling and as a result you might need to completely disable the feature because otherwise it means no go for you. – Stepan Vavra Jul 31 '17 at 07:48
  • 3
    In my case, after an upgrade from an older Jenkins, my Groovy script stopped working and the only way to make it work would be to run the script 300 times (just an estimate) and for each run to click in the Jenkins UI to allow all the method calls in a 200 lines script. Moreover the UI doesn't allow you to paste the complete list of all the allowed method calls in case you were able to somehow generate them. Additionally, the UI stopped showing some of the the method calls and after a while I was unable to proceed. – Stepan Vavra Jul 31 '17 at 07:49
2

To get the version of a maven project, I usually use mvn binary in the sh block as follows. No need for admin permissions.

stage("Compile") {
    steps {
       sh """
         mvn help:evaluate -Dexpression=project.version -q -DforceStdout > version.txt
       """
    }
}
JavaTechnical
  • 8,846
  • 8
  • 61
  • 97
  • +1 Clever idea! But what to do with `version.txt` afterwards? Anyway, there's [no need for redirection and later text file handling](https://stackoverflow.com/a/68957153/1744774). – Gerold Broser Aug 27 '21 at 17:16
1

Unrelated to OP's issue; But this Stack Overflow Question pops up on top of search.

I was getting this error when I tried to declare a variable named owner (re-declare apparently) in my pipeline script. Changed it to repoOwner and the script worked as expected.

fsb2023
  • 21
  • 1
0

Following @JavaTechnical's answer herein a Maven project's version can be assigend to a variable:

stage("getPomProjectVersion") {
    steps {
       ...
       def pomProjectVersion = sh script: 'mvn help:evaluate -Dexpression=project.version -q -DforceStdout', returnStdout: true
       ...
    }
}
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • I agree this is the best way to read a pom, at least at this time https://www.jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#readmavenpom-read-a-maven-project-file but the need of t his post was how to skip or bypass that security constraint when we need to use custom or weird piece of codes – Daniel Hernández Aug 28 '21 at 20:50
0

The issue I had was that the Groovy object didn't have the function I was attempting to call. To my understanding if Groovy can't find the function then Groovy starts to do introspection on the object looking for for the undefined object, which caused this error.

So check to make sure that the function you are trying to call really exists.

Fred
  • 1,054
  • 1
  • 12
  • 32