From 9de62915807deab61d6e780eed660428f9889b51 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 9 Feb 2018 11:25:42 -0500 Subject: [PATCH] [SECURITY-705] Additional precautions. --- core/src/main/java/hudson/Plugin.java | 2 +- test/src/test/java/hudson/PluginTest.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/hudson/Plugin.java b/core/src/main/java/hudson/Plugin.java index e8d8be1e693b..32ca74a1b54a 100644 --- a/core/src/main/java/hudson/Plugin.java +++ b/core/src/main/java/hudson/Plugin.java @@ -228,7 +228,7 @@ public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOExceptio String path = req.getRestOfPath(); String pathUC = path.toUpperCase(Locale.ENGLISH); - if (path.isEmpty() || path.contains("..") || path.contains("%") || pathUC.contains("META-INF") || pathUC.contains("WEB-INF")) { + if (path.isEmpty() || path.contains("..") || path.startsWith(".") || path.contains("%") || pathUC.contains("META-INF") || pathUC.contains("WEB-INF")) { LOGGER.warning("rejecting possibly malicious " + req.getRequestURIWithQueryString()); rsp.sendError(HttpServletResponse.SC_BAD_REQUEST); return; diff --git a/test/src/test/java/hudson/PluginTest.java b/test/src/test/java/hudson/PluginTest.java index 4ddfd44f94d3..ef9bc38a5208 100644 --- a/test/src/test/java/hudson/PluginTest.java +++ b/test/src/test/java/hudson/PluginTest.java @@ -37,17 +37,17 @@ public class PluginTest { @Issue({"SECURITY-131", "SECURITY-155", "SECURITY-705"}) @Test public void doDynamic() throws Exception { r.createWebClient().goTo("plugin/credentials/images/24x24/credentials.png", "image/png"); - /* Collapsed somewhere before it winds up in restOfPath: - r.createWebClient().assertFails("plugin/credentials/images/../images/24x24/credentials.png", HttpServletResponse.SC_BAD_REQUEST); - */ + r.createWebClient().goTo("plugin/credentials/images/../images/24x24/credentials.png", "image/png"); // collapsed somewhere before it winds up in restOfPath r.createWebClient().assertFails("plugin/credentials/images/%2E%2E/images/24x24/credentials.png", HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // IAE from TokenList. r.createWebClient().assertFails("plugin/credentials/images/%252E%252E/images/24x24/credentials.png", HttpServletResponse.SC_BAD_REQUEST); // SECURITY-131 r.createWebClient().assertFails("plugin/credentials/images/%25252E%25252E/images/24x24/credentials.png", HttpServletResponse.SC_BAD_REQUEST); // just checking // SECURITY-705: r.createWebClient().assertFails("plugin/credentials/images/..%2fWEB-INF/licenses.xml", HttpServletResponse.SC_BAD_REQUEST); + r.createWebClient().assertFails("plugin/credentials/./credentials.jpi", /* Path collapsed to simply `credentials.jpi` before entering */ HttpServletResponse.SC_NOT_FOUND); r.createWebClient().assertFails("plugin/credentials/images/%2e%2e%2fWEB-INF/licenses.xml", HttpServletResponse.SC_BAD_REQUEST); r.createWebClient().assertFails("plugin/credentials/images/%2e.%2fWEB-INF/licenses.xml", HttpServletResponse.SC_BAD_REQUEST); r.createWebClient().assertFails("plugin/credentials/images/..%2f..%2f..%2f" + r.jenkins.getRootDir().getName() + "%2fsecrets%2fmaster.key", HttpServletResponse.SC_BAD_REQUEST); + r.createWebClient().assertFails("plugin/credentials/" + r.jenkins.getRootDir() + "/secrets/master.key", /* ./ prepended anyway */ HttpServletResponse.SC_NOT_FOUND); // SECURITY-155: r.createWebClient().assertFails("plugin/credentials/WEB-INF/licenses.xml", HttpServletResponse.SC_BAD_REQUEST); r.createWebClient().assertFails("plugin/credentials/META-INF/MANIFEST.MF", HttpServletResponse.SC_BAD_REQUEST);