Security context
Medium· 5.4GHSA-hg6g-jj7g-x6v2 CVE-2019-10401CWE-79Published May 24, 2022

Improper Neutralization of Input During Web Page Generation in Jenkins

Research this vulnerability

Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.

Affected versions

0 → fixed in 2.176.42.177 → fixed in 2.197

Details

In Jenkins 2.196 and earlier, LTS 2.176.3 and earlier, the f:expandableTextBox form control interpreted its content as HTML when expanded, resulting in a stored XSS vulnerability exploitable by users with permission to define its contents (typically Job/Configure).

The fix

[SECURITY-1498]

Wadeck Follonier· Sep 10, 2019, 06:31 PM+932df600eb7a2
test/src/test/java/lib/form/ExpandableTextboxSEC1498Test.java+58 0
@@ -0,0 +1,58 @@
+package lib.form;
+
+import com.gargoylesoftware.htmlunit.html.HtmlElementUtil;
+import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import hudson.model.FreeStyleProject;
+import hudson.model.Job;
+import jenkins.model.OptionalJobProperty;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.TestExtension;
+
+import static org.junit.Assert.assertEquals;
+
+//TODO meant to be merged back into ExpandableTextboxTest after security release to avoid conflict during the upmerge process
+public class ExpandableTextboxSEC1498Test {
+ @Rule
+ public JenkinsRule j = new JenkinsRule();
+
+ @Test
+ public void noXssUsingInputValue() throws Exception {
+ XssProperty xssProperty = new XssProperty("</textarea><h1>HACK</h1>");
+ FreeStyleProject p = j.createFreeStyleProject();
+ p.addProperty(xssProperty);
+
+ JenkinsRule.WebClient wc = j.createWebClient();
+ HtmlPage configurePage = wc.getPage(p, "configure");
+
+ int numberOfH1Before = configurePage.getElementsByTagName("h1").size();
+
+ HtmlInput xssInput = configurePage.getElementByName("_.xss");
+ HtmlInput expandButton = (HtmlInput) xssInput.getParentNode().getNextSibling().getFirstChild();
+ HtmlElementUtil.click(expandButton);
+
+ // no additional h1, meaning the "payload" is not interpreted
+ int numberOfH1After = configurePage.getElementsByTagName("h1").size();
+
+ assertEquals(numberOfH1Before, numberOfH1After);
+ }
+
+ public static final class XssProperty extends OptionalJobProperty<Job<?,?>> {
+
+ private String xss;
+
+ public XssProperty(String xss){
+ this.xss = xss;
+ }
+
+ public String getXss() {
+ return xss;
+ }
+
+ @TestExtension("noXssUsingInputValue")
+ public static class DescriptorImpl extends OptionalJobProperty.OptionalJobPropertyDescriptor {
+ }
+ }
+}
test/src/test/resources/lib/form/ExpandableTextboxSEC1498Test/XssProperty/config-details.jelly+29 0
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+<?jelly escape-by-default='true'?>
+<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
+ <f:entry field="xss">
+ <f:expandableTextbox />
+ </f:entry>
+</j:jelly>
war/src/main/webapp/scripts/hudson-behavior.js+6 2
@@ -1505,8 +1505,12 @@ function expandTextArea(button,id) {
n = n.parentNode;
}
- n.parentNode.innerHTML =
- "<textarea rows=8 class='setting-input' name='"+field.name+"'>"+value+"</textarea>";
+ var parent = n.parentNode;
+ parent.innerHTML = "<textarea rows=8 class='setting-input'></textarea>";
+ var textArea = parent.childNodes[0];
+ textArea.name = field.name;
+ textArea.innerText = value;
+
layoutUpdateCallback.call();
}

References