From b5ec2b48df3c4f7b4999c4edf137b34fbea694fd Mon Sep 17 00:00:00 2001 From: rsandell Date: Tue, 1 Mar 2022 16:54:23 +0100 Subject: [PATCH] [SECURITY-2185] --- .../CapturedEnvironmentAction.java | 24 +++- .../CapturedEnvironmentActionTest.java | 128 ++++++++++++++++++ .../jobs/tobetriggered/builds/1/build.xml | 44 ++++++ .../jobs/tobetriggered/builds/1/changelog.xml | 1 + .../onLoad/jobs/tobetriggered/builds/1/log | 9 ++ .../onLoad/jobs/tobetriggered/config.xml | 32 +++++ .../onLoad/jobs/tobetriggered/nextBuildNumber | 1 + .../onLoad/jobs/triggering/builds/1/build.xml | 49 +++++++ .../jobs/triggering/builds/1/changelog.xml | 1 + .../onLoad/jobs/triggering/builds/1/log | 8 ++ .../onLoad/jobs/triggering/config.xml | 43 ++++++ .../onLoad/jobs/triggering/nextBuildNumber | 1 + .../onLoad/queue.xml | 5 + 13 files changed, 344 insertions(+), 2 deletions(-) create mode 100644 src/test/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest.java create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/build.xml create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/changelog.xml create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/log create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/config.xml create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/nextBuildNumber create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/build.xml create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/changelog.xml create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/log create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/config.xml create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/nextBuildNumber create mode 100644 src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/queue.xml diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentAction.java b/src/main/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentAction.java index be214351..26589090 100644 --- a/src/main/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentAction.java +++ b/src/main/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentAction.java @@ -1,14 +1,20 @@ package hudson.plugins.parameterizedtrigger; import hudson.EnvVars; +import hudson.diagnosis.OldDataMonitor; import hudson.model.InvisibleAction; +import hudson.model.Run; +import jenkins.model.RunAction2; + +import java.util.Collections; /** * @author Nicolas De Loof */ -public class CapturedEnvironmentAction extends InvisibleAction { +public class CapturedEnvironmentAction extends InvisibleAction implements RunAction2 { - private final EnvVars env; + static final String OLD_DATA_MESSAGE = "The build.xml contains captured environment variables at the time of building which could contain sensitive data."; + private transient volatile EnvVars env; public CapturedEnvironmentAction(EnvVars env) { this.env = env; @@ -17,4 +23,18 @@ public CapturedEnvironmentAction(EnvVars env) { public EnvVars getCapturedEnvironment() { return env; } + + @Override + public void onAttached(final Run r) { + //noop + } + + @Override + public void onLoad(final Run r) { + if (env != null) { + OldDataMonitor.report(r, Collections.singletonList(new AssertionError(OLD_DATA_MESSAGE))); + } + //If it is not null then we loaded old data that needs to be cleaned, if it is null then it needs to be something. + env = new EnvVars(); + } } diff --git a/src/test/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest.java b/src/test/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest.java new file mode 100644 index 00000000..4af36c3b --- /dev/null +++ b/src/test/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest.java @@ -0,0 +1,128 @@ +package hudson.plugins.parameterizedtrigger; + +import hudson.ExtensionList; +import hudson.FilePath; +import hudson.diagnosis.OldDataMonitor; +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; +import hudson.model.Saveable; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.Issue; +import org.jvnet.hudson.test.JenkinsSessionRule; + +import java.io.File; +import java.net.URL; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.anEmptyMap; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.sameInstance; +import static org.hamcrest.collection.IsMapContaining.hasEntry; +import static org.hamcrest.core.IsNot.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class CapturedEnvironmentActionTest { + + @Rule + public JenkinsSessionRule j = new JenkinsSessionRule(); + + @Test + @Issue("SECURITY-2185") //@LocalData + public void onLoad() throws Throwable { + j.then(r -> { + final URL url = CapturedEnvironmentActionTest.class.getResource("/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad"); + if (url == null) { + fail("No test resources found!"); + } + if (!url.getProtocol().equals("file")) + throw new AssertionError("Test data is not available in the file system: " + url); + File home = new File(url.toURI()); + System.err.println("Loading $JENKINS_HOME from " + home); + new FilePath(home).copyRecursiveTo("**/*", r.jenkins.getRootPath()); + }); + j.then(r -> { + final OldDataMonitor monitor = ExtensionList.lookupSingleton(OldDataMonitor.class); + final FreeStyleProject triggering = r.jenkins.getItem("triggering", r.jenkins, FreeStyleProject.class); + final FreeStyleBuild build = triggering.getLastBuild(); + + assertTrue("OldDataMonitor should be active.", monitor.isActivated()); + Map data = monitor.getData(); + assertThat(data, + hasEntry(sameInstance(build), + new HasExtra(containsString("AssertionError: " + CapturedEnvironmentAction.OLD_DATA_MESSAGE)))); + + build.save(); + data = monitor.getData(); + assertThat(data, anEmptyMap()); + }); + j.then(r -> { + final OldDataMonitor monitor = ExtensionList.lookupSingleton(OldDataMonitor.class); + final FreeStyleProject triggering = r.jenkins.getItem("triggering", r.jenkins, FreeStyleProject.class); + + assertFalse("OldDataMonitor should not be active.", monitor.isActivated()); + + FreeStyleBuild build = triggering.getLastBuild(); + assertNotNull(build); + assertEquals(1, build.getNumber()); + CapturedEnvironmentAction action = build.getAction(CapturedEnvironmentAction.class); + assertNotNull(action); + assertThat(action.getCapturedEnvironment(), anEmptyMap()); + + r.buildAndAssertSuccess(triggering); + r.waitUntilNoActivity(); + + build = triggering.getLastBuild(); + assertNotNull(build); + assertEquals(2, build.getNumber()); + action = build.getAction(CapturedEnvironmentAction.class); + assertNotNull(action); + assertThat(action.getCapturedEnvironment(), not(anEmptyMap())); + }); + j.then(r -> { + final OldDataMonitor monitor = ExtensionList.lookupSingleton(OldDataMonitor.class); + final FreeStyleProject triggering = r.jenkins.getItem("triggering", r.jenkins, FreeStyleProject.class); + + assertFalse("OldDataMonitor should not be active.", monitor.isActivated()); + + FreeStyleBuild build = triggering.getLastBuild(); + assertNotNull(build); + assertEquals(2, build.getNumber()); + CapturedEnvironmentAction action = build.getAction(CapturedEnvironmentAction.class); + assertNotNull(action); + assertThat(action.getCapturedEnvironment(), anEmptyMap()); + }); + } + + private static class HasExtra extends TypeSafeMatcher { + private final Matcher valueMatcher; + + private HasExtra(final Matcher valueMatcher) { + this.valueMatcher = valueMatcher; + } + + @Override + protected boolean matchesSafely(final OldDataMonitor.VersionRange item) { + return valueMatcher.matches(item.extra); + } + + @Override + public void describeTo(final Description description) { + description.appendText(" a VersionRange with extra ").appendDescriptionOf(valueMatcher); + } + + @Override + protected void describeMismatchSafely(final OldDataMonitor.VersionRange item, final Description mismatchDescription) { + mismatchDescription.appendText(" extra was "); + valueMatcher.describeMismatch(item, mismatchDescription); + } + } +} \ No newline at end of file diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/build.xml b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/build.xml new file mode 100644 index 00000000..5768fa39 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/build.xml @@ -0,0 +1,44 @@ + + + + + + + + ok + false + + + + ok + + + + + + + triggering + job/triggering/ + 1 + + + + + 1 + + + + + 4 + 1646074593325 + 1646074593336 + SUCCESS + 64 + UTF-8 + false + + work/workspace/tobetriggered + 2.270 + + + \ No newline at end of file diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/changelog.xml b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/changelog.xml new file mode 100644 index 00000000..a8911916 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/changelog.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/log b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/log new file mode 100644 index 00000000..93294fd4 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/builds/1/log @@ -0,0 +1,9 @@ +Started by upstream project "ha:////4GRnFg0qnrPw4M47q42/6Hn+zLu1JydjlwbdO4AqwQb+AAAAmR+LCAAAAAAAAP9b85aBtbiIQTGjNKU4P08vOT+vOD8nVc83PyU1x6OyILUoJzMv2y+/JJUBAhiZGBgqihhk0NSjKDWzXb3RdlLBUSYGJk8GtpzUvPSSDB8G5tKinBIGIZ+sxLJE/ZzEvHT94JKizLx0a6BxUmjGOUNodHsLgAyuEgYB/az8JH2g5vT0VJAJ+gCV2UdCxQAAAA==triggering" build number ha:////4D+Ec5DGhEbnE6Cp3rmOis4sanYY4ucMjj06VZLZDDfkAAAAmR+LCAAAAAAAAP9b85aBtbiIQTGjNKU4P08vOT+vOD8nVc83PyU1x6OyILUoJzMv2y+/JJUBAhiZGBgqihhk0NSjKDWzXb3RdlLBUSYGJk8GtpzUvPSSDB8G5tKinBIGIZ+sxLJE/ZzEvHT94JKizLx0a6BxUmjGOUNodHsLQIwSBkH9rPwkfaDm9PRUkAn6RgBro0wrxgAAAA==2 +originally caused by: + Started by user unknown or anonymous +Running as SYSTEM +Building in workspace work/workspace/tobetriggered +[tobetriggered] $ /bin/sh -xe /tmp/jenkins6745008012408524781.sh ++ echo warning +warning +Finished: SUCCESS diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/config.xml b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/config.xml new file mode 100644 index 00000000..2004b582 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/config.xml @@ -0,0 +1,32 @@ + + + + + false + + + + + ok + Are you OK? + true + + + + + + true + false + false + false + + false + + + echo warning + + + + + + \ No newline at end of file diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/nextBuildNumber b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/nextBuildNumber new file mode 100644 index 00000000..0cfbf088 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/tobetriggered/nextBuildNumber @@ -0,0 +1 @@ +2 diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/build.xml b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/build.xml new file mode 100644 index 00000000..19f37c2d --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/build.xml @@ -0,0 +1,49 @@ + + + + + + + + 1 + + + + + + + + + + + 4 + BUILD_DISPLAY_NAME + #2 + BUILD_ID + 2 + BUILD_NUMBER + 1 + BUILD_TAG + jenkins-triggering-2 + + + + UNIX + + + + + + 3 + 1646074584286 + 1646074584297 + SUCCESS + 117 + UTF-8 + false + + work/workspace/triggering + 2.270 + + + \ No newline at end of file diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/changelog.xml b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/changelog.xml new file mode 100644 index 00000000..a8911916 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/changelog.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/log b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/log new file mode 100644 index 00000000..71a8adb4 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/builds/1/log @@ -0,0 +1,8 @@ +Started by user unknown or anonymous +Running as SYSTEM +Building in workspace work/workspace/triggering +[triggering] $ /bin/sh -xe /tmp/jenkins6322047612148674788.sh ++ echo hello world +hello world +Triggering a new build of ha:////4GiHzYchwi/IfoIgwGyntRMZkxF7TZatrqlGUxMVSCGyAAAAnh+LCAAAAAAAAP9b85aBtbiIQTGjNKU4P08vOT+vOD8nVc83PyU1x6OyILUoJzMv2y+/JJUBAhiZGBgqihhk0NSjKDWzXb3RdlLBUSYGJk8GtpzUvPSSDB8G5tKinBIGIZ+sxLJE/ZzEvHT94JKizLx0a6BxUmjGOUNodHsLgAzeEgZh/az8JP2S/KRUoAHp6alFqSn6ALQLPErIAAAAtobetriggered +Finished: SUCCESS diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/config.xml b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/config.xml new file mode 100644 index 00000000..5920522c --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/config.xml @@ -0,0 +1,43 @@ + + + + + false + + + true + false + false + false + + false + + + echo hello world + + + + + + + + + + + + ok + false + + + + + tobetriggered, + ALWAYS + false + false + + + + + + \ No newline at end of file diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/nextBuildNumber b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/nextBuildNumber new file mode 100644 index 00000000..0cfbf088 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/jobs/triggering/nextBuildNumber @@ -0,0 +1 @@ +2 diff --git a/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/queue.xml b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/queue.xml new file mode 100644 index 00000000..e8f43c12 --- /dev/null +++ b/src/test/resources/hudson/plugins/parameterizedtrigger/CapturedEnvironmentActionTest/onLoad/queue.xml @@ -0,0 +1,5 @@ + + + 4 + + \ No newline at end of file