From e9e8068d8732214f39a1d3406b647a3129438dde Mon Sep 17 00:00:00 2001 From: Jonathan Leitschuh Date: Wed, 21 Sep 2022 15:22:31 +0000 Subject: [PATCH] vuln-fix: Partial Path Traversal Vulnerability This fixes a partial path traversal vulnerability. Replaces `dir.getCanonicalPath().startsWith(parent.getCanonicalPath())`, which is vulnerable to partial path traversal attacks, with the more secure `dir.getCanonicalFile().toPath().startsWith(parent.getCanonicalFile().toPath())`. To demonstrate this vulnerability, consider `"/usr/outnot".startsWith("/usr/out")`. The check is bypassed although `/outnot` is not under the `/out` directory. It's important to understand that the terminating slash may be removed when using various `String` representations of the `File` object. For example, on Linux, `println(new File("/var"))` will print `/var`, but `println(new File("/var", "/")` will print `/var/`; however, `println(new File("/var", "/").getCanonicalPath())` will print `/var`. Weakness: CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') Severity: Medium CVSSS: 6.1 Detection: CodeQL & OpenRewrite (https://public.moderne.io/recipes/org.openrewrite.java.security.PartialPathTraversalVulnerability) Reported-by: Jonathan Leitschuh Signed-off-by: Jonathan Leitschuh Bug-tracker: https://github.com/JLLeitschuh/security-research/issues/13 Co-authored-by: Moderne --- .../java/org/apache/catalina/servlets/ManagerServlet.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/apache/catalina/servlets/ManagerServlet.java b/src/main/java/org/apache/catalina/servlets/ManagerServlet.java index 2a23dfe..3c6f0c9 100644 --- a/src/main/java/org/apache/catalina/servlets/ManagerServlet.java +++ b/src/main/java/org/apache/catalina/servlets/ManagerServlet.java @@ -1102,7 +1102,6 @@ protected void undeploy(PrintWriter writer, String path) { // Identify the appBase of the owning Host of this Context (if any) String appBase = null; File appBaseDir = null; - String appBasePath = null; if (context.getParent() instanceof Host) { appBase = ((Host) context.getParent()).getAppBase(); appBaseDir = new File(appBase); @@ -1110,7 +1109,6 @@ protected void undeploy(PrintWriter writer, String path) { appBaseDir = new File(System.getProperty("catalina.base"), appBase); } - appBasePath = appBaseDir.getCanonicalPath(); } // Validate the docBase path of this application @@ -1121,7 +1119,7 @@ protected void undeploy(PrintWriter writer, String path) { docBaseDir = new File(appBaseDir, docBase); } String docBasePath = docBaseDir.getCanonicalPath(); - if (!docBasePath.startsWith(deployedPath)) { + if (!docBaseDir.getCanonicalFile().toPath().startsWith(deployedPath)) { writer.println(sm.getString("managerServlet.noDocBase", displayPath)); return;