From f2d52d06dae53a062d24605902796913da9da2d7 Mon Sep 17 00:00:00 2001 From: alerickson <25858831+alerickson@users.noreply.github.com> Date: Mon, 23 Oct 2023 22:26:14 -0700 Subject: [PATCH] Sanitize archive entry file name --- src/code/InstallHelper.cs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/code/InstallHelper.cs b/src/code/InstallHelper.cs index 736267417..bccf8d11c 100644 --- a/src/code/InstallHelper.cs +++ b/src/code/InstallHelper.cs @@ -1175,19 +1175,25 @@ private bool TryExtractToDirectory(string zipPath, string extractPath, out Error { foreach (ZipArchiveEntry entry in archive.Entries) { - // Sanitize the filename to remove any potentially harmful characters - string sanitizedFileName = Path.GetFileName(entry.FullName); + // Sanitize the filename to remove any potentially harmful characters (ie '..'). + if (entry.Name.Equals("..")) + { + error = new ErrorRecord( + new Exception($"Error occured while extracting .nupkg. File contains a potentially malicious file path."), + "FileNameErrorWhenExtractingNupkg", + ErrorCategory.InvalidArgument, + _cmdletPassedIn); - // Create a new entry in the archive - ZipArchiveEntry sanitizedEntry = archive.CreateEntry(sanitizedFileName); + return false; + } // If a file has one or more parent directories. - if (sanitizedEntry.FullName.Contains(Path.DirectorySeparatorChar) || sanitizedEntry.FullName.Contains(Path.AltDirectorySeparatorChar)) + if (entry.FullName.Contains(Path.DirectorySeparatorChar) || entry.FullName.Contains(Path.AltDirectorySeparatorChar)) { // Create the parent directories if they do not already exist var lastPathSeparatorIdx = entry.FullName.Contains(Path.DirectorySeparatorChar) ? - sanitizedEntry.FullName.LastIndexOf(Path.DirectorySeparatorChar) : sanitizedEntry.FullName.LastIndexOf(Path.AltDirectorySeparatorChar); - var parentDirs = sanitizedEntry.FullName.Substring(0, lastPathSeparatorIdx); + entry.FullName.LastIndexOf(Path.DirectorySeparatorChar) : entry.FullName.LastIndexOf(Path.AltDirectorySeparatorChar); + var parentDirs = entry.FullName.Substring(0, lastPathSeparatorIdx); var destinationDirectory = Path.Combine(extractPath, parentDirs); if (!Directory.Exists(destinationDirectory)) { @@ -1196,9 +1202,9 @@ private bool TryExtractToDirectory(string zipPath, string extractPath, out Error } // Gets the full path to ensure that relative segments are removed. - string destinationPath = Path.GetFullPath(Path.Combine(extractPath, sanitizedEntry.FullName)); + string destinationPath = Path.GetFullPath(Path.Combine(extractPath, entry.FullName)); - sanitizedEntry.ExtractToFile(destinationPath, overwrite:true); + entry.ExtractToFile(destinationPath, overwrite:true); } } }