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