ASP.NET Core  

Preventing Path Traversal and Directory Browsing Attacks in ASP.NET Core

Web applications frequently need to handle file uploads and downloads and serve static resources. If not properly secured, they become vulnerable to path traversal and directory browsing attacks, which attackers can exploit to gain unauthorized access to sensitive files.

In this article, we’ll understand these attacks and see practical ways to mitigate them in ASP.NET Core.

What Are Path Traversal and Directory Browsing?

  • Path Traversal Attack
    Occurs when an attacker manipulates file paths (e.g., using ../ or %2e%2e/) to access files outside the intended directory.
    Example

    GET /download?file=../../web.config
    

    This could expose configuration files, credentials, or source code.

  • Directory Browsing Attack
    It happens when directory listing is enabled, allowing users to see all files inside a folder.
    Example

    http://example.com/uploads/
    

    If browsing is enabled, attackers can enumerate sensitive files.

Mitigation Strategies in ASP.NET Core

1. Disable Directory Browsing

By default, directory browsing should be disabled in production.
In Program.cs (or Startup.cs in older versions):

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Do NOT enable directory browsing
// app.UseDirectoryBrowser(); //  Avoid this

app.UseStaticFiles(); // Safe for serving static content

app.Run();

If you must allow browsing in a specific directory, configure it explicitly and restrict access using Authorization Policies.

2. Sanitize File Paths

When handling file upload or download requests, never trust user input for file paths. Use safe methods like Path.GetFileName or Path.Combine.

[HttpGet("download")]
public IActionResult DownloadFile(string fileName)
{
    // Sanitize the input
    var safeFileName = Path.GetFileName(fileName); // Removes directory traversal chars
    var uploads = Path.Combine(Directory.GetCurrentDirectory(), "uploads");
    var filePath = Path.Combine(uploads, safeFileName);

    if (!System.IO.File.Exists(filePath))
        return NotFound();

    var contentType = "application/octet-stream";
    return PhysicalFile(filePath, contentType, safeFileName);
}

Path.GetFileName ensures only the file name is used, preventing ../ tricks.

3. Restrict File Upload Paths

When saving uploaded files, lock them into a safe directory:

[HttpPost("upload")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
    if (file == null || file.Length == 0)
        return BadRequest("Invalid file.");

    var uploads = Path.Combine(Directory.GetCurrentDirectory(), "uploads");

    // Ensure directory exists
    if (!Directory.Exists(uploads))
        Directory.CreateDirectory(uploads);

    var safeFileName = Path.GetFileName(file.FileName);
    var filePath = Path.Combine(uploads, safeFileName);

    using (var stream = new FileStream(filePath, FileMode.Create))
    {
        await file.CopyToAsync(stream);
    }

    return Ok("File uploaded successfully.");
}

4. Validate File Types and Extensions

Attackers may upload scripts (.aspx, .php, .exe).
Block dangerous file extensions:

string[] allowedExtensions = { ".jpg", ".png", ".pdf" };
string ext = Path.GetExtension(file.FileName).ToLowerInvariant();

if (!allowedExtensions.Contains(ext))
{
    return BadRequest("File type not allowed.");
}

5. Use Static File Middleware Safely

If serving files:

app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        // Prevent caching of sensitive files
        ctx.Context.Response.Headers.Append("Cache-Control", "no-store");
    }
});

6. Harden web.config and Sensitive Files

Although ASP.NET Core doesn’t use web.config for hosting settings on Kestrel, IIS environments still do. Ensure sensitive files are not accessible via HTTP.

Add in web.config (for IIS hosting):

<configuration>
  <system.webServer>
    <security>
      <requestFiltering>
        <hiddenSegments>
          <add segment="bin"/>
          <add segment="App_Data"/>
          <add segment="App_Code"/>
        </hiddenSegments>
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

7. Apply Least Privilege on File System

  • Run the application with a dedicated service account.

  • Restrict read/write permissions only to the intended upload directory.

  • Do not give write access to application binaries.

Best Practices Checklist

  • Disable directory browsing

  • Always sanitize file paths (Path.GetFileName)

  • Restrict file upload directory

  • Validate file extensions & MIME types

  • Disable serving of executable/script files

  • Apply least privilege to folders

  • Monitor logs for suspicious file access

Conclusion

Path traversal and directory browsing are serious threats that can compromise your application and server. By disabling directory browsing, sanitizing paths, validating uploads, and enforcing least privilege, you can secure your ASP.NET Core applications against these common attacks.