The analyzer has detected a file extraction operation using an unsecure path that includes a file name. If the file name contains "dot-dot-slash" sequences, this operation will result in a Zip Slip vulnerability in the application.
Zip Slip occurs when an application receives an archive with malicious files. These files contain "dot-dot-slash" sequences in the name ("../../evil.csx"). If such an archive is extracted, an attacker can overwrite any files that can be accessed by the application.
Most archive creation tools and operation systems don't allow users to create files with '../../evil.csx' names. However, there are tools that allow attackers to create files with such names. This makes the Zip Slip attack possible.
Consider an example of vulnerable code:
public void ExtractArchive(ZipArchive archive, string destinationDirectory)
{
var entries = archive.Entries;
foreach (var entry in entries)
{
var extractPath = Path.Combine(destinationDirectory, entry.FullName);
entry.ExtractToFile(extractPath, true);
}
}
Inside the loop, the files are extracted from the archive to the directory located in the 'destinationDirectory' path. With the help of the 'Path.Combine' method, an extract path is created for each file. Then, the result is written to the 'extractPath' variable. Next, 'extractPath' is used as an argument of the 'entry.ExtractToFile' method that extracts the file into the target path.
Suppose that the archive should be extracted to the 'C:\ApplicationFiles\UserFiles' directory. However, if the 'entry.FullName' property returns the '\..\config.ini' string, the file will get into the root directory of the application — 'C:\ApplicationFiles'. If the name of the extracted file and, for example, the name of the application configuration file match, the latter will be overwritten.
We can secure the code in the previous example as follows:
public void ExtractArchive(ZipArchive archive, string destinationDirectory)
{
var destinationDirectoryFullPath = Path.GetFullPath(destinationDirectory);
foreach (var entry in archive.Entries)
{
var extractPath = Path.Combine(destinationDirectory, entry.FullName);
var extractFullPath = Path.GetFullPath(extractPath);
if (!extractFullPath.StartsWith(destinationDirectoryFullPath))
{
throw new IOException("Zip Slip vulnerability");
}
entry.ExtractToFile(extractFullPath);
}
}
The 'Path.GetFullPath' method processes the 'extractPath' path — the result is written to the 'extractFullPath' variable. During this operation, the path containing "dot-dot-slash" sequences will be replaced with a similar one that does not include them.
Then, with the help of the 'extractFullPath.StartsWith' method, we check whether the directory for extracting the file has not changed as a result of the previous operation. If the directory has changed, an exception is thrown.
This diagnostic is classified as: