Zip Slip

Writes outside the extraction directory through unvalidated ZIP entry paths

Description

Using ZIP entry names as extraction paths without validation can allow entries containing ../ to write files outside the destination directory.

Potential impact

  • Arbitrary file writes, overwritten configuration, or file creation in a web root.

Remediation

Compute each entry's final canonical path and reject extraction if it escapes the destination directory. Create a new extraction directory beneath a service-owned location attackers cannot write to, and do not overwrite existing files.

Examples

Before

csharp
using System.IO;
using System.IO.Compression;

sealed class ZipExtractor
{
    public static void ExtractEntry(
        ZipArchiveEntry entry,
        string targetDirectory)
    {
        var path = Path.GetFullPath(Path.Combine(targetDirectory, entry.FullName));
        entry.ExtractToFile(path, overwrite: true);
    }
}

After

csharp
using System;
using System.IO;
using System.IO.Compression;

static string ExtractToNewDirectory(ZipArchive archive, string serviceOwnedRoot)
{
    // Other users or processes must not be able to write to serviceOwnedRoot.
    var targetRoot = Directory.CreateDirectory(
        Path.Combine(serviceOwnedRoot, Path.GetRandomFileName())).FullName;
    var targetPrefix = Path.GetFullPath(targetRoot) + Path.DirectorySeparatorChar;

    foreach (var entry in archive.Entries)
    {
        var path = Path.GetFullPath(Path.Combine(targetRoot, entry.FullName));
        if (!path.StartsWith(targetPrefix, StringComparison.Ordinal))
        {
            throw new InvalidDataException("Archive entry escapes the target directory");
        }

        if (string.IsNullOrEmpty(entry.Name))
        {
            Directory.CreateDirectory(path);
            continue;
        }

        Directory.CreateDirectory(Path.GetDirectoryName(path)!);
        entry.ExtractToFile(path, overwrite: false);
    }

    return targetRoot;
}

Explanation:

  • Before: Without validating the normalized destination, an entry containing ../ can write outside the target directory.
  • After: Each extraction uses a new directory in a service-only location. The Ordinal boundary check prevents path escape on case-sensitive filesystems as well, while overwrite: false preserves existing files.

References