Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-50470

Cannot evaluate ArrayList.name inside Groovy Sandbox

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Minor Minor
    • script-security-plugin
    • None
    • Jenkins 2.89.x
      Script Security 1.39 & 1.43

      Steps to reproduce:

      1. Create a freestyle job
      2. Add "Execute system Groovy script" build step
      3. Add content (see below)
      4. Run build with "Use Groovy Sandbox" enabled.
      5. Run without "Use Groovy Sandbox" enabled

      Script content:

      def someArrayList = []
      
      println someArrayList.name
      

      This works with Sandbox disabled. When enabled, the following exception is thrown:

      ERROR: Build step failed with exception
      org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.util.ArrayList name
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:397)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:381)
      	at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:288)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
      	at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty.callStatic(Unknown Source)
      	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:194)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:230)
      	at Script1.run(Script1.groovy:3)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.run(GroovySandbox.java:141)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:333)
      	at hudson.plugins.groovy.SystemGroovy.run(SystemGroovy.java:95)
      	at hudson.plugins.groovy.SystemGroovy.perform(SystemGroovy.java:59)
      	at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
      	at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:744)
      	at hudson.model.Build$BuildExecution.build(Build.java:206)
      	at hudson.model.Build$BuildExecution.doRun(Build.java:163)
      	at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:504)
      	at hudson.model.Run.execute(Run.java:1724)
      	at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
      	at hudson.model.ResourceController.execute(ResourceController.java:97)
      	at hudson.model.Executor.run(Executor.java:429)
      Build step 'Execute system Groovy script' marked build as failure
      Finished: FAILURE
      

      It looks like, outside the sandbox, groovy evaluates

      someArrayList.name
      

      to

      someArrayList.collect { it.name } 
      

      but inside the sandbox, this doesn't happen.

      Feedback from Andrew:

      fwiw, it's https://github.com/apache/groovy/blob/eedc6bfcd134749e7d76b05031dfbd914cec2d6e/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java#L7855 we need to somehow handle - we have to check the contents of the list to see if the objects in there can have that field accessed.

      The workaround currently is to change to using:

      someArrayList.collect { it.name }
      

      when using the sandbox.

          [JENKINS-50470] Cannot evaluate ArrayList.name inside Groovy Sandbox

          Andrew Bayer added a comment -

          So yeah, the gist here is that script-security tries to go straight to someList.getName() and onward to someList.name (the field directly), which isn't right and fails out. It should effectively be calling someList.getAt("name"), as done through MetaClassImpl.getProperty. I think we just need to get Checker.checkedGetProperty to treat a Collection receiver as if it were a spread operation (which is already supported). I'm experimenting now.

          Andrew Bayer added a comment - So yeah, the gist here is that script-security tries to go straight to someList.getName() and onward to someList.name (the field directly), which isn't right and fails out. It should effectively be calling someList.getAt("name") , as done through MetaClassImpl.getProperty . I think we just need to get Checker.checkedGetProperty to treat a Collection receiver as if it were a spread operation (which is already supported). I'm experimenting now.

          Andrew Bayer added a comment -

          Well, yeah, that turned out to be pretty simple. PRs up.

          Andrew Bayer added a comment - Well, yeah, that turned out to be pretty simple. PRs up.

          Jesse Glick added a comment -

          Would never have dreamed that this would be legal Groovy. Ugh.

          Jesse Glick added a comment - Would never have dreamed that this would be legal Groovy. Ugh.

          Code changed in jenkins
          User: Andrew Bayer
          Path:
          pom.xml
          src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptorTest.java
          http://jenkins-ci.org/commit/script-security-plugin/f7601abde0df3fec15be935ad95473959185f0a4
          Log:
          [FIXED JENKINS-50470] Treat someList.someField as spread.

          See upstream PR at
          https://github.com/jenkinsci/groovy-sandbox/pull/46, but the gist is
          that Groovy's normal behavior for this is to treat it the same as we
          do spread cases - iterate over the list to get the value from each
          object in the list and return the resulting list.

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Andrew Bayer Path: pom.xml src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptorTest.java http://jenkins-ci.org/commit/script-security-plugin/f7601abde0df3fec15be935ad95473959185f0a4 Log: [FIXED JENKINS-50470] Treat someList.someField as spread. See upstream PR at https://github.com/jenkinsci/groovy-sandbox/pull/46 , but the gist is that Groovy's normal behavior for this is to treat it the same as we do spread cases - iterate over the list to get the value from each object in the list and return the resulting list.

          Andrew Bayer added a comment -

          Will be in next release of script-security, presumably 1.44.

          Andrew Bayer added a comment - Will be in next release of script-security, presumably 1.44.

          Alex Varju added a comment -

          I'm seeing very similar behaviour with 1.44.  In my freestyle job I've got this Groovy:

          def someList = [1, 2, 3]
          println someList.size
          

          When the sandbox is enabled, this ends up throwing:

          RejectedAccessException: No such field found: field java.lang.Integer size
          

          Changing the list to contain strings changes the error to:

          RejectedAccessException: No such field found: field java.lang.String size
          

          Alex Varju added a comment - I'm seeing very similar behaviour with 1.44.  In my freestyle job I've got this Groovy: def someList = [1, 2, 3] println someList.size When the sandbox is enabled, this ends up throwing: RejectedAccessException: No such field found: field java.lang.Integer size Changing the list to contain strings changes the error to: RejectedAccessException: No such field found: field java.lang.String size

          Marco Moikl added a comment -

          varju, did you solve the issue? I have your same problem.

          Marco Moikl added a comment - varju , did you solve the issue? I have your same problem.

          Alex Varju added a comment - - edited

          Unfortunately, no. In the case above, I had to refactor my code to use someList.size()

          Since commenting previously, I've encountered at least one other example of a similar failure:

          def tuple = new Tuple2( 'a', 'b' )
          println tuple.first
          

          Which results in:

          RejectedAccessException: No such field found: field java.lang.String first
          

          And again, changing tuple.first to tuple.getFirst() works around the issue.

          Alex Varju added a comment - - edited Unfortunately, no. In the case above, I had to refactor my code to use someList.size() Since commenting previously, I've encountered at least one other example of a similar failure: def tuple = new Tuple2( 'a', 'b' ) println tuple.first Which results in: RejectedAccessException: No such field found: field java.lang.String first And again, changing tuple.first to tuple.getFirst() works around the issue.

          I faced the same issue at 1.44

           

          println 'test,value'.tokenize(',').size
          
          org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.lang.String size
          

          It works with 1.42. Workaround is to use `size()` instead

           

          Dmitry Burmistrov added a comment - I faced the same issue at 1.44   println 'test,value' .tokenize( ',' ).size org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.lang. String size It works with 1.42. Workaround is to use `size()` instead  

          I am facing the same issue at 1.71

          I am using FolderProperties in Pipeline job

          In my pipeline jenkins Code:
                withFolderProperties{ echo "URL STEP 1: ${env.testURL}" }
          Getting below error:
          org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.lang.String
          testURL

          Any workaround?

          Murugesh Subramaniam added a comment - I am facing the same issue at 1.71 I am using FolderProperties in Pipeline job In my pipeline jenkins Code:       withFolderProperties{ echo "URL STEP 1: ${env.testURL}" } Getting below error: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.lang.String testURL Any workaround?

            abayer Andrew Bayer
            owood Owen Wood
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: