Skip to content

Commit

Permalink
PR #519: Restrict path traversal on TarArchive extraction
Browse files Browse the repository at this point in the history
  • Loading branch information
piksel authored Oct 7, 2020
1 parent 61d3a21 commit 0cbdef2
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.IO;
using System.Numerics;
using System.Text;
using ICSharpCode.SharpZipLib.Core;

namespace ICSharpCode.SharpZipLib.Tar
{
Expand Down Expand Up @@ -594,13 +596,25 @@ public void ListContents()
/// <param name="destinationDirectory">
/// The destination directory into which to extract.
/// </param>
public void ExtractContents(string destinationDirectory)
public void ExtractContents(string destinationDirectory)
=> ExtractContents(destinationDirectory, false);

/// <summary>
/// Perform the "extract" command and extract the contents of the archive.
/// </summary>
/// <param name="destinationDirectory">
/// The destination directory into which to extract.
/// </param>
/// <param name="allowParentTraversal">Allow parent directory traversal in file paths (e.g. ../file)</param>
public void ExtractContents(string destinationDirectory, bool allowParentTraversal)
{
if (isDisposed)
{
throw new ObjectDisposedException("TarArchive");
}

var fullDistDir = Path.GetFullPath(destinationDirectory);

while (true)
{
TarEntry entry = tarIn.GetNextEntry();
Expand All @@ -613,7 +627,7 @@ public void ExtractContents(string destinationDirectory)
if (entry.TarHeader.TypeFlag == TarHeader.LF_LINK || entry.TarHeader.TypeFlag == TarHeader.LF_SYMLINK)
continue;

ExtractEntry(destinationDirectory, entry);
ExtractEntry(fullDistDir, entry, allowParentTraversal);
}
}

Expand All @@ -627,7 +641,8 @@ public void ExtractContents(string destinationDirectory)
/// <param name="entry">
/// The TarEntry returned by tarIn.GetNextEntry().
/// </param>
private void ExtractEntry(string destDir, TarEntry entry)
/// <param name="allowParentTraversal">Allow parent directory traversal in file paths (e.g. ../file)</param>
private void ExtractEntry(string destDir, TarEntry entry, bool allowParentTraversal)
{
OnProgressMessageEvent(entry, null);

Expand All @@ -644,6 +659,11 @@ private void ExtractEntry(string destDir, TarEntry entry)

string destFile = Path.Combine(destDir, name);

if (!allowParentTraversal && !Path.GetFullPath(destFile).StartsWith(destDir, StringComparison.InvariantCultureIgnoreCase))
{
throw new InvalidNameException("Parent traversal in paths is not allowed");
}

if (entry.IsDirectory)
{
EnsureDirectoryExists(destFile);
Expand Down

0 comments on commit 0cbdef2

Please sign in to comment.