Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Foorcee committed Nov 18, 2024
1 parent fbb01c4 commit 18486ad
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 7 deletions.
10 changes: 10 additions & 0 deletions src/Zip/ZipEntry.Extract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,16 @@ bool IsDoneWithOutputToBaseDir(string baseDir, out string outFileName)

// workitem 10639
outFileName = outFileName.Replace('/', Path.DirectorySeparatorChar);

// Resolve any directory traversal sequence and compare the result with the intended base directory
// where the file or folder will be created.
// https://gist.github.com/thomas-chauchefoin-bentley-systems/855218959116f870f08857cce2aec731
var canonicalOutPath = Path.GetFullPath(outFileName);
var canonicalBaseDir = Path.GetFullPath(baseDir);
if (!canonicalOutPath.StartsWith(canonicalBaseDir, StringComparison.OrdinalIgnoreCase))
{
throw new IOException(string.Format("Extracting {0} would write to {1}, outside of {2}; rejecting.", outFileName, canonicalOutPath, canonicalBaseDir));
}

// check if it is a directory
if (IsDirectory || FileName.EndsWith("/"))
Expand Down
52 changes: 45 additions & 7 deletions test/BasicTest.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,52 @@
using Xunit;
using Xunit.Abstractions;

namespace Ionic.Zip.Tests
namespace Ionic.Zip.Tests;

public class BasicTest
{
public class BasicTest
private readonly ITestOutputHelper _output;

public BasicTest(ITestOutputHelper output)
{
_output = output;
}

[Fact]
public void TestCreate()
{
var result = new ZipFile();
Assert.NotNull(result);
}

[Fact]
public void Extract_ZipWithAbsolutePathsOutside()
{
[Fact]
public void TestCreate()
Assert.Throws<IOException>(() => Extract_ZipFile("absolute-path-traversal.zip"));
Assert.False(File.Exists(@"C:\Windows\Temp\foo"));
}

private void Extract_ZipFile(string fileName)
{
var sourceDir = Directory.GetCurrentDirectory();
_output.WriteLine("Current Dir: {0}", sourceDir);

var fqFileName = Path.Combine(sourceDir, "zips", fileName);

_output.WriteLine("Reading zip file: '{0}'", fqFileName);
using var zip = ZipFile.Read(fqFileName);
const string extractDir = "extract";
foreach (ZipEntry e in zip)
{
var result = new ZipFile();
Assert.NotNull(result);
_output.WriteLine("{1,-22} {2,9} {3,5:F0}% {4,9} {5,3} {6:X8} {0}",
e.FileName,
e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
e.UncompressedSize,
e.CompressionRatio,
e.CompressedSize,
(e.UsesEncryption) ? "Y" : "N",
e.Crc);
e.Extract(extractDir);
}
}
}
}
6 changes: 6 additions & 0 deletions test/ProDotNetZipNetStandardTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@
<ProjectReference Include="..\src\ProDotNetZipNetStandard.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="zips\absolute-path-traversal.zip">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Binary file added test/zips/absolute-path-traversal.zip
Binary file not shown.

0 comments on commit 18486ad

Please sign in to comment.