diff --git a/pom.xml b/pom.xml index aa08b2202..749d76c05 100644 --- a/pom.xml +++ b/pom.xml @@ -10,14 +10,14 @@ plexus-archiver - 3.4 + 3.4.2-SNAPSHOT Plexus Archiver Component scm:git:git@github.com:codehaus-plexus/plexus-archiver.git scm:git:git@github.com:codehaus-plexus/plexus-archiver.git http://github.com/codehaus-plexus/plexus-archiver - plexus-archiver-3.4 + master jira diff --git a/src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java b/src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java index f9035c8cb..cd1625ec0 100644 --- a/src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java +++ b/src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java @@ -308,6 +308,15 @@ protected void extractFile( final File srcF, final File dir, final InputStream c // Hmm. Symlinks re-evaluate back to the original file here. Unsure if this is a good thing... final File f = FileUtils.resolveFile( dir, entryName ); + // Make sure that the resolved path of the extracted file doesn't escape the destination directory + String canonicalDirPath = dir.getCanonicalPath(); + String canonicalDestPath = f.getCanonicalPath(); + + if ( !canonicalDestPath.startsWith( canonicalDirPath ) ) + { + throw new ArchiverException( "Entry is outside of the target directory (" + entryName + ")" ); + } + try { if ( !isOverwrite() && f.exists() && ( f.lastModified() >= entryDate.getTime() ) ) diff --git a/src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java b/src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java index 1f72a6156..ea46a5aae 100644 --- a/src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java +++ b/src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java @@ -190,6 +190,30 @@ public void testSelectors() } ); } + public void testExtractingZipWithEntryOutsideDestDirThrowsException() + throws Exception + { + Exception ex = null; + String s = "target/zip-unarchiver-slip-tests"; + File testZip = new File( getBasedir(), "src/test/zips/zip-slip.zip" ); + File outputDirectory = new File( getBasedir(), s ); + + FileUtils.deleteDirectory( outputDirectory ); + + try + { + ZipUnArchiver zu = getZipUnArchiver( testZip ); + zu.extract( "", outputDirectory ); + } + catch ( Exception e ) + { + ex = e; + } + + assertNotNull( ex ); + assertTrue( ex.getMessage().startsWith( "Entry is outside of the target directory" ) ); + } + private ZipArchiver getZipArchiver() { try diff --git a/src/test/zips/zip-slip.zip b/src/test/zips/zip-slip.zip new file mode 100644 index 000000000..38b3f499d Binary files /dev/null and b/src/test/zips/zip-slip.zip differ