Path Traversal in Aspnet
How Path Traversal Manifests in Aspnet
Path traversal vulnerabilities in Aspnet applications typically occur when user input is used to construct file paths without proper validation. In Aspnet, these vulnerabilities often manifest through several common patterns:
Physical File Access via MapPath
Many legacy Aspnet applications use Server.MapPath() to resolve virtual paths to physical paths. An attacker can manipulate path parameters to escape the intended directory:
protected void DownloadFile(string fileName)
{
string filePath = Server.MapPath("/Uploads/" + fileName);
// Vulnerable: ../ can escape the Uploads directory
File.WriteAllText(filePath, "..."));
}
Virtual Path Manipulation
Applications using VirtualPathUtility to resolve paths can be vulnerable when combined with user input:
protected string GetConfigPath(string configName)
{
string path = VirtualPathUtility.ToAbsolute("/Configs/" + configName);
// Attacker can use: ../../web.config
return File.ReadAllText(path);
}
ASP.NET Core Path Joining Issues
Even in modern Aspnet Core, path traversal can occur when using Path.Combine() incorrectly:
public IActionResult GetProfileImage(string userId, string fileName)
{
string userDir = Path.Combine("Profiles", userId);
string filePath = Path.Combine(userDir, fileName);
// If fileName contains ../, attacker can access other users' files
return PhysicalFile(filePath, "image/jpeg");
}
Configuration File Exposure
Attackers often target configuration files through path traversal:
protected string GetSetting(string configFile)
{
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs", configFile);
// If configFile = "../../web.config", sensitive data exposed
return File.ReadAllText(path);
}
Log File Manipulation
Path traversal in logging implementations can allow attackers to overwrite critical files:
public void WriteLog(string logName, string message)
{
string logPath = Path.Combine("Logs", logName + ".log");
// If logName contains ../, attacker can overwrite any file
File.AppendAllText(logPath, message);
}Aspnet-Specific Detection
Detecting path traversal vulnerabilities in Aspnet applications requires both static analysis and dynamic testing. Here's how to identify these issues:
Static Code Analysis
Review your codebase for these Aspnet-specific patterns:
grep -r "Server\.MapPath" --include="*.cs"
grep -r "VirtualPathUtility" --include="*.cs"
grep -r "Path\.Combine" --include="*.cs" | grep -v "Path\.GetFullPath"
Dynamic Testing with middleBrick
middleBrick's black-box scanning approach is particularly effective for Aspnet applications because it tests the actual runtime behavior without requiring source code access. The scanner automatically:
- Tests common traversal patterns like
../,..∕,..%2f, and Unicode variants - Attempts to access sensitive Aspnet files (web.config, global.asax, bin/ directories)
- Verifies if directory traversal succeeds in the actual deployed environment
- Checks for proper input validation and sanitization
middleBrick CLI Example
npm install -g middlebrick
middlebrick scan https://yourapi.com/api/download
The scan will test for path traversal across all endpoints, including those that accept file paths, document IDs, or other path-like parameters. Results include severity levels, specific payloads that triggered the vulnerability, and Aspnet-specific remediation guidance.
Manual Testing Techniques
Complement automated scanning with manual testing:
GET /api/files?path=../../web.config
GET /api/documents?fileId=../../../bin/myapp.dll
POST /api/upload?filename=../../web.config
Test both encoded and unencoded variants, and verify if the application canonicalizes paths correctly using Path.GetFullPath() or similar methods.
Aspnet-Specific Remediation
Remediating path traversal vulnerabilities in Aspnet requires a defense-in-depth approach. Here are Aspnet-specific solutions:
Input Validation and Sanitization
Always validate and sanitize user input before using it in file paths:
public IActionResult GetProfileImage(string userId, string fileName)
{
if (!IsValidFileName(fileName))
return BadRequest("Invalid file name");
string safeFileName = SanitizeFileName(fileName);
string userDir = Path.Combine("Profiles", userId);
string filePath = Path.Combine(userDir, safeFileName);
// Canonicalize and verify path is within allowed directory
string fullPath = Path.GetFullPath(filePath);
if (!fullPath.StartsWith(Path.GetFullPath("Profiles")))
return BadRequest("Invalid path");
return PhysicalFile(fullPath, "image/jpeg");
}
private bool IsValidFileName(string fileName)
{
// Only allow alphanumeric, hyphens, underscores, and periods
return Regex.IsMatch(fileName, @"^[a-zA-Z0-9_\-\.]+$");
}
private string SanitizeFileName(string fileName)
{
return Path.GetFileName(fileName); // Removes any directory components
}
Using Aspnet Core's File Providers
Aspnet Core provides safer abstractions for file access:
public class SafeFileProvider : IFileProvider
{
private readonly string _rootDirectory;
public SafeFileProvider(string rootDirectory)
{
_rootDirectory = Path.GetFullPath(rootDirectory);
}
public IFileInfo GetFileInfo(string subpath)
{
string fullPath = Path.GetFullPath(Path.Combine(_rootDirectory, subpath));
if (!fullPath.StartsWith(_rootDirectory))
return new NotFoundFileInfo(subpath);
return new PhysicalFileInfo(new FileInfo(fullPath));
}
}
ASP.NET Framework Solutions
For classic Aspnet Framework, use similar validation:
protected void DownloadFile(string fileName)
{
string safeFileName = Path.GetFileName(fileName);
string filePath = Server.MapPath("/Uploads/" + safeFileName);
// Verify the resolved path is within the intended directory
string uploadDir = Server.MapPath("/Uploads/");
string fullPath = Path.GetFullPath(filePath);
if (!fullPath.StartsWith(Path.GetFullPath(uploadDir)))
throw new SecurityException("Path traversal attempt detected");
Response.ContentType = "application/octet-stream";
Response.WriteFile(filePath);
}
Configuration-Based Path Restrictions
Implement configuration-based path restrictions:
public class PathTraversalMiddleware
{
private readonly RequestDelegate _next;
private readonly string _allowedRoot;
public PathTraversalMiddleware(RequestDelegate next, IConfiguration config)
{
_next = next;
_allowedRoot = Path.GetFullPath(config["AllowedFilePathRoot"]);
}
public async Task InvokeAsync(HttpContext context)
{
var originalPath = context.Request.Path.Value;
if (originalPath.Contains("..") || originalPath.Contains(":") || originalPath.Contains("|"))
{
context.Response.StatusCode = 400;
await context.Response.WriteAsync("Invalid path");
return;
}
await _next(context);
}
}
OWASP Compliance
These remediation techniques align with OWASP's recommendations for path traversal prevention and help achieve compliance with standards like PCI-DSS and SOC2. middleBrick's scanning results map directly to these security controls, providing documentation for compliance audits.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |