diff --git a/build.gradle b/build.gradle index 0a060cd..1ff40ff 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { sourceCompatibility=1.7 targetCompatibility=1.7 -version = '0.7.0' +version = '0.7.1' repositories { mavenCentral() diff --git a/src/main/groovy/com/bloidonia/groovy/extensions/FileExtensionMethods.groovy b/src/main/groovy/com/bloidonia/groovy/extensions/FileExtensionMethods.groovy index c01bd89..687189c 100644 --- a/src/main/groovy/com/bloidonia/groovy/extensions/FileExtensionMethods.groovy +++ b/src/main/groovy/com/bloidonia/groovy/extensions/FileExtensionMethods.groovy @@ -142,6 +142,7 @@ class FileExtensionMethods { while(entry = zipInput.nextEntry) { if (!entry.isDirectory()) { final file = new File(destination, entry.name) + checkForZipSlip(destination, file) if( filter == null || filter( file ) ) { file.parentFile?.mkdirs() @@ -155,6 +156,7 @@ class FileExtensionMethods { } else { final dir = new File(destination, entry.name) + checkForZipSlip(destination, dir) if( filter == null || filter( dir ) ) { dir.mkdirs() @@ -167,6 +169,12 @@ class FileExtensionMethods { unzippedFiles } + private static void checkForZipSlip(File destination, File dir) { + if (!dir.canonicalPath.startsWith(destination.canonicalPath)) { + throw new IllegalArgumentException("Attempt to unzip ($dir.canonicalPath) outside of destination ($destination.canonicalPath) rejected") + } + } + private static void checkUnzipFileType(File self) { if (!self.isFile()) throw new IllegalArgumentException("File#unzip() has to be called on a *.zip file.") diff --git a/src/test/groovy/tests/FileTests.groovy b/src/test/groovy/tests/FileTests.groovy new file mode 100644 index 0000000..b5630af --- /dev/null +++ b/src/test/groovy/tests/FileTests.groovy @@ -0,0 +1,22 @@ +package tests + +import spock.lang.Specification + +import java.nio.file.Files + +class FileTests extends Specification { + + def "check for ZipSlip"() { + given: + def dest = Files.createTempDirectory("zipslip") + def zip = new File(FileTests.class.getResource("/zip-slip.zip").toURI()) + + when: + zip.unzip(dest.toFile()) + + then: + def ex = thrown(IllegalArgumentException) + ex.printStackTrace() + } + +} diff --git a/src/test/resources/zip-slip.zip b/src/test/resources/zip-slip.zip new file mode 100644 index 0000000..38b3f49 Binary files /dev/null and b/src/test/resources/zip-slip.zip differ