Security context
Medium· 4.3GHSA-w2hv-rcqr-2h7r CVE-2021-21640CWE-240Published May 24, 2022

View name validation bypass 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.277.22.278 → fixed in 2.287

Details

Jenkins 2.286 and earlier, LTS 2.277.1 and earlier does not properly check that a newly created view has an allowed name. When a form to create a view is submitted, the name is included twice in the submission. One instance is validated, but the other instance is used to create the value. This allows attackers with View/Create permission to create views with invalid or already-used names. Jenkins 2.287, LTS 2.277.2 uses the same submitted value for validation and view creation.

The fix

[SECURITY-1871]

Matt Sicker· Mar 25, 2021, 07:23 AM+37142e2c74049
core/src/main/java/hudson/model/View.java+3 1
@@ -1357,7 +1357,9 @@ public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup own
}
// create a view
- v = descriptor.newInstance(req,req.getSubmittedForm());
+ JSONObject submittedForm = req.getSubmittedForm();
+ submittedForm.put("name", name);
+ v = descriptor.newInstance(req, submittedForm);
}
owner.getACL().checkCreatePermission(owner, v.getDescriptor());
v.owner = owner;
test/src/test/java/hudson/model/ViewSEC1871Test.java+34 0
@@ -0,0 +1,34 @@
+package hudson.model;
+
+import com.gargoylesoftware.htmlunit.FormEncodingType;
+import com.gargoylesoftware.htmlunit.HttpMethod;
+import com.gargoylesoftware.htmlunit.WebRequest;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.Issue;
+import org.jvnet.hudson.test.JenkinsRule;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class ViewSEC1871Test {
+
+ @Rule
+ public JenkinsRule j = new JenkinsRule();
+
+ @Test
+ @Issue("SECURITY-1871")
+ public void shouldNotAllowInconsistentViewName() throws IOException {
+ assertNull(j.jenkins.getView("ViewName"));
+ JenkinsRule.WebClient wc = j.createWebClient();
+ WebRequest req = new WebRequest(wc.createCrumbedUrl("createView"), HttpMethod.POST);
+ req.setEncodingType(FormEncodingType.URL_ENCODED);
+ req.setRequestBody("name=ViewName&mode=hudson.model.ListView&json=" + URLEncoder.encode("{\"mode\":\"hudson.model.ListView\",\"name\":\"DifferentViewName\"}", "UTF-8"));
+ wc.getPage(req);
+ assertNull(j.jenkins.getView("DifferentViewName"));
+ assertNotNull(j.jenkins.getView("ViewName"));
+ }
+}

References