From 9db360c0113db8f51a27bc94e063bbc55508e5f1 Mon Sep 17 00:00:00 2001 From: Jonathan Leitschuh Date: Fri, 29 Jul 2022 13:23:49 +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 --- .../PureUtilities/VirtualFS/RealFileSystemLayer.java | 6 +++--- src/main/java/com/laytonsmith/core/Security.java | 2 +- src/main/java/com/laytonsmith/core/asm/AsmInstaller.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/laytonsmith/PureUtilities/VirtualFS/RealFileSystemLayer.java b/src/main/java/com/laytonsmith/PureUtilities/VirtualFS/RealFileSystemLayer.java index 0efc762608..3ba26e8c31 100644 --- a/src/main/java/com/laytonsmith/PureUtilities/VirtualFS/RealFileSystemLayer.java +++ b/src/main/java/com/laytonsmith/PureUtilities/VirtualFS/RealFileSystemLayer.java @@ -23,17 +23,17 @@ public RealFileSystemLayer(VirtualFile path, VirtualFileSystem fileSystem, Strin super(path, fileSystem, symlink); if(symlink == null) { real = new File(fileSystem.root, path.getPath()); - if(!real.getCanonicalPath().startsWith(fileSystem.root.getCanonicalPath())) { + if(!real.getCanonicalFile().toPath().startsWith(fileSystem.root.getCanonicalFile().toPath())) { throw new PermissionException(path.getPath() + " extends above the root directory of this file system, and does not point to a valid file."); } } else { File symlinkRoot = new File(fileSystem.symlinkFile, symlink); real = new File(symlinkRoot, path.getPath()); //If the path extends above the symlink, disallow it - if(!real.getCanonicalPath().startsWith(symlinkRoot.getCanonicalPath())) { + if(!real.getCanonicalFile().toPath().startsWith(symlinkRoot.getCanonicalFile().toPath())) { //Unless of course, the path is still within the full real path, then //eh, we'll allow it. - if(!real.getCanonicalPath().startsWith(fileSystem.root.getCanonicalPath())) { + if(!real.getCanonicalFile().toPath().startsWith(fileSystem.root.getCanonicalFile().toPath())) { throw new PermissionException(path.getPath() + " extends above the root directory of this file system, and does not point to a valid file."); } } diff --git a/src/main/java/com/laytonsmith/core/Security.java b/src/main/java/com/laytonsmith/core/Security.java index 9affb26ad8..67dcbef26c 100644 --- a/src/main/java/com/laytonsmith/core/Security.java +++ b/src/main/java/com/laytonsmith/core/Security.java @@ -34,7 +34,7 @@ public static boolean CheckSecurity(String location) throws IOException { baseFinal = baseFinal.substring(0, baseFinal.length() - 1); } File loc = new File(location); - if(loc.getCanonicalPath().startsWith(baseFinal)) { + if(loc.getCanonicalFile().toPath().startsWith(baseFinal)) { return true; } } diff --git a/src/main/java/com/laytonsmith/core/asm/AsmInstaller.java b/src/main/java/com/laytonsmith/core/asm/AsmInstaller.java index f3652ed405..447148bf75 100644 --- a/src/main/java/com/laytonsmith/core/asm/AsmInstaller.java +++ b/src/main/java/com/laytonsmith/core/asm/AsmInstaller.java @@ -200,7 +200,7 @@ public static File getWindowsBuildToolsLocation() { } for(File fullVersion : buildTool.listFiles()) { try { - if(fullVersion.getCanonicalPath().startsWith(withVersion.getCanonicalPath())) { + if(fullVersion.getCanonicalFile().toPath().startsWith(withVersion.getCanonicalFile().toPath())) { return fullVersion; } } catch (IOException e) {