Skip to content

Commit

Permalink
vuln-fix: Zip Slip Vulnerability
Browse files Browse the repository at this point in the history
This fixes a Zip-Slip vulnerability.

This change does one of two things. This change either

1. Inserts a guard to protect against Zip Slip.
OR
2. 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())`.

For number 2, 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: High
CVSSS: 7.4
Detection: CodeQL (https://codeql.github.com/codeql-query-help/java/java-zipslip/) & OpenRewrite (https://public.moderne.io/recipes/org.openrewrite.java.security.ZipSlip)

Reported-by: Jonathan Leitschuh <[email protected]>
Signed-off-by: Jonathan Leitschuh <[email protected]>

Bug-tracker: JLLeitschuh/security-research#16


Co-authored-by: Moderne <[email protected]>
  • Loading branch information
JLLeitschuh and TeamModerne committed Oct 3, 2022
1 parent 704eae2 commit ccde8f0
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 4 deletions.
3 changes: 3 additions & 0 deletions carbon-p2-plugin/src/main/java/org/wso2/maven/p2/generate/utils/FileManagementUtil.java
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@ public static void unzip(File archiveFile,File destination) throws Exception{
int count;
byte data[] = new byte[BUFFER];
File file = new File(base,entry.getName());
if (!file.toPath().normalize().startsWith(base.toPath().normalize())) {
throw new IOException("Bad zip entry");
}
if (entry.getName().endsWith("/")){
file.mkdirs();
continue;
Expand Down
3 changes: 3 additions & 0 deletions maven-car-plugin/src/main/java/org/wso2/maven/car/artifact/utils/FileManagementUtil.java
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,9 @@ public static void unzip(File archiveFile,File destination) throws Exception{
int count;
byte data[] = new byte[BUFFER];
File file = new File(base,entry.getName());
if (!file.toPath().normalize().startsWith(base.toPath().normalize())) {
throw new IOException("Bad zip entry");
}
if (entry.getName().endsWith("/")){
file.mkdirs();
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,10 @@ public void extractFromStream(InputStream inputStream, String extractDir) throws
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
String entryName = entry.getName();
File f = new File(extractDir + File.separator + entryName);
File f = new File(extractDir, entryName);
if (!f.toPath().normalize().startsWith(extractDir)) {
throw new IOException("Bad zip entry");
}

if (entryName.endsWith("/") && !f.exists()) { // this is a
// directory
Expand All @@ -171,7 +174,7 @@ public void extractFromStream(InputStream inputStream, String extractDir) throws
String dirPath = "";
if (lastIndexOfSlash != -1) {
dirPath = entryName.substring(0, lastIndexOfSlash);
File dir = new File(extractDir + File.separator + dirPath);
File dir = new File(extractDir, dirPath);
if (!dir.exists()) {
dir.mkdirs();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,10 @@ public static void extractFromStream(InputStream inputStream, String extractDir)
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
String entryName = entry.getName();
File f = new File(extractDir + File.separator + entryName);
File f = new File(extractDir, entryName);
if (!f.toPath().normalize().startsWith(extractDir)) {
throw new IOException("Bad zip entry");
}

if (entryName.endsWith("/") && !f.exists()) { // this is a
// directory
Expand All @@ -674,7 +677,7 @@ public static void extractFromStream(InputStream inputStream, String extractDir)
String dirPath = "";
if (lastIndexOfSlash != -1) {
dirPath = entryName.substring(0, lastIndexOfSlash);
File dir = new File(extractDir + File.separator + dirPath);
File dir = new File(extractDir, dirPath);
if (!dir.exists()) {
dir.mkdirs();
}
Expand Down

0 comments on commit ccde8f0

Please sign in to comment.