Overview
Path traversal (also called directory traversal) is a class of web vulnerability in which an attacker supplies crafted input to a file-path parameter, causing the application to resolve a location outside the intended directory — the web root or a designated upload/download folder. By inserting sequences such as ../ (or URL-encoded equivalents like %2e%2e%2f), an attacker can escape the expected directory tree and reach sensitive files anywhere the server process has read or write access.
The vulnerability is catalogued as CWE-22 and falls under OWASP A01:2021 – Broken Access Control. It is one of the oldest and most consistently exploited vulnerability classes in web security, appearing in commercial software, open-source frameworks, and custom-built applications alike.
How it works
Applications are vulnerable when they construct a file-system path by concatenating a base directory with user-supplied input without adequate validation or canonicalization. The attack proceeds as follows:
- Attacker identifies a file-path parameter — commonly a query string parameter (
?file=report.pdf), a form field, an HTTP header, or part of a REST path segment (/api/download/{filename}). - Attacker injects traversal sequences — for example, replacing
report.pdfwith../../../../etc/passwd. Each../moves one directory level toward the filesystem root. - Server resolves the manipulated path — if the application does not canonicalize and validate the final path, the OS resolves it and the application reads (or writes) the unintended file.
- Response leaks file contents — the application returns the file to the attacker, embeds it in an error message, or silently processes it.
Common bypass techniques that evade naive blocklists include:
- URL encoding:
%2e%2e%2for%2e%2e/ - Double URL encoding:
%252e%252e%252f - Unicode / UTF-8 overlong encoding:
%c0%ae%c0%ae%c0%af - Mixed slash styles on Windows:
..\or..%5c - Null byte injection (in older environments):
../../../../etc/passwd%00.jpg - Nested traversal sequences that survive a single-pass strip:
....//....//
Write-capable path traversal is especially dangerous: an attacker can overwrite configuration files, plant web shells, or corrupt application data.
Business impact
A successful path traversal attack can have severe consequences:
- Confidential data exposure: Credentials, private keys, environment files (
.env), database configuration, and application source code can be exfiltrated. - System compromise: Reading
/etc/passwd,/etc/shadow, SSH private keys, or cloud instance metadata endpoints may facilitate privilege escalation or lateral movement. - Remote code execution: Write-based traversal can place executable files (web shells, server-side scripts) in publicly accessible directories, leading to full server takeover.
- Regulatory and compliance penalties: Exposure of personal data may trigger obligations under GDPR, HIPAA, PCI DSS, and similar frameworks, with associated fines and breach-notification requirements.
- Reputational damage: Public disclosure of a data breach resulting from path traversal can permanently erode customer trust.
How to fix it
- Avoid passing user input to file-system APIs. The most robust defense is to redesign the feature so that user input maps to an application-controlled identifier (e.g., a database record ID) rather than directly to a file path.
- Canonicalize before validating. Resolve the full, absolute path using the language/platform's canonical path function (
realpath()in PHP/C,Path.GetFullPath()in .NET,os.path.realpath()in Python,fs.realpathSync()in Node.js) before any security check. - Enforce a strict prefix check. After canonicalization, verify that the resolved path begins with the expected base directory string. Reject any path that does not share the intended prefix.
- Use an allowlist of permitted filenames or extensions. Accept only known-safe filenames, extensions, or patterns; reject everything else. Do not rely solely on a denylist of traversal sequences.
- Apply least-privilege file-system permissions. Run the web application process under an account with minimal file-system access. Use chroot jails, containers, or OS-level mandatory access controls to limit the damage of any bypass.
- Serve static files through the web server, not application code. Let the web server (nginx, Apache) handle static file delivery with its own path normalization and access controls, rather than proxying through application logic.
- Sanitize archive extraction. When extracting ZIP, TAR, or other archive formats, check each entry's path after canonicalization ("Zip Slip" variant of path traversal, CVE class).
- Apply security headers. While not a primary defense, headers such as
Content-Disposition: attachmentfor file downloads reduce the risk of served content being interpreted by the browser. - Log and alert on traversal patterns. Monitor access logs and application logs for sequences like
../,%2e%2e, and repeated directory separators; alert on anomalies.
References
- OWASP – Path Traversal Attack
- OWASP Top 10 A01:2021 – Broken Access Control
- OWASP WSTG – Testing for Path Traversal (OTG-AUTHZ-001)
- MITRE CWE-22 – Improper Limitation of a Pathname to a Restricted Directory
- MITRE CWE-23 – Relative Path Traversal
- MITRE CWE-24 – Absolute Path Traversal
- PortSwigger Web Security Academy – File Path Traversal
- Snyk Research – Zip Slip Vulnerability (Archive Path Traversal)