From c9ef603d8719566cfa52e52755451f8786190743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sat, 3 Oct 2020 20:27:42 +0200 Subject: [PATCH] Restrict path traversal on TarArchive extraction --- src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs b/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs index 562480a3c..d5849e1d5 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs @@ -1,6 +1,8 @@ using System; using System.IO; +using System.Numerics; using System.Text; +using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.Tar { @@ -594,7 +596,17 @@ public void ListContents() /// /// The destination directory into which to extract. /// - public void ExtractContents(string destinationDirectory) + public void ExtractContents(string destinationDirectory) + => ExtractContents(destinationDirectory, false); + + /// + /// Perform the "extract" command and extract the contents of the archive. + /// + /// + /// The destination directory into which to extract. + /// + /// Allow parent directory traversal in file paths (e.g. ../file) + public void ExtractContents(string destinationDirectory, bool allowParentTraversal) { if (isDisposed) { @@ -613,7 +625,7 @@ public void ExtractContents(string destinationDirectory) if (entry.TarHeader.TypeFlag == TarHeader.LF_LINK || entry.TarHeader.TypeFlag == TarHeader.LF_SYMLINK) continue; - ExtractEntry(destinationDirectory, entry); + ExtractEntry(destinationDirectory, entry, allowParentTraversal); } } @@ -627,7 +639,8 @@ public void ExtractContents(string destinationDirectory) /// /// The TarEntry returned by tarIn.GetNextEntry(). /// - private void ExtractEntry(string destDir, TarEntry entry) + /// Allow parent directory traversal in file paths (e.g. ../file) + private void ExtractEntry(string destDir, TarEntry entry, bool allowParentTraversal) { OnProgressMessageEvent(entry, null); @@ -644,6 +657,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);