Jenkins CI-Pipeline-Skripte dürfen die Methode groovy.lang.GroovyObject nicht verwenden

104

Ich verwende Jenkins 2 zum Kompilieren von Java-Projekten. Ich möchte die Version aus einer pom.xml lesen. Ich habe dieses Beispiel befolgt:

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

Das Beispiel legt nahe:

Volle Jenkins-Pipeline mit problematischer Funktion eingekreist

Es scheint, dass es ein Sicherheitsproblem beim Zugriff auf das Dateisystem gibt, aber ich kann nicht herausfinden, was es dieses Problem verursacht (oder warum):

Ich mache nur ein bisschen anders als das Beispiel:

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

Der Fehler, den ich beim Ausführen der 'version'-Methode erhalte:

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)

Ich verwende diese Versionen: Plugin Pipeline 2.1 Jenkins 2.2

Daniel Hernández
quelle
Ich hatte einen ähnlichen Fehler zu Scripts not permitted to use method, aber es geschah , weil ich schrieb scm 'checkout'statt checkou scm. Nur für den Fall, dass jemand darauf fällt, achten Sie auf schlechte Syntax :). Das zu tun, was Maarten Kieft sagte, erlaubte mir, eine
klarere

Antworten:

261

Schnelle Lösung

Ich hatte ein ähnliches Problem und habe es wie folgt gelöst

  1. Navigieren Sie zu jenkins> jenkins verwalten> In-process Script Approval
  2. Es gab einen ausstehenden Befehl, den ich genehmigen musste.

In Bearbeitung Genehmigungslink in Jenkins 2.61 Alternative 1: Sandbox deaktivieren

Wie in diesem Artikel ausführlich erläutert, werden groovige Skripte standardmäßig im Sandbox-Modus ausgeführt. Dies bedeutet, dass eine Teilmenge der groovigen Methoden ohne Genehmigung des Administrators ausgeführt werden darf. Es ist auch möglich, Skripte auszuführen, die sich nicht im Sandbox-Modus befinden. Dies bedeutet, dass das gesamte Skript sofort von einem Administrator genehmigt werden muss. Dies verhindert, dass Benutzer jede Zeile gleichzeitig genehmigen.

Das Ausführen von Skripten ohne Sandbox kann durch Deaktivieren dieses Kontrollkästchens in Ihrer Projektkonfiguration direkt unter Ihrem Skript erfolgen: Geben Sie hier die Bildbeschreibung ein

Alternative 2: Deaktivieren Sie die Skriptsicherheit

Wie in diesem Artikel erläutert, ist es auch möglich, die Skriptsicherheit vollständig zu deaktivieren. Installieren Sie zuerst das zulässige Skript-Sicherheits-Plugin und ändern Sie anschließend Ihre Datei jenkins.xml. Fügen Sie dieses Argument hinzu:

-Dpermissive-script-security.enabled = true

Ihre jenkins.xml sieht also ungefähr so ​​aus:

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

Stellen Sie sicher, dass Sie wissen, was Sie tun, wenn Sie dies implementieren!

Maarten Kieft
quelle
1
Ob die Genehmigung des gesamten Skripts besser ist, hängt von der Teamstruktur ab. Für ein paar Entwickler mit vollem Zugriff ist es ganz nett. Ein Setup mit mehreren Teams würde Administratoren jedoch dazu zwingen, jede Änderung in allen Pipeline-Skripten zu genehmigen.
Roger Lehmann
2
Alternative 3 (sollte eigentlich der erste Vorschlag sein) besteht darin , problematischen Code ohne Whitelist zu ändern . In diesem Fall würde eine einfache Verwendung von @NonCPSfür die MatcherVerwendung ausreichen. In diesem Fall muss die Sicherheit für die gesamte Pipeline und insbesondere für die gesamte Jenkins-Installation nicht deaktiviert werden. Bewerten Sie jeden blockierten Anruf einzeln und entscheiden Sie, ob Sie ihn wirklich genehmigen müssen.
mkobit
1
@mkobit funktioniert bei mir nicht. @NonCPShilft nicht.
Warvariuc
@warvariuc hmm, es könnte sein, dass Sie sich Matcherselbst zurückgeben, weil Matcherdie SerializableSchnittstelle nicht implementiert wird. Es könnte sich lohnen, eine neue Frage zu stellen. Ich wünsche mir, dass die in der ursprünglichen Frage genannte Dokumentation beibehalten wird und zunächst nicht falsch ist.
Mkobit
2
@mkobit Ich habe mit NonCPS einer Funktion dekoriert, die verwendet currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(). Nach dem, was ich gelesen habe, hilft NonCPS bei Sicherheitsproblemen überhaupt nicht.
Warvariuc
12

Sie müssen die Sandbox für Groovy in Ihrer Jobkonfiguration deaktivieren.

Derzeit ist dies für Multibranch-Projekte nicht möglich, bei denen das groovige Skript vom scm stammt. Weitere Informationen finden Sie unter https://issues.jenkins-ci.org/browse/JENKINS-28178

Andre
quelle
6

Ich bin darauf gestoßen, als ich die Anzahl der Benutzereingabeparameter in userInput von 3 auf 1 reduziert habe. Dadurch wurde der variable Ausgabetyp von userInput von einem Array in ein Grundelement geändert.

Beispiel:

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

zu:

myvar = userInput
Kennzeichen
quelle
Dies ist genau die Lösung für das Symptom, das ich erlebt habe. Die Fehlermeldung war org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object. Die Methode erwartete 2 Parameter und erhielt 3.
Tyler W
4

Um das Sandboxing von SCM-gespeicherten Groovy-Skripten zu umgehen, empfehle ich, das Skript als Groovy-Befehl (anstelle der Groovy- Skriptdatei) auszuführen :

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)

In diesem Fall wird das groovige Skript vom Arbeitsbereich an den Jenkins-Master übertragen, wo es als ausgeführt werden kann system Groovy Script. Das Sandboxing wird unterdrückt, solange das Kontrollkästchen Groovy Sandbox verwenden nicht aktiviert ist .

Stepan Vavra
quelle
5
Dies scheint klobig, riskant und verpflichtet, zurück zu kommen und dich zu beißen.
Simon Forsberg
4
Sicherheit ist wichtig, insbesondere wenn sie benutzersensible Daten schützt, aber auch mit einem Preis wie einer Komplikation während des Entwicklungsprozesses verbunden ist. Wenn das Sicherheitstool nur zur Hälfte implementiert ist, wird es noch schlimmer. Das Jenkins-Skript-Sandboxing ist ein schönes Beispiel für halb implementierte Sicherheitstools. Daher müssen Sie die Funktion möglicherweise vollständig deaktivieren, da dies sonst bedeutet, dass Sie nichts dagegen haben.
Stepan Vavra
3
In meinem Fall funktionierte mein Groovy-Skript nach einem Upgrade von einem älteren Jenkins nicht mehr. Die einzige Möglichkeit, es zum Laufen zu bringen, bestand darin, das Skript 300 Mal auszuführen (nur eine Schätzung) und bei jedem Lauf auf die Jenkins-Benutzeroberfläche zu klicken, um dies zuzulassen Alle Methodenaufrufe in einem 200-Zeilen-Skript. Darüber hinaus können Sie auf der Benutzeroberfläche nicht die vollständige Liste aller zulässigen Methodenaufrufe einfügen, falls Sie sie irgendwie generieren konnten. Außerdem wurden auf der Benutzeroberfläche einige Methodenaufrufe nicht mehr angezeigt, und nach einer Weile konnte ich nicht mehr fortfahren.
Stepan Vavra