← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Path Traversal

security CWE-22 OWASP A3:2021 CVSS 7.5 PHP 5.0+ Intermediate

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

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);

Added 15 Mar 2026
Edited 22 Mar 2026
Views 30
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T
No pings yesterday
Amazonbot 7 Perplexity 7 Ahrefs 3 Google 2 Unknown AI 2 SEMrush 2 Majestic 1 ChatGPT 1
crawler 24 crawler_json 1
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

✓ schema.org compliant