Path Traversal
Also Known As
directory traversal
dot-dot-slash
../ attack
path traversal attack
TL;DR
User input used in a file path allows attackers to navigate outside the intended directory using ../ sequences.
Explanation
Path traversal (also called directory traversal) lets attackers read or include arbitrary files on the server by supplying sequences like ../../etc/passwd in a parameter used to build a file path. In PHP, include/require with user-supplied filenames is the classic vector. Mitigation requires resolving the real path with realpath() and asserting it starts with the intended base directory — whitelist known-good filenames where possible.
How It's Exploited
GET /download?file=../../etc/passwd
# Reads /etc/passwd if not validated
# Reads /etc/passwd if not validated
Diagram
flowchart TD
INPUT2[User input: ../../../etc/passwd] --> APP_READ[App reads<br/>uploads . . / . . / . . /etc/passwd]
APP_READ --> SECRET[Reads /etc/passwd!]
subgraph Fix2
REALPATH2[realpath resolves all .. and symlinks]
BASEDIR[Check resolved path starts with allowed dir]
REALPATH2 --> BASEDIR
BASEDIR -->|outside allowed| REJECT3[Reject - path traversal]
BASEDIR -->|inside allowed| ALLOW2[Allow access]
end
style APP_READ fill:#f85149,color:#fff
style SECRET fill:#f85149,color:#fff
style REJECT3 fill:#238636,color:#fff
Common Misconception
✗ Stripping ../ from user input prevents path traversal. Attackers use encoded variants (..%2F, %2e%2e%2f, ....//), unicode sequences, and URL double-encoding that survive naive string replacement. Use realpath() and compare against the allowed base directory.
Why It Matters
A path traversal vulnerability can read any file the web server process has permission to access — including /etc/passwd, .env files, and PHP source containing database credentials.
Common Mistakes
- Passing user-supplied filenames to file_get_contents(), readfile(), or fopen() without normalisation.
- Filtering traversal sequences with str_replace('../', '') — bypassed with ....// which collapses to ../.
- Not verifying that the realpath() of the requested file is within the intended directory.
- Allowing the full filesystem path to be specified via a 'file' or 'path' query parameter.
Code Examples
✗ Vulnerable
$file = $_GET['file'];
readfile('/var/www/uploads/' . $file);
✓ Fixed
$base = realpath('/var/www/uploads');
$requested = realpath($base . '/' . $_GET['file']);
if ($requested === false || !str_starts_with($requested, $base . DIRECTORY_SEPARATOR)) {
http_response_code(403); exit;
}
readfile($requested);
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
30
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
Amazonbot 7
Perplexity 7
Ahrefs 3
Google 2
Unknown AI 2
SEMrush 2
Majestic 1
ChatGPT 1
Also referenced
How they use it
crawler 24
crawler_json 1
Related categories
⚡
DEV INTEL
Tools & Severity
🔴 Critical
⚙ Fix effort: Low
⚡ Quick Fix
Pass user input through realpath() then verify the result starts with your allowed base directory using str_starts_with()
📦 Applies To
PHP 5.0+
web
cli
🔗 Prerequisites
🔍 Detection Hints
readfile( or fopen( or include( or file_get_contents( with $_GET/$_POST without realpath validation
Auto-detectable:
✓ Yes
semgrep
psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: Function
Tests: Update
CWE-22
CWE-23
CWE-35