From 6a256a69b625696337aca043f63c2009b2c4053f Mon Sep 17 00:00:00 2001 From: Jonathan Leitschuh Date: Fri, 4 Nov 2022 16:32:17 +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 --- .../objectstorage/services/s3/transfer/TransferManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ibm-cos-java-sdk-s3/src/main/java/com/ibm/cloud/objectstorage/services/s3/transfer/TransferManager.java b/ibm-cos-java-sdk-s3/src/main/java/com/ibm/cloud/objectstorage/services/s3/transfer/TransferManager.java index a860286431..7523777ab5 100644 --- a/ibm-cos-java-sdk-s3/src/main/java/com/ibm/cloud/objectstorage/services/s3/transfer/TransferManager.java +++ b/ibm-cos-java-sdk-s3/src/main/java/com/ibm/cloud/objectstorage/services/s3/transfer/TransferManager.java @@ -1512,7 +1512,7 @@ public MultipleFileDownload downloadDirectory(String bucketName, String keyPrefi private boolean leavesRoot(File localBaseDirectory, String key) { try { - return !new File(localBaseDirectory, key).getCanonicalPath().startsWith(localBaseDirectory.getCanonicalPath()); + return !new File(localBaseDirectory, key).getCanonicalFile().toPath().startsWith(localBaseDirectory.getCanonicalFile().toPath()); } catch (IOException e) { throw new RuntimeException("Unable to canonicalize paths", e); }