From 49b446e173911d99b203b6ef70952f8b74a2f24c Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 13 Jan 2025 08:28:51 +0100 Subject: [PATCH] [msbuild] Validate that we don't write outside the target directory when decompressing zip files. Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2334855. --- msbuild/Xamarin.MacDev.Tasks/Decompress.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/msbuild/Xamarin.MacDev.Tasks/Decompress.cs b/msbuild/Xamarin.MacDev.Tasks/Decompress.cs index 4f2f8d5c0636..17fb3ff4b6d4 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Decompress.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Decompress.cs @@ -171,6 +171,7 @@ static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string resource = resource.TrimEnd ('/', '\\'); resource = resource.Replace ('\\', zipDirectorySeparator); var resourceAsDir = resource + zipDirectorySeparator; + decompressionDir = Path.GetFullPath (decompressionDir); using var archive = ZipFile.OpenRead (zip); foreach (var entry in archive.Entries) { @@ -204,6 +205,16 @@ static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string var isDir = entryPath [entryPath.Length - 1] == zipDirectorySeparator; var targetPath = Path.Combine (decompressionDir, entryPath.Replace (zipDirectorySeparator, Path.DirectorySeparatorChar)); + + // canonicalize the path + targetPath = Path.GetFullPath (targetPath); + + // validate that the unzipped file is inside the target directory + if (!targetPath.StartsWith (decompressionDir + Path.DirectorySeparatorChar)) { + log.LogMessage (MessageImportance.Low, "Did not extract {0} because it would write outside the target directory.", entryPath); + continue; + } + if (isDir) { Directory.CreateDirectory (targetPath); } else {