Skip to content

Commit

Permalink
[SECURITY-1336] Prevent unsandboxed invocation of constructors
Browse files Browse the repository at this point in the history
Co-authored-by: Jesse Glick <jglick@cloudbees.com>
  • Loading branch information
2 people authored and dwnusbaum committed Feb 27, 2019
1 parent 32b4016 commit c396140
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 6 deletions.
Expand Up @@ -18,6 +18,8 @@
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.SourceUnit;
import org.jenkinsci.plugins.scriptsecurity.sandbox.Whitelist;
import org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox;

/**
* {@link GroovyShell} with additional tweaks necessary to run {@link CpsScript}
Expand Down Expand Up @@ -126,12 +128,20 @@ public Script parse(GroovyCodeSource codeSource) throws CompilationFailedExcepti
}

private Script doParse(GroovyCodeSource codeSource) throws CompilationFailedException {
if (execution != null) {
try (CpsFlowExecution.Timing t = execution.time(CpsFlowExecution.TimingKind.parse)) {
return super.parse(codeSource);
}
} else {
return super.parse(codeSource);
try {
return GroovySandbox.runInSandbox(() -> {
if (execution != null) {
try (CpsFlowExecution.Timing t = execution.time(CpsFlowExecution.TimingKind.parse)) {
return super.parse(codeSource);
}
} else {
return super.parse(codeSource);
}
}, Whitelist.all());
} catch (RuntimeException x) { // incl. CompilationFailedException, RejectedAccessException
throw x;
} catch (Exception x) {
throw new AssertionError(x);
}
}

Expand Down
Expand Up @@ -552,4 +552,22 @@ public void sandboxRejectsASTTransforms() throws Exception {

assertNull(jenkins.jenkins.getItem("should-not-exist"));
}

@Issue("SECURITY-1336")
@Test
public void blockConstructorInvocationAtRuntime() throws Exception {
WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "w");
job.setDefinition(new CpsFlowDefinition(
"class DoNotRunConstructor extends org.jenkinsci.plugins.workflow.cps.CpsScript {\n" +
" DoNotRunConstructor() {\n" +
" assert jenkins.model.Jenkins.instance.createProject(hudson.model.FreeStyleProject, 'should-not-exist')\n" +
" }\n" +
" Object run() {null}\n" +
"}\n", true));
WorkflowRun b = job.scheduleBuild2(0).get();
assertNull(jenkins.jenkins.getItem("should-not-exist"));
jenkins.assertBuildStatus(Result.FAILURE, b);
jenkins.assertLogContains("staticMethod jenkins.model.Jenkins getInstance", b);
}

}
Expand Up @@ -31,6 +31,7 @@
import hudson.security.ACL;
import hudson.security.ACLContext;
import jenkins.model.Jenkins;
import org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.junit.Test;
import static org.junit.Assert.*;
Expand Down Expand Up @@ -97,4 +98,21 @@ public void configureRequired() throws Exception {
assertThat(d.doCheckScriptCompile(job, "echo 'hello").toString(), containsString("success"));
}
}

@Issue("SECURITY-1336")
@Test
public void blockConstructorInvocationInCheck() throws Exception {
CpsFlowDefinition.DescriptorImpl d = r.jenkins.getDescriptorByType(CpsFlowDefinition.DescriptorImpl.class);
WorkflowJob job = r.jenkins.createProject(WorkflowJob.class, "w");
assertThat(d.doCheckScriptCompile(job, "import jenkins.model.Jenkins\n" +
"import hudson.model.FreeStyleProject\n" +
"public class DoNotRunConstructor {\n" +
" public DoNotRunConstructor() {\n" +
" assert Jenkins.getInstance().createProject(FreeStyleProject.class, \"should-not-exist\")\n" +
" }\n" +
"}\n").toString(), containsString("success"));

assertNull(r.jenkins.getItem("should-not-exist"));
}

}

0 comments on commit c396140

Please sign in to comment.