Skip to content

Commit 58bc24e

Browse files
OdinnOdinn
Odinn
authored and
Odinn
committed
fix: fail when trying to extract outside of dest dir
A well crafted zip file may cause the code to extract outside of the destination dir. This PR fails when that happens so that no unexpected behaviour happens.
1 parent 97c0d97 commit 58bc24e

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java

+9
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,15 @@ protected void extractFile( final File srcF, final File dir, final InputStream c
308308
// Hmm. Symlinks re-evaluate back to the original file here. Unsure if this is a good thing...
309309
final File f = FileUtils.resolveFile( dir, entryName );
310310

311+
// Make sure that the resolved path of the extracted file doesn't escape the destination directory
312+
String canonicalDirPath = dir.getCanonicalPath();
313+
String canonicalDestPath = f.getCanonicalPath();
314+
315+
if ( !canonicalDestPath.startsWith( canonicalDirPath ) )
316+
{
317+
throw new ArchiverException( "Entry is outside of the target directory (" + entryName + ")" );
318+
}
319+
311320
try
312321
{
313322
if ( !isOverwrite() && f.exists() && ( f.lastModified() >= entryDate.getTime() ) )

src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java

+24
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,30 @@ public void testSelectors()
190190
} );
191191
}
192192

193+
public void testExtractingZipWithEntryOutsideDestDirThrowsException()
194+
throws Exception
195+
{
196+
Exception ex = null;
197+
String s = "target/zip-unarchiver-slip-tests";
198+
File testZip = new File( getBasedir(), "src/test/zips/zip-slip.zip" );
199+
File outputDirectory = new File( getBasedir(), s );
200+
201+
FileUtils.deleteDirectory( outputDirectory );
202+
203+
try
204+
{
205+
ZipUnArchiver zu = getZipUnArchiver( testZip );
206+
zu.extract( "", outputDirectory );
207+
}
208+
catch ( Exception e )
209+
{
210+
ex = e;
211+
}
212+
213+
assertNotNull( ex );
214+
assertTrue( ex.getMessage().startsWith( "Entry is outside of the target directory" ) );
215+
}
216+
193217
private ZipArchiver getZipArchiver()
194218
{
195219
try

src/test/zips/zip-slip.zip

545 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)