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

          Owen Wood created issue -

          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 made changes -
          Status Original: Open [ 1 ] New: In Progress [ 3 ]
          Andrew Bayer made changes -
          Status Original: In Progress [ 3 ] New: In Review [ 10005 ]
          Andrew Bayer made changes -
          Remote Link New: This issue links to "script-security PR #195 (Web Link)" [ 20346 ]

          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.
          Andrew Bayer made changes -
          Remote Link New: This issue links to "groovy-sandbox PR #46 (Web Link)" [ 20347 ]

          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.
          Andrew Bayer made changes -
          Resolution New: Fixed [ 1 ]
          Status Original: In Review [ 10005 ] New: Resolved [ 5 ]

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

              Created:
              Updated:
              Resolved: