Skip to content

Services, Wiki-Artikel und Blog-Beiträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen

Path Traversal - Verzeichnisüberschreitung (Directory Traversal)

Path traversal (CWE-22, OWASP A01:2021) allows attackers to access files outside the permitted directory using ../ sequences. Objective: Reading sensitive fi...

Table of Contents (4 sections)

Summary: Path traversal (CWE-22, OWASP A01:2021) allows attackers to access files outside the permitted directory using ../ sequences. Objective: Reading sensitive files (/etc/passwd, web.config, .env, SSH keys); in the worst-case scenario, writing or executing files. Variants: URL-encoded traversal (%2e%2e%2f), double-encoded (%252e%252e%252f), null-byte injection (.php%00), Windows paths with backslash notation. Protection: absolute path validation with realpath(), allowlist-based file selection.

Path Traversal is one of the oldest and most persistent web vulnerabilities. Despite its long history, it regularly turns up in penetration tests—and in 2021, CVE-2021-41773 (Apache HTTP Server) made global headlines: a single %2e%2e/cgi-bin/ was enough to trigger remote code execution. The pattern is always the same: unvalidated user input flows directly into file system access.

Basic Principle

Normal file access:
  https://example.com/download?file=report.pdf
  → Server: /var/www/uploads/report.pdf ← allowed

Path traversal attack:
  https://example.com/download?file=../../../etc/passwd
  → Server: /var/www/uploads/../../../etc/passwd
           = /etc/passwd  ← outside the allowed directory!

Simple vulnerable implementation (PHP):
  $file = $_GET['file'];
  readfile('/var/www/uploads/' . $file);  // ← NO protection!

Typical attack targets:
  Linux:
  → /etc/passwd (user list)
  → /etc/shadow (password hashes, if as root)
  → /etc/hosts (network configuration)
  → ~/.ssh/id_rsa (SSH private key!)
  → /proc/self/environ (environment variables containing API keys!)
  → /proc/self/cmdline (process arguments)

  Windows:
  → C:\Windows\win.ini (system information)
  → C:\Windows\System32\drivers\etc\hosts
  → C:\inetpub\wwwroot\web.config (database passwords!)
  → C:\Users\[user]\AppData\Local\Microsoft\Outlook\*.ost

  Web applications:
  → .env (database passwords, API keys, secrets!)
  → config/database.yml (Rails)
  → WEB-INF/web.xml (Java)
  → ../../../wp-config.php (WordPress)

Bypass Techniques

Bypassing simple filters:

Filter 1: Replaces "../" with "" (non-recursive):
  Bypass: "....//....//....//etc/passwd"
  → After replacement: "../../../etc/passwd"!

Filter 2: URL decoding only once:
  Bypass: "%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd"
  → Decoded: "../../../etc/passwd"

Filter 3: Slash is filtered:
  Bypass: "%252e%252e%252fetc%252fpasswd"  (double-encoded)
  → First decoding: "%2e%2e%2fetc%2fpasswd"
  → Second decoding: "../../../etc/passwd"

Filter 4: Expects .jpg at the end:
  Bypass (Null byte, Legacy PHP < 5.3.4):
  "../../../../etc/passwd%00.jpg"
  → PHP stops at null byte: reads /etc/passwd
  → .jpg check: filename ends with .jpg ← PASS!

Filter 5: Checks if path starts with "/uploads/":
  Bypass: "/uploads/../../../../etc/passwd"
  → Starts with /uploads/ → PASS!
  → But contains path traversal!

Windows-specific bypasses:
  Backslash: "..\..\..\..\Windows\win.ini"
  URL-encoded: "..\"..\"..\"..\Windows\win.ini"
  UNC paths: "\\server\share\file"
  Drive letter: "C:\Windows\win.ini" (if absolute paths are accepted)

ZIP/archive-based path traversal (Zip Slip):
  ZIP archive containing the entry "../../../evil.php"
  → When the application unpacks the ZIP: evil.php ends up OUTSIDE the target folder!
  → Known as "Zip Slip" (2018, Snyk)
  → Affects: Java, Python, Go, Ruby zip libraries (unpatched versions)

Detection in Penetration Testing

Systematic Testing:

1. Parameter Identification:
   → All parameters that indicate filenames/paths:
     ?file=, ?page=, ?path=, ?filename=, ?template=, ?doc=,
     ?view=, ?include=, ?load=, ?source=, ?content=, ?show=

2. Payload Progression (from simple to complex):
   Level 1: Simple
   ?file=../../../etc/passwd

   Level 2: URL-encoded
   ?file=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd

   Level 3: Double-encoded
   ?file=%252e%252e%252f%252e%252e%252f%252e%252e%252fetc%252fpasswd

   Level 4: Null Byte (Legacy)
   ?file=../../../etc/passwd%00.pdf

   Level 5: OS-specific
   ?file=..\..\..\Windows\win.ini  (Windows)

3. Burp Suite Intruder:
   → Payload position: ?file=§value§
   → Payload list: SecLists/Fuzzing/LFI/LFI-Jhaddix.txt
   → Grep Match: "root:x:", "[drivers]", "DB_PASSWORD"

4. Indicators of Success:
   → Response contains "/bin/bash" or "root:x:0:0:" → /etc/passwd
   → Response contains "[fonts]" → win.ini
   → Error message contains path information: "Failed to open /etc/..."

5. Automated Testing:
   # Nuclei with LFI templates:
   nuclei -u https://target.com -tags lfi

   # dotdotpwn:
   dotdotpwn -m http -h target.com -u "https://target.com/page?file=TRAVERSAL"

Mitigation Measures

Secure implementations by language:

PHP - realpath() for absolute path validation:
  $base = realpath('/var/www/uploads');
  $requested = realpath($base . '/' . $_GET['file']);

  if ($requested === false ||
      strpos($requested, $base) !== 0) {
    die('Access denied');
  }
  // Only here: Read file

  Why realpath() is correct:
  → Resolves all ../ (including URL-encoded ones after decoding)
  → Returns FALSE if file does not exist → Attack detectable
  → Comparison with $base: outside? → DENY!

Python - pathlib for secure path validation:
  from pathlib import Path

  BASE_DIR = Path('/var/www/uploads').resolve()
  requested = (BASE_DIR / user_input).resolve()

  try:
    requested.relative_to(BASE_DIR)  # Raises ValueError if outside!
  except ValueError:
    raise PermissionError('Access denied')

  # Now secure:
  content = requested.read_bytes()

Java - Path.normalize() + startsWith():
  Path base = Paths.get("/uploads").toAbsolutePath().normalize();
  Path requested = base.resolve(userInput).normalize();

  if (!requested.startsWith(base)) {
    throw new SecurityException("Path traversal detected");
  }

Node.js - path.resolve() + startsWith():
  const base = path.resolve('/uploads');
  const requested = path.resolve(base, userInput);

  if (!requested.startsWith(base + path.sep)) {
    return res.status(403).send('Forbidden');
  }

Whitelist approach (most secure):
  // Instead of open paths: only allowed filenames
  const ALLOWED_FILES = {
    'manual': 'manual.pdf',
    'report': 'q4-report.pdf',
  };

  const filename = ALLOWED_FILES[req.query.doc];
  if (!filename) return res.status(400).send('Invalid document');
  res.sendFile(path.join('/uploads', filename));

Operating system level:
  □ Web server process with minimal privileges (no root!)
  □ chroot jail or container isolation
  □ AppArmor/SELinux profiles: Read access only to defined paths
  □ WAF rules: Block "../" and encoding variants
  □ Logging: Alert on file accesses to anomalous paths

Questions about this topic?

Our experts advise you free of charge and without obligation.

Free Consultation

About the Author

Chris Wojzechowski
Chris Wojzechowski

Geschäftsführender Gesellschafter

E-Mail

Geschäftsführender Gesellschafter der AWARE7 GmbH mit langjähriger Expertise in Informationssicherheit, Penetrationstesting und IT-Risikomanagement. Absolvent des Masterstudiengangs Internet-Sicherheit an der Westfälischen Hochschule (if(is), Prof. Norbert Pohlmann). Bestseller-Autor im Wiley-VCH Verlag und Lehrbeauftragter der ASW-Akademie. Einschätzungen zu Cybersecurity und digitaler Souveränität erschienen u.a. in Welt am Sonntag, WDR, Deutschlandfunk und Handelsblatt.

10 Publikationen
  • Einsatz von elektronischer Verschlüsselung - Hemmnisse für die Wirtschaft (2018)
  • Kompass IT-Verschlüsselung - Orientierungshilfen für KMU (2018)
  • IT Security Day 2025 - Live Hacking: KI in der Cybersicherheit (2025)
  • Live Hacking - Credential Stuffing: Finanzrisiken jenseits Ransomware (2025)
  • Keynote: Live Hacking Show - Ein Blick in die Welt der Cyberkriminalität (2025)
  • Analyse von Angriffsflächen bei Shared-Hosting-Anbietern (2024)
  • Gänsehaut garantiert: Die schaurigsten Funde aus dem Leben eines Pentesters (2022)
  • IT Security Zertifizierungen - CISSP, T.I.S.P. & Co (Live-Webinar) (2023)
  • Sicherheitsforum Online-Banking - Live Hacking (2021)
  • Nipster im Netz und das Ende der Kreidezeit (2017)
IT-Grundschutz-Praktiker (TÜV) IT Risk Manager (DGI) § 8a BSIG Prüfverfahrenskompetenz Ausbilderprüfung (IHK)
This article was last edited on 03/29/2026. Responsible: Chris Wojzechowski, Geschäftsführender Gesellschafter at AWARE7 GmbH. License: CC BY 4.0 - free use with attribution: "AWARE7 GmbH, https://a7.de"