From 08438a2c47112f2fce1e512f6c843c908abed4c7 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Fri, 4 May 2018 09:15:04 +0200 Subject: SONAR-10661 fix vulnerability in ZipUtils#unzip() --- .../java/org/sonar/api/utils/ZipUtilsTest.java | 41 +++++++++++++++++---- .../org/sonar/api/utils/ZipUtilsTest/zip-slip.zip | Bin 0 -> 545 bytes 2 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 sonar-plugin-api/src/test/resources/org/sonar/api/utils/ZipUtilsTest/zip-slip.zip (limited to 'sonar-plugin-api/src/test') diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/ZipUtilsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/ZipUtilsTest.java index d721585d477..76e86dc99fd 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/ZipUtilsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/ZipUtilsTest.java @@ -20,19 +20,20 @@ package org.sonar.api.utils; import com.google.common.collect.Iterators; -import java.net.URL; -import org.apache.commons.io.FileUtils; -import org.assertj.core.util.Files; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; - import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URL; import java.util.Iterator; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import org.apache.commons.io.FileUtils; +import org.assertj.core.util.Files; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; import static org.assertj.core.api.Assertions.assertThat; @@ -40,6 +41,8 @@ public class ZipUtilsTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); @Test public void zip_directory() throws IOException { @@ -106,6 +109,30 @@ public class ZipUtilsTest { assertThat(toDir.listFiles()).containsOnly(new File(toDir, "foo.txt")); } + @Test + public void fail_if_unzipping_file_outside_target_directory() throws Exception { + File zip = new File(getClass().getResource("ZipUtilsTest/zip-slip.zip").toURI()); + File toDir = temp.newFolder(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Unzipping an entry outside the target directory is not allowed: ../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../tmp/evil.txt"); + + ZipUtils.unzip(zip, toDir); + } + + @Test + public void fail_if_unzipping_stream_outside_target_directory() throws Exception { + File zip = new File(getClass().getResource("ZipUtilsTest/zip-slip.zip").toURI()); + File toDir = temp.newFolder(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Unzipping an entry outside the target directory is not allowed: ../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../tmp/evil.txt"); + + try (InputStream input = new FileInputStream(zip)) { + ZipUtils.unzip(input, toDir); + } + } + private URL urlToZip() { return getClass().getResource("/org/sonar/api/utils/ZipUtilsTest/shouldUnzipFile.zip"); } diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/utils/ZipUtilsTest/zip-slip.zip b/sonar-plugin-api/src/test/resources/org/sonar/api/utils/ZipUtilsTest/zip-slip.zip new file mode 100644 index 00000000000..38b3f499de0 Binary files /dev/null and b/sonar-plugin-api/src/test/resources/org/sonar/api/utils/ZipUtilsTest/zip-slip.zip differ -- cgit v1.2.3