Medium severity5.4NVD Advisory· Published Feb 3, 2016· Updated May 6, 2026
CVE-2015-7536
CVE-2015-7536
Description
Cross-site scripting (XSS) vulnerability in Jenkins before 1.640 and LTS before 1.625.2 allows remote authenticated users to inject arbitrary web script or HTML via unspecified vectors related to workspaces and archived artifacts.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jenkins-ci.main:jenkins-coreMaven | >= 1.626, < 1.640 | 1.640 |
org.jenkins-ci.main:jenkins-coreMaven | < 1.625.2 | 1.625.2 |
Affected products
2Patches
227c303417a22Merge pull request #49 from jenkinsci-cert/SECURITY-95
2 files changed · +46 −0
core/src/main/java/hudson/model/DirectoryBrowserSupport.java+16 −0 modified@@ -47,6 +47,8 @@ import org.apache.commons.io.IOUtils; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -307,6 +309,17 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root // pseudo file name to let the Stapler set text/plain rsp.serveFile(req, in, lastModified, -1, length, "plain.txt"); } else { + String csp = System.getProperty(DirectoryBrowserSupport.class.getName() + ".CSP"); + if (csp == null) { + // default value unless overridden with system property + csp = DEFAULT_CSP_VALUE; + } + if (!csp.trim().equals("")) { + // allow users to prevent sending this header by setting empty system property + for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) { + rsp.setHeader(header, csp); + } + } rsp.serveFile(req, in, lastModified, -1, length, baseFile.getName() ); } } @@ -574,4 +587,7 @@ private static void buildPathList(VirtualFile baseDir, VirtualFile filePath, Lis private static final Logger LOGGER = Logger.getLogger(DirectoryBrowserSupport.class.getName()); + + @Restricted(NoExternalUse.class) + public static final String DEFAULT_CSP_VALUE = "sandbox; default-src 'none'; img-src 'self'; style-src 'self';"; }
test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java+30 −0 modified@@ -169,6 +169,36 @@ public void zipDownload() throws Exception { zipfile.delete(); } + @Issue("SECURITY-95") + @Test + public void contentSecurityPolicy() throws Exception { + FreeStyleProject p = j.createFreeStyleProject(); + p.setScm(new SingleFileSCM("test.html", "<html><body><h1>Hello world!</h1></body></html>")); + p.getPublishersList().add(new ArtifactArchiver("*", "", true)); + assertEquals(Result.SUCCESS, p.scheduleBuild2(0).get().getResult()); + + HtmlPage page = j.createWebClient().goTo("job/" + p.getName() + "/lastSuccessfulBuild/artifact/test.html"); + for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) { + assertEquals("Header set: " + header, page.getWebResponse().getResponseHeaderValue(header), DirectoryBrowserSupport.DEFAULT_CSP_VALUE); + } + + String propName = DirectoryBrowserSupport.class.getName() + ".CSP"; + String initialValue = System.getProperty(propName); + try { + System.setProperty(propName, ""); + page = j.createWebClient().goTo("job/" + p.getName() + "/lastSuccessfulBuild/artifact/test.html"); + for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) { + assertFalse("Header not set: " + header, page.getWebResponse().getResponseHeaders().contains(header)); + } + } finally { + if (initialValue == null) { + System.clearProperty(DirectoryBrowserSupport.class.getName() + ".CSP"); + } else { + System.setProperty(DirectoryBrowserSupport.class.getName() + ".CSP", initialValue); + } + } + } + private File download(UnexpectedPage page) throws IOException { File file = File.createTempFile("DirectoryBrowserSupport", "zipDownload");
d3fb2c09f290[FIX SECURITY-95] Add CSP headers to files served by Jenkins
2 files changed · +46 −0
core/src/main/java/hudson/model/DirectoryBrowserSupport.java+16 −0 modified@@ -47,6 +47,8 @@ import org.apache.commons.io.IOUtils; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -307,6 +309,17 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root // pseudo file name to let the Stapler set text/plain rsp.serveFile(req, in, lastModified, -1, length, "plain.txt"); } else { + String csp = System.getProperty(DirectoryBrowserSupport.class.getName() + ".CSP"); + if (csp == null) { + // default value unless overridden with system property + csp = DEFAULT_CSP_VALUE; + } + if (!csp.trim().equals("")) { + // allow users to prevent sending this header by setting empty system property + for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) { + rsp.setHeader(header, csp); + } + } rsp.serveFile(req, in, lastModified, -1, length, baseFile.getName() ); } } @@ -574,4 +587,7 @@ private static void buildPathList(VirtualFile baseDir, VirtualFile filePath, Lis private static final Logger LOGGER = Logger.getLogger(DirectoryBrowserSupport.class.getName()); + + @Restricted(NoExternalUse.class) + public static final String DEFAULT_CSP_VALUE = "sandbox; default-src 'none'; img-src 'self'; style-src 'self';"; }
test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java+30 −0 modified@@ -169,6 +169,36 @@ public void zipDownload() throws Exception { zipfile.delete(); } + @Issue("SECURITY-95") + @Test + public void contentSecurityPolicy() throws Exception { + FreeStyleProject p = j.createFreeStyleProject(); + p.setScm(new SingleFileSCM("test.html", "<html><body><h1>Hello world!</h1></body></html>")); + p.getPublishersList().add(new ArtifactArchiver("*", "", true)); + assertEquals(Result.SUCCESS, p.scheduleBuild2(0).get().getResult()); + + HtmlPage page = j.createWebClient().goTo("job/" + p.getName() + "/lastSuccessfulBuild/artifact/test.html"); + for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) { + assertEquals("Header set: " + header, page.getWebResponse().getResponseHeaderValue(header), DirectoryBrowserSupport.DEFAULT_CSP_VALUE); + } + + String propName = DirectoryBrowserSupport.class.getName() + ".CSP"; + String initialValue = System.getProperty(propName); + try { + System.setProperty(propName, ""); + page = j.createWebClient().goTo("job/" + p.getName() + "/lastSuccessfulBuild/artifact/test.html"); + for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) { + assertFalse("Header not set: " + header, page.getWebResponse().getResponseHeaders().contains(header)); + } + } finally { + if (initialValue == null) { + System.clearProperty(DirectoryBrowserSupport.class.getName() + ".CSP"); + } else { + System.setProperty(DirectoryBrowserSupport.class.getName() + ".CSP", initialValue); + } + } + } + private File download(UnexpectedPage page) throws IOException { File file = File.createTempFile("DirectoryBrowserSupport", "zipDownload");
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-x3p3-929j-pq66ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2015-7536ghsaADVISORY
- wiki.jenkins-ci.org/display/SECURITY/Jenkins+Security+Advisory+2015-12-09nvdVendor AdvisoryWEB
- github.com/jenkinsci/jenkins/commit/27c303417a226bf4c06a588570f28ac2e2507c6cghsaWEB
- github.com/jenkinsci/jenkins/commit/d3fb2c09f29007dce84a213ae8323df1105dcc30ghsaWEB
News mentions
0No linked articles in our index yet.