View name validation bypass in Jenkins
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
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]
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
- ADVISORYhttps://nvd.nist.gov/vuln/detail/CVE-2021-21640
- WEBhttps://github.com/jenkinsci/jenkins/commit/42e2c74049ddf5e0aca1fe6aadc7b24fdabb5494
- PACKAGEhttps://github.com/jenkinsci/jenkins
- WEBhttps://www.jenkins.io/security/advisory/2021-04-07/#SECURITY-1871
- WEBhttp://www.openwall.com/lists/oss-security/2021/04/07/2