CVE-2017-1000400
Description
Jenkins remote API disclosed upstream/downstream project information to users without permission, fixed by filtering results based on user's Item/Read access.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jenkins remote API disclosed upstream/downstream project information to users without permission, fixed by filtering results based on user's Item/Read access.
Vulnerability
In Jenkins versions 2.73.1 and earlier, and 2.83 and earlier, the remote API endpoint /job/(job-name)/api exposed information about upstream and downstream projects. This included tasks that the current user had no access to, such as due to lack of Item/Read permission [1][2]. The vulnerability is tracked as SECURITY-617 [3].
Exploitation
An attacker could access the remote API for a job they have at least some access to (e.g., Item/Read on that job) and then enumerate upstream/downstream projects. No authentication is required beyond Jenkins session, but the attacker must have some permission on the job to access its API endpoint. The API would reveal project names and tasks of linked projects even if the attacker lacked Item/Read permission on those projects [1][2].
Impact
An attacker with limited access to a Jenkins job could gain information about other upstream/downstream projects and their tasks, bypassing access control restrictions. This constitutes an information disclosure vulnerability, potentially exposing sensitive project names and build triggers that the attacker should not have been able to see [1][2].
Mitigation
The fix was released in Jenkins 2.74 and 2.84 (or later). Users should upgrade to Jenkins 2.74 or 2.84 or later. No workaround is available [2][3].
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jenkins-ci.main:jenkins-coreMaven | < 2.73.2 | 2.73.2 |
org.jenkins-ci.main:jenkins-coreMaven | >= 2.74, < 2.84 | 2.84 |
Affected products
1Patches
1b2083a387a5b[SECURITY-617] Do not export information about hidden upstream or downstream projects.
3 files changed · +98 −3
core/src/main/java/hudson/model/AbstractBuild.java+1 −1 modified@@ -1108,7 +1108,7 @@ public String getWhyKeepLog() { AbstractBuild<?,?> b = p.getBuildByNumber(i); if (b!=null) - return Messages.AbstractBuild_KeptBecause(b); + return Messages.AbstractBuild_KeptBecause(p.hasPermission(Item.READ) ? b.toString() : "?"); } }
core/src/main/java/hudson/model/AbstractProject.java+24 −2 modified@@ -1645,16 +1645,38 @@ public <T extends Trigger> T getTrigger(Class<T> clazz) { * Gets the other {@link AbstractProject}s that should be built * when a build of this project is completed. */ - @Exported public final List<AbstractProject> getDownstreamProjects() { return Jenkins.getInstance().getDependencyGraph().getDownstream(this); } - @Exported + @Exported(name="downstreamProjects") + @Restricted(DoNotUse.class) // only for exporting + public List<AbstractProject> getDownstreamProjectsForApi() { + List<AbstractProject> r = new ArrayList<>(); + for (AbstractProject p : getDownstreamProjects()) { + if (p.hasPermission(Item.READ)) { + r.add(p); + } + } + return r; + } + public final List<AbstractProject> getUpstreamProjects() { return Jenkins.getInstance().getDependencyGraph().getUpstream(this); } + @Exported(name="upstreamProjects") + @Restricted(DoNotUse.class) // only for exporting + public List<AbstractProject> getUpstreamProjectsForApi() { + List<AbstractProject> r = new ArrayList<>(); + for (AbstractProject p : getUpstreamProjects()) { + if (p.hasPermission(Item.READ)) { + r.add(p); + } + } + return r; + } + /** * Returns only those upstream projects that defines {@link BuildTrigger} to this project. * This is a subset of {@link #getUpstreamProjects()}
test/src/test/java/hudson/model/AbstractProject2Test.java+73 −0 added@@ -0,0 +1,73 @@ +/* + * The MIT License + * + * Copyright 2017 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. + */ + +package hudson.model; + +import hudson.tasks.BuildTrigger; +import java.util.Collections; +import jenkins.model.Jenkins; +import static org.hamcrest.Matchers.*; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Rule; +import org.jvnet.hudson.test.Issue; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.MockAuthorizationStrategy; + +// TODO merge with AbstractProjectTest when converted from Groovy to Java +public class AbstractProject2Test { + + @Rule + public JenkinsRule r = new JenkinsRule(); + + @Issue("SECURITY-617") + @Test + public void upstreamDownstreamExportApi() throws Exception { + FreeStyleProject us = r.createFreeStyleProject("upstream-project"); + FreeStyleProject ds = r.createFreeStyleProject("downstream-project"); + us.getPublishersList().add(new BuildTrigger(Collections.singleton(ds), Result.SUCCESS)); + r.jenkins.rebuildDependencyGraph(); + assertEquals(Collections.singletonList(ds), us.getDownstreamProjects()); + assertEquals(Collections.singletonList(us), ds.getUpstreamProjects()); + r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy(). + grant(Jenkins.READ).everywhere().toEveryone(). + grant(Item.READ).everywhere().to("alice"). + grant(Item.READ).onItems(us).to("bob"). + grant(Item.READ).onItems(ds).to("charlie")); + String api = r.createWebClient().login("alice").goTo(us.getUrl() + "api/json?pretty", null).getWebResponse().getContentAsString(); + System.out.println(api); + assertThat(api, containsString("downstream-project")); + api = r.createWebClient().login("alice").goTo(ds.getUrl() + "api/json?pretty", null).getWebResponse().getContentAsString(); + System.out.println(api); + assertThat(api, containsString("upstream-project")); + api = r.createWebClient().login("bob").goTo(us.getUrl() + "api/json?pretty", null).getWebResponse().getContentAsString(); + System.out.println(api); + assertThat(api, not(containsString("downstream-project"))); + api = r.createWebClient().login("charlie").goTo(ds.getUrl() + "api/json?pretty", null).getWebResponse().getContentAsString(); + System.out.println(api); + assertThat(api, not(containsString("upstream-project"))); + } + +}
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-p8x8-p473-mmmvghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-1000400ghsaADVISORY
- github.com/jenkinsci/jenkins/blob/6d179998e18adfbaa4e443c7e837135bf36c53d7/test/src/test/java/hudson/model/AbstractProjectTest.javaghsaWEB
- github.com/jenkinsci/jenkins/commit/b2083a387a5bdb6f7ee7f7c81a1f6312aca2a558ghsaWEB
- jenkins.io/security/advisory/2017-10-11ghsaWEB
- jenkins.io/security/advisory/2017-10-11/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.