Jenkins CI管道脚本不允许使用groovy.lang.GroovyObject方法


104

我正在使用Jenkins 2来编译Java项目,我想从pom.xml中读取版本,我在遵循以下示例:

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

该示例建议:

带问题功能的完整Jenkins管道盘旋

似乎在访问文件系统时存在一些安全问题,但是我无法弄清楚它给了什么(或为什么)该问题:

我只是在做一些与示例不同的事情:

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

运行'version'方法时出现的错误:

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)

我正在使用以下版本:Plugin Pipeline 2.1 Jenkins 2.2


我也有类似的错误Scripts not permitted to use method,但这是因为我写了scm 'checkout'而不是checkou scm。以防万一有人落在这上,请注意语法错误:)。按照Maarten Kieft所说的做,使我可以看到关于错误命令的更清楚的错误消息:)
GabLeRoux

Answers:


261

快速解决

我遇到了类似的问题,并通过以下措施解决了它

  1. 导航到jenkins>管理jenkins>进程内脚本批准
  2. 有一个待批准的命令,我必须批准。

Jenkins 2.61中的过程中批准链接 选择1:禁用沙箱

正如本文深入解释的那样,默认情况下,groovy脚本在沙箱模式下运行。这意味着可以在无需管理员批准的情况下运行常规方法的子集。也可以不在沙盒模式下运行脚本,这意味着整个脚本需要立即获得管理员的批准。这样可以防止用户同时批准每一行。

通过在脚本下方的项目配置中取消选中此复选框,可以运行没有沙箱的脚本: 在此处输入图片说明

选择2:禁用脚本安全性

本文所述,还可以完全禁用脚本安全性。首先安装许可脚本安全性插件,然后更改您的jenkins.xml文件,添加以下参数:

-Dpermissive-script-security.enabled = true

因此,您的jenkins.xml将如下所示:

<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>

如果执行此操作,请确保您知道自己在做什么!


1
如果批准整个脚本更好,则取决于团队结构。对于具有完全访问权限的一些开发人员来说,这是非常好的。但是由多个团队进行的设置将迫使管理员批准所有管道脚本中的每项更改。
罗杰·莱曼

2
备选方案3(实际上应该是第一个建议)是更改有问题的未列入白名单的代码。在这种情况下,一个简单的使用@NonCPSMatcher使用就足够了。在这种情况下,无需禁用整个管道的安全性,尤其是整个Jenkins安装的安全性。分别评估每个阻止的呼叫,然后确定是否确实需要批准它们。
mkobit

1
@mkobit对我不起作用。@NonCPS没有帮助。
warvariuc

@warvariuc hmm,可能是您正在返回Matcher自身,因为Matcher未实现该Serializable接口。可能值得提出一个新问题。我希望原始问题中引用的文档得到维护,并且从一开始就没有错。
mkobit

2
@mkobit我装饰了NonCPS 一个使用的函数currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId()。根据我的阅读,NonCPS根本无法解决安全问题。
warvariuc


6

当我将userInput中用户输入参数的数量从3减少到1时,我遇到了这个问题。这将userInput的变量输出类型从数组更改为原始类型。

例:

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

至:

myvar = userInput

这正是我遇到的症状的解决方法。错误消息为org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object。该方法预期2个参数,并接收3
泰勒W¯¯

4

为了避开SCM存储的Groovy脚本的沙箱,我建议以Groovy Command(而不是Groovy脚本文件)运行脚本:

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)

在这种情况下,groovy脚本从工作空间传输到Jenkins Master,在该脚本中可以作为脚本执行system Groovy Script。只要未选中使用Groovy沙箱”,便会抑制沙箱


5
这似乎笨拙,冒险,势必回来咬你。
西蒙·佛斯伯格

4
嗯,安全性很重要,特别是当它保护用户敏感数据时,同时在开发过程中也会带来诸如复杂性之类的代价。当安全工具仅实现一半时,情况就更糟了。Jenkins脚本沙箱是半实现的安全工具的一个很好的示例,因此您可能需要完全禁用该功能,因为否则就不行了。
斯捷潘Vavra

3
在我的情况下,从较旧的Jenkins升级后,我的Groovy脚本停止工作,并且使其起作用的唯一方法是将脚本运行300次(只是估算值),每次运行都单击Jenkins UI以允许所有方法都在200行脚本中调用。此外,如果您能够以某种方式生成它们,则UI不允许您粘贴所有允许的方法调用的完整列表。此外,UI停止显示一些方法调用,过了一会儿我无法继续。
Stepan Vavra
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.