Skip to content

Commit

Permalink
Merge pull request #374 from odinn1984/feat/fail_on_outside_target_files
Browse files Browse the repository at this point in the history
fix: prevent extracting archived files outside of target path
  • Loading branch information
adamhathcock committed May 2, 2018
2 parents 259acd0 + 80ceb1c commit 42b1205
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
21 changes: 19 additions & 2 deletions src/SharpCompress/Archives/IArchiveEntryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWrite
{
string destinationFileName;
string file = Path.GetFileName(entry.Key);
string fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory);

options = options ?? new ExtractionOptions()
{
Expand All @@ -58,19 +59,35 @@ public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWrite
if (options.ExtractFullPath)
{
string folder = Path.GetDirectoryName(entry.Key);
string destdir = Path.Combine(destinationDirectory, folder);
string destdir = Path.GetFullPath(
Path.Combine(fullDestinationDirectoryPath, folder)
);

if (!Directory.Exists(destdir))
{
if (!destdir.StartsWith(fullDestinationDirectoryPath))
{
throw new ExtractionException("Entry is trying to create a directory outside of the destination directory.");
}

Directory.CreateDirectory(destdir);
}
destinationFileName = Path.Combine(destdir, file);
}
else
{
destinationFileName = Path.Combine(destinationDirectory, file);
destinationFileName = Path.Combine(fullDestinationDirectoryPath, file);
}

if (!entry.IsDirectory)
{
destinationFileName = Path.GetFullPath(destinationFileName);

if (!destinationFileName.StartsWith(fullDestinationDirectoryPath))
{
throw new ExtractionException("Entry is trying to write a file outside of the destination directory.");
}

entry.WriteToFile(destinationFileName, options);
}
}
Expand Down
27 changes: 27 additions & 0 deletions tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,34 @@ public void Zip_Deflate_PKWear_Multipy_Entry_Access()
}
}
}
}

[Fact]
public void Zip_Evil_Throws_Exception()
{
Exception expectedExcetpion = null;
string zipFile = Path.Combine(TEST_ARCHIVES_PATH, "Zip.Evil.zip");

try
{
using (var archive = ZipArchive.Open(zipFile))
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
{
entry.WriteToDirectory(SCRATCH_FILES_PATH, new ExtractionOptions()
{
ExtractFullPath = true,
Overwrite = true
});
}
}
}
catch (Exception ex)
{
expectedExcetpion = ex;
}

Assert.NotEqual(expectedExcetpion, null);
}

class NonSeekableMemoryStream : MemoryStream
Expand Down
Binary file added tests/TestArchives/Archives/Zip.Evil.zip
Binary file not shown.

0 comments on commit 42b1205

Please sign in to comment.