HIGH zip slipaspnetmutual tls

Zip Slip in Aspnet with Mutual Tls

Zip Slip in Aspnet with Mutual Tls — how this specific combination creates or exposes the vulnerability

Zip Slip is a path traversal vulnerability that occurs when an archive (ZIP, TAR, JAR, etc.) contains entries that resolve outside the intended extraction directory. In an ASP.NET application, this typically manifests during file uploads or plugin loading where a developer extracts an archive without validating or sanitizing member paths. The presence of Mutual TLS (mTLS) changes the threat model and observability surface but does not prevent the exploit itself; instead, it can obscure the client identity that might otherwise be used for additional authorization checks.

Mutual TLS ensures that both client and server present valid certificates, which is excellent for authentication and establishing trust. However, mTLS does not enforce authorization on file operations. An authenticated client with a valid certificate might still send a crafted archive containing paths like ../../../etc/passwd or ../../bin/evil.dll. If the server-side extraction code trusts the authenticated identity and skips path normalization, the archive can write files outside the target directory. In ASP.NET, this commonly occurs in controller actions that accept uploaded files or configuration packages, especially when using libraries like System.IO.Compression without strict path validation.

The combination can expose the vulnerability in two ways. First, because mTLS strongly authenticates the client, developers may mistakenly assume that the authenticated principal implies safe behavior and skip rigorous input validation. Second, logging and monitoring in mTLS environments may focus on certificate metadata rather than request payloads, making it harder to detect malicious archive contents during testing. Attackers can leverage this gap by using valid client certificates to bypass IP-based or network-level restrictions, then deliver malicious archives through legitimate mTLS channels.

Consider an ASP.NET Core endpoint that accepts a ZIP file over mTLS and extracts it:

using System.IO.Compression;
[ApiController]
[Route("api/[controller]")]
public class UploadController : ControllerBase
{
    [HttpPost("extract")]
    public IActionResult Extract([FromForm] IFormFile archive)
    {
        if (archive == null || archive.Length == 0)
            return BadRequest("No file uploaded.");
        using var stream = archive.OpenReadStream();
        using var archiveZip = new ZipArchive(stream);
        foreach (var entry in archiveZip.Entries)
        {
            entry.ExtractToFile(Path.Combine("C:/app/uploads", entry.FullName));
        }
        return Ok();
    }
}

In this example, entry.FullName is used directly without normalization or directory traversal checks. Even with mTLS ensuring the request originates from a trusted client, this code is vulnerable to Zip Slip because malicious paths can traverse outside C:/app/uploads. The fix requires validating each entry path to ensure it remains within the intended directory, regardless of mTLS status.

OWASP API Top 10 categories relevant here include Broken Object Level Authorization (though mTLS handles authentication, authorization on file paths is separate) and Path Traversal. While this is not an LLM/AI security issue, it highlights that strong transport-layer identity does not replace secure coding practices around file handling.

Mutual Tls-Specific Remediation in Aspnet — concrete code fixes

Remediation focuses on strict path validation and avoiding reliance on mTLS for file operation safety. In ASP.NET, you should normalize and constrain extracted paths independently of the transport identity. Use Path.GetFullPath combined with a base directory check to ensure no entry escapes the intended folder.

Here is a secure extraction pattern for ASP.NET Core that works alongside mTLS:

using System.IO.Compression;
using System.Runtime.InteropServices;
public static class ZipHelper
{
    public static void ExtractToDirectory(string zipPath, string outputDirectory)
    {
        Directory.CreateDirectory(outputDirectory);
        using var fs = File.OpenRead(zipPath);
        using var archive = new ZipArchive(fs);
        foreach (var entry in archive.Entries)
        {
            var destinationPath = Path.GetFullPath(Path.Combine(outputDirectory, entry.FullName));
            if (!destinationPath.StartsWith(Path.GetFullPath(outputDirectory), StringComparison.Ordinal))
                throw new InvalidOperationException("Entry is outside the target directory: " + entry.FullName);
            if (entry.FullName.EndsWith("/"))
            {
                Directory.CreateDirectory(destinationPath);
            }
            else
            {
                entry.ExtractToFile(destinationPath, overwrite: true);
            }
        }
    }
}

In an ASP.NET Core controller using mTLS, you would call this helper instead of extracting directly:

using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class UploadController : ControllerBase
{
    [HttpPost("extract")]
    public IActionResult Extract([FromForm] IFormFile archive)
    {
        if (archive == null || archive.Length == 0)
            return BadRequest("No file uploaded.");
        var uploadsDir = Path.Combine(Directory.GetCurrentDirectory(), "uploads");
        using var tempPath = Path.GetTempFileName();
        using (var stream = new FileStream(tempPath, FileMode.Create))
        {
            archive.CopyTo(stream);
        }
        try
        {
            ZipHelper.ExtractToDirectory(tempPath, uploadsDir);
        }
        finally
        {
            if (System.IO.File.Exists(tempPath))
                System.IO.File.Delete(tempPath);
        }
        return Ok();
    }
}

For mutual TLS scenarios, ensure your ASP.NET Core configuration enforces client certificates but does not skip validation on file paths. In Program.cs, you can require client certificates:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(httpsOptions =>
    {
        httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
    });
});
var app = builder.Build();
app.UseHttpsRedirection();
app.MapControllers();
app.Run();

Combine this with the extraction logic above to ensure that even authenticated clients cannot exploit Zip Slip. Note that mTLS certificates help identify the client but should not be used as the sole mechanism for authorizing file operations.

Key takeaways: Always validate and sanitize archive entries, use full path resolution, and enforce directory boundaries explicitly. mTLS improves authentication but does not replace secure handling of user-supplied archive contents.

Frequently Asked Questions

Does enabling Mutual TLS automatically protect against Zip Slip in ASP.NET?
No. Mutual TLS authenticates clients but does not validate file paths. You must still sanitize and constrain archive entries to prevent traversal.
What additional checks should be added when accepting ZIP files over mTLS in ASP.NET Core?
Validate each entry’s full resolved path against a canonical output directory, reject entries with absolute paths or parent directory sequences, and avoid using entry.FullName directly without normalization.