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.