jenkinsci / jenkinsci/script-security-plugin
[JENKINS-62749] Groovy Sandbox doesn't allow to use Closure.DELEGATE_FIRST to class instance in shared library
- Dominant language
- Java
- Stars
- 76
- Forks
- 181
- Avg merge
- 14h 55m
- Merged PRs (30d)
- 3
Description
I'm getting following exception:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (Foo echo org.codehaus.groovy.runtime.GStringImpl)
when delegating instance of class to closure in shared library.
In shared library I have file vars/buildPlugin.groovy
def call(body) {
def config = new Foo()
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()
echo "Name set by closure: ${config.name}"
}
class Foo {
def name
}
and here is how it is using in Jenkinsfile (or pipeline script):
@Library('library.name') _buildPlugin {
name = 'name_from_Jenkinsfile'
echo "Name from Jenkinsfile: ${name}"
}
I'm expecting to get following output:
Name from Jenkinsfile: name_from_Jenkinsfile
Name set by closure: name_from_Jenkinsfile
But instead getting the exception above.
Possible workarounds:
1) If uncheck Use Groovy Sandbox checkbox in pipeline job config - I'm getting expected output. But I don't want to disable sandbox or whitelist `method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object`
2) If change `def config = new Foo()` to `def config = [:]` in vars/buildPlugin.groovy I'm getting expected output. But I need to use class for defining additional methods in it.
3) If change `echo` to `this.echo` in Jenkinsfile - I'm getting expected output. But this will require to add `this` in all Jenkinsfiles for all objects not defined in delegated class instance.
---
Originally reported by kdsnice, imported from: Groovy Sandbox doesn't allow to use Closure.DELEGATE_FIRST to class instance in shared library
Raw content of original issue
I'm getting following exception:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (Foo echo org.codehaus.groovy.runtime.GStringImpl)when delegating instance of class to closure in shared library.
In shared library I have file vars/buildPlugin.groovy
def call(body) {
def config = new Foo()
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()echo "Name set by closure: ${config.name}"
}class Foo {
def name
}and here is how it is using in Jenkinsfile (or pipeline script):
@Library('library.name') _buildPlugin {
name = 'name_from_Jenkinsfile'
echo "Name from Jenkinsfile: ${name}"
}I'm expecting to get following output:
Name from Jenkinsfile: name_from_Jenkinsfile
Name set by closure: name_from_Jenkinsfile
But instead getting the exception above.Possible workarounds:
1) If uncheck Use Groovy Sandbox checkbox in pipeline job config - I'm getting expected output. But I don't want to disable sandbox or whitelist `method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object`2) If change `def config = new Foo()` to `def config = [:]` in vars/buildPlugin.groovy I'm getting expected output. But I need to use class for defining additional methods in it.
3) If change `echo` to `this.echo` in Jenkinsfile - I'm getting expected output. But this will require to add `this` in all Jenkinsfiles for all objects not defined in delegated class instance.
- environment:
Official docker image jenkins/jenkins:2.222.4, script-security:1.73
Contributor guide
Assessment
This issue has not been assessed yet.