diff --git a/main/src/com/google/refine/io/FileProjectManager.java b/main/src/com/google/refine/io/FileProjectManager.java index ff792b48dbd7..7bf6a3941465 100644 --- a/main/src/com/google/refine/io/FileProjectManager.java +++ b/main/src/com/google/refine/io/FileProjectManager.java @@ -169,6 +169,9 @@ protected void untar(File destDir, InputStream inputStream) throws IOException { while ((tarEntry = tin.getNextTarEntry()) != null) { File destEntry = new File(destDir, tarEntry.getName()); + if (!destEntry.toPath().normalize().startsWith(destDir.toPath().normalize())) { + throw new IllegalArgumentException("Zip archives with files escaping their root directory are not allowed."); + } File parent = destEntry.getParentFile(); if (!parent.exists()) { diff --git a/main/tests/data/zip-slip.tar b/main/tests/data/zip-slip.tar new file mode 100644 index 000000000000..201e2803b357 Binary files /dev/null and b/main/tests/data/zip-slip.tar differ diff --git a/main/tests/server/src/com/google/refine/io/FileProjectManagerTests.java b/main/tests/server/src/com/google/refine/io/FileProjectManagerTests.java index 34bf6873e07d..5d755e7c2d75 100644 --- a/main/tests/server/src/com/google/refine/io/FileProjectManagerTests.java +++ b/main/tests/server/src/com/google/refine/io/FileProjectManagerTests.java @@ -30,6 +30,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertThrows; import java.io.File; import java.io.FileInputStream; @@ -116,4 +117,19 @@ public void deleteProjectAndSaveWorkspace() throws IOException { JsonObject json = JSON.parse(inputStream); assertTrue(json.get("projectIDs").getAsArray().isEmpty()); } + + @Test + public void testUntarZipSlip() throws IOException { + FileProjectManager manager = new FileProjectManagerStub(workspaceDir); + + File tempDir = TestUtils.createTempDirectory("openrefine-project-import-zip-slip-test"); + try { + File subDir = new File(tempDir, "dest"); + InputStream stream = FileProjectManagerTests.class.getClassLoader().getResourceAsStream("zip-slip.tar"); + + assertThrows(IllegalArgumentException.class, () -> manager.untar(subDir, stream)); + } finally { + tempDir.delete(); + } + } }