From 212e048a319ae32dad4cfec5e73a885a9f4781f0 Mon Sep 17 00:00:00 2001 From: Andrew Bayer Date: Tue, 22 Jan 2019 08:45:30 -0500 Subject: [PATCH] [SECURITY-1293] Secure the script check in StringScriptSource --- pom.xml | 8 +-- .../plugins/groovy/StringScriptSource.java | 3 +- .../groovy/StringScriptSourceTest.java | 61 +++++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 src/test/java/hudson/plugins/groovy/StringScriptSourceTest.java diff --git a/pom.xml b/pom.xml index b7757a2..409424c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jenkins-ci.plugins plugin - 2.19 + 3.21 @@ -15,8 +15,8 @@ http://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin - 1.580.3 - 6 + 2.7.3 + 7 @@ -53,7 +53,7 @@ org.jenkins-ci.plugins script-security - 1.24 + 1.50 diff --git a/src/main/java/hudson/plugins/groovy/StringScriptSource.java b/src/main/java/hudson/plugins/groovy/StringScriptSource.java index 5800427..82a315b 100644 --- a/src/main/java/hudson/plugins/groovy/StringScriptSource.java +++ b/src/main/java/hudson/plugins/groovy/StringScriptSource.java @@ -10,6 +10,7 @@ import java.io.IOException; import org.codehaus.groovy.control.CompilationFailedException; +import org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -67,7 +68,7 @@ public FormValidation doCheckScript(@QueryParameter String command) { return FormValidation.error("Script seems to be empty string!"); try { - new GroovyShell().parse(command); + new GroovyShell(GroovySandbox.createSecureCompilerConfiguration()).parse(command); return FormValidation.ok("So far so good"); } catch (CompilationFailedException e) { return FormValidation.error(e.getMessage()); diff --git a/src/test/java/hudson/plugins/groovy/StringScriptSourceTest.java b/src/test/java/hudson/plugins/groovy/StringScriptSourceTest.java new file mode 100644 index 0000000..4f98961 --- /dev/null +++ b/src/test/java/hudson/plugins/groovy/StringScriptSourceTest.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright (c) 2019, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package hudson.plugins.groovy; + +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.Issue; +import org.jvnet.hudson.test.JenkinsRule; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +public class StringScriptSourceTest { + @Rule + public JenkinsRule j = new JenkinsRule(); + + @Issue("SECURITY-1293") + @Test + public void blockASTTest() throws Exception { + StringScriptSource.DescriptorImpl d = j.jenkins.getDescriptorByType(StringScriptSource.DescriptorImpl.class); + assertThat(d.doCheckScript("import groovy.transform.*\n" + + "import jenkins.model.Jenkins\n" + + "import hudson.model.FreeStyleProject\n" + + "@ASTTest(value={ assert Jenkins.getInstance().createProject(FreeStyleProject.class, \"should-not-exist\") })\n" + + "@Field int x\n" + + "echo 'hello'\n").toString(), containsString("Annotation ASTTest cannot be used in the sandbox")); + + assertNull(j.jenkins.getItem("should-not-exist")); + } + + @Issue("SECURITY-1293") + @Test + public void blockGrab() throws Exception { + StringScriptSource.DescriptorImpl d = j.jenkins.getDescriptorByType(StringScriptSource.DescriptorImpl.class); + assertThat(d.doCheckScript("@Grab(group='foo', module='bar', version='1.0')\ndef foo\n").toString(), + containsString("Annotation Grab cannot be used in the sandbox")); + } +}