Path Traversal
Path Traversal is a critical web application vulnerability that allows attackers to access files and directories stored outside the web root folder. By manipulating file path references, attackers can read sensitive system files, source code, and configuration data they should never be able to access.
What Is Path Traversal?
Path Traversal, also known as directory traversal or dot-dot-slash attack, is a security vulnerability that enables attackers to read arbitrary files on the server running an application. This occurs when an application uses user-supplied input to construct file paths without proper validation or sanitization. The vulnerability gets its name from the use of "../" sequences (dot-dot-slash), which navigate up the directory tree in most operating systems.
The attack works by exploiting insufficient security validation of user-supplied file names. When an application concatenates user input directly into file system operations, an attacker can inject path traversal sequences like "../../etc/passwd" to escape the intended directory and access sensitive files anywhere on the file system. Attackers can also use various encoding techniques such as URL encoding (%2e%2e%2f), double encoding, unicode normalization, or null byte injection to bypass basic input filters.
Path Traversal is classified under OWASP A01 (Broken Access Control) in the 2021 Top 10. Despite being a well-known vulnerability with straightforward prevention methods, it continues to appear in modern applications, particularly in file upload handlers, document viewers, image processors, and backup/restore functionality. The vulnerability is especially dangerous because it can lead to full system compromise when combined with other attack vectors.
How It Works
The application provides a feature that accepts a file name or path parameter from the user. This could be a document download endpoint, an image viewer, a template renderer, or any feature that serves files based on user input.
The application takes the user-supplied file name and directly concatenates it with a base directory path without proper validation. For example, it might build a path like /var/www/uploads/ + userInput to construct the full file path.
Instead of providing a legitimate file name like document.pdf, the attacker injects path traversal sequences such as ../../../../etc/passwd. These dot-dot-slash sequences navigate up the directory tree, escaping the intended base directory.
The resulting path becomes /var/www/uploads/../../../../etc/passwd, which the operating system resolves to /etc/passwd. The traversal sequences effectively cancel out parts of the base path, allowing access to arbitrary locations on the file system.
The application reads and returns the contents of the targeted file without any awareness that it has been tricked into accessing a file outside its intended directory. The attacker successfully retrieves sensitive system files, configuration data, or source code.
Vulnerable Code Example
@RestController
public class FileController {
private static final String BASE_DIR = "/var/www/uploads/";
@GetMapping("/download")
public ResponseEntity<Resource> downloadFile(
@RequestParam String filename) throws IOException {
// VULNERABLE: User input is directly concatenated
// into the file path without validation
Path filePath = Paths.get(BASE_DIR + filename);
Resource resource = new UrlResource(filePath.toUri());
if (resource.exists()) {
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + filename + "\"")
.body(resource);
}
return ResponseEntity.notFound().build();
}
}
// An attacker can access system files by submitting:
// GET /download?filename=../../../../etc/passwd
//
// Resulting path:
// /var/www/uploads/../../../../etc/passwd
// Which resolves to: /etc/passwd
//
// The attacker successfully reads sensitive system files.Secure Code Example
@RestController
public class FileController {
private static final Path BASE_DIR = Paths.get("/var/www/uploads/")
.toAbsolutePath().normalize();
private static final Set<String> ALLOWED_EXTENSIONS =
Set.of("pdf", "docx", "txt", "png", "jpg");
@GetMapping("/download")
public ResponseEntity<Resource> downloadFile(
@RequestParam String filename) throws IOException {
// SECURE: Validate and sanitize the filename
// 1. Remove any path separators from filename
String sanitized = Paths.get(filename).getFileName().toString();
// 2. Validate file extension against allowlist
String extension = sanitized.substring(
sanitized.lastIndexOf('.') + 1).toLowerCase();
if (!ALLOWED_EXTENSIONS.contains(extension)) {
return ResponseEntity.badRequest().build();
}
// 3. Construct the full path and normalize it
Path filePath = BASE_DIR.resolve(sanitized).normalize();
// 4. Critical: Verify the resolved path still starts with BASE_DIR
if (!filePath.startsWith(BASE_DIR)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
Resource resource = new UrlResource(filePath.toUri());
if (resource.exists() && resource.isReadable()) {
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + sanitized + "\"")
.body(resource);
}
return ResponseEntity.notFound().build();
}
}
// With proper validation, path traversal attempts fail:
// Input: ../../../../etc/passwd
// After sanitization: passwd (path separators removed)
// Resolved path: /var/www/uploads/passwd
// startsWith check: passes (within BASE_DIR)
// Result: File not found (passwd doesn't exist in uploads)Types of Path Traversal
Relative Path Traversal
The most common form of path traversal attack. Attackers use ../ sequences (dot-dot-slash) to navigate up the directory tree and escape the intended base directory. For example, ../../../etc/passwd moves up three directory levels to access the /etc directory. Variations include using backslashes on Windows (..\..\..\), multiple slashes (....//....//), or combining them in various ways to bypass simple pattern-matching filters.
Absolute Path Traversal
Attackers provide a complete absolute path directly, such as /etc/passwd on Unix systems or C:\Windows\System32\config\SAM on Windows. This bypasses the base directory entirely if the application doesn't validate that the resolved path starts with the intended base directory. Some applications mistakenly trust that prepending a base path provides security, but if the user input begins with a path separator, it overrides the base path completely in some file system APIs.
Encoding & Filter Bypass
Sophisticated attackers use various encoding techniques to evade basic input filters. URL encoding converts ../ to %2e%2e%2f, double encoding becomes %252e%252e%252f, and unicode/UTF-8 encoding can represent dots as %c0%2e. Additional techniques include null byte injection (%00) to terminate strings early, 16-bit unicode encoding, and exploiting normalization differences between validation and file access code. Filters that only check for literal "../" strings are easily bypassed by these encoding variations.
Impact
A successful Path Traversal attack can have severe consequences, ranging from information disclosure to complete system compromise. The impact depends on the permissions of the web server process, the files accessible on the system, and what the attacker can do with the disclosed information.
Attackers can read the application's source code files, revealing business logic, proprietary algorithms, hardcoded credentials, API keys, and other vulnerabilities in the code. This information can be used to plan more sophisticated attacks tailored to the specific application architecture.
Access to configuration files exposes database credentials, API secrets, encryption keys, and internal network information. Common targets include .env files, config.php, application.properties, web.config, and cloud provider credential files like ~/.aws/credentials.
Reading sensitive operating system files like /etc/passwd, /etc/shadow (if permissions allow), Windows SAM database, or registry hives can provide information for privilege escalation attacks. Log files may contain session tokens, user activity patterns, or additional vulnerabilities.
In some scenarios, attackers can combine path traversal with log file injection. By injecting malicious code into log files (e.g., through User-Agent headers or error messages) and then using path traversal to include those log files as executable code (via PHP include, JSP include, etc.), attackers can achieve remote code execution and full server compromise.
Prevention Checklist
Maintain a predefined list of allowed file names or use indirect references like database IDs mapped to file names. Instead of accepting arbitrary file names from users, map numeric IDs to actual file paths server-side. This completely eliminates the possibility of path manipulation by preventing direct file path input.
Always resolve paths to their canonical absolute form using functions like Path.normalize(), realpath(), or File.getCanonicalPath(). After canonicalization, verify that the resolved path starts with the expected base directory. This prevents both relative and absolute path traversal attempts.
Use Path.getFileName() or equivalent functions to extract only the file name portion, automatically removing any directory separators and path traversal sequences. This ensures that user input can only specify a file name, not a path structure.
Maintain a strict allowlist of permitted file extensions and reject any files that don't match. Check the extension after sanitization and normalization to prevent double-extension attacks. Use case-insensitive comparison and check for null byte injection attempts that might truncate the extension.
Run the web application with minimal file system permissions. The application should only have read access to files it legitimately needs to serve, and should run under a dedicated user account with restricted permissions. This limits the damage an attacker can do even if path traversal is successful.
Avoid concatenating user input directly into file paths. Use parameterized file system APIs, path builder functions, or abstraction layers that handle sanitization automatically. Treat file paths from users the same way you treat SQL queries—never trust user input without thorough validation and sanitization.
Real-World Examples
Fortinet VPN (CVE-2018-13379)
A critical path traversal vulnerability in Fortinet's FortiOS SSL VPN allowed unauthenticated attackers to download system files by manipulating the file path parameter. Attackers exploited this to steal VPN credentials, leading to widespread breaches. The vulnerability affected hundreds of thousands of devices and was actively exploited in the wild, resulting in major government and corporate compromises.
Citrix ADC (CVE-2019-19781)
Citrix Application Delivery Controller and Gateway contained a path traversal vulnerability that allowed remote code execution. Attackers could traverse directories to access and execute arbitrary files on the system. The vulnerability was so severe that organizations worldwide rushed to patch their Citrix infrastructure. Exploitation led to ransomware attacks and data breaches affecting major enterprises and government agencies.
Apache HTTP Server (CVE-2021-41773)
A path traversal vulnerability in Apache HTTP Server 2.4.49 allowed attackers to map URLs to files outside the configured document root. By sending specially crafted requests with encoded dot-dot-slash sequences, attackers could read source code and configuration files. When combined with CGI script execution (CVE-2021-42013), it led to remote code execution, making it one of the most critical Apache vulnerabilities in recent years.
Zip Slip Vulnerability
Zip Slip is a widespread path traversal vulnerability in archive extraction functionality. When extracting ZIP files, many libraries and applications failed to validate that file paths within the archive don't contain traversal sequences. Attackers could craft malicious ZIP files containing entries like ../../evil.sh that would extract outside the target directory, potentially overwriting critical system files or application code, leading to remote code execution.
Ready to Test Your Knowledge?
Put what you have learned into practice. Try identifying and fixing Path Traversal vulnerabilities in our interactive coding challenges, or explore more security guides to deepen your understanding.