-
Bug
-
Resolution: Fixed
-
Minor
-
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.
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.