Path Traversal Explained: The Art of Escaping the Filesystem Prison

Idle

Path Traversal: The Art of Escaping the Filesystem Prison

Welcome, security engineers, bug hunters, and people who still think ../ is harmless.

If SQL Injection is about betraying your database, then Path Traversal is about betraying your filesystem. It’s the vulnerability that turns “Here’s a file you’re allowed to see” into “Here’s literally everything on the server — enjoy.”

No magic. No zero-days. Just dots. Slashes. And developer trust.

This article is not a quick overview. This is the Path Traversal Hall of Fame — how it works, how it’s exploited in the real world, how developers keep re-introducing it, and how attackers chain it into full compromises.

If you’ve ever written something like:

open("/app/files/" + user_input)

This article is about you.


What Is Path Traversal? (The Filesystem Betrayal)

Path Traversal (also called Directory Traversal) is a vulnerability that allows an attacker to access files and directories outside the intended directory by manipulating file paths.

The core idea is painfully simple:

The application trusts user input to stay inside a folder. The attacker teaches it how to walk out.

The Mental Model

Every Path Traversal bug follows this flow:

User Input → Path Construction → Filesystem Trust → Disaster

The application assumes:

  • The user will request valid filenames
  • The filesystem will “do the right thing”
  • ../ is someone else’s problem

The filesystem, of course, does exactly what it’s told.


The One-Line Bug That Breaks Everything

Let’s start with the smallest possible mistake.

filename = request.args.get("file")
with open("/app/files/" + filename) as f:
    return f.read()

Developer intention:

  • Serve files from /app/files/

Attacker input:

file=../../../../etc/passwd

Final resolved path:

/etc/passwd

No exploit framework. No memory corruption. Just string concatenation.


Why Path Traversal Is So Dangerous

Path Traversal is underestimated because it looks “read-only”. In reality, it often leads to:

  • Reading sensitive files ( /etc/passwd , .env , configs, source code)
  • Credential disclosure (DB passwords, API keys, tokens)
  • Local File Inclusion (LFI)
  • Remote Code Execution (via log poisoning, uploads, or templates)
  • Privilege escalation
  • Container and cloud secret leaks

Path Traversal is rarely the end of an attack. It’s usually the first unlocked door.


The Attacker’s Toolkit: How Traversal Actually Works

The Classic Payloads

  • ../ → move up one directory
  • ../../../../ → move up a lot
  • ..\ → Windows traversal
  • Absolute paths: /etc/passwd , C:\Windows\win.ini

Encoding Tricks

Attackers don’t stop at ../.

  • URL encoding: %2e%2e%2f
  • Double encoding: %252e%252e%252f
  • Mixed encoding: ..%2f
  • UTF-8 overlong sequences (legacy): ..%c0%af

Why Filtering Fails

Blocking "../" does nothing when:

  • The server decodes twice
  • The framework normalizes late
  • The OS handles paths differently
  • Windows accepts both / and \

Blacklists lose. Every time.


Types of Path Traversal (The Full Spectrum)

1. Basic Path Traversal

The textbook case.

file=../../../../etc/passwd

Still works in 2026. Still appears in production.


2. Encoded Traversal

Filters check raw input, filesystem sees decoded output.

file=%2e%2e%2f%2e%2e%2fetc%2fpasswd

3. Double-Decoding Traversal

Common in:

  • Reverse proxies
  • Legacy frameworks
  • Misconfigured middleware
file=%252e%252e%252fetc%252fpasswd

Decoded twice → ../etc/passwd


4. Windows-Specific Traversal

Windows is generous.

..\..\windows\win.ini

Also works with:

  • Mixed slashes
  • Case variations
  • UNC paths

5. Null Byte Injection (Legacy but Real)

Old PHP / C-based systems:

../../etc/passwd%00.png

The app thinks it’s an image. The OS stops at the null byte.


6. Zip Slip (Traversal by Archive)

Traversal inside compressed files.

../../../../var/www/html/shell.php

When extracted? Files land outside the intended directory.

This one caused real-world RCEs at scale.


7. Symlink Traversal

Upload a symlink → access it like a normal file.

uploads/report.pdf → symlink → /etc/shadow

The app checks the path. The filesystem follows the link.


Attack Vectors: Where Traversal Hides

Path Traversal doesn’t live only in /download.

1. GET Parameters

/download?file=report.pdf

Classic. Dangerous.


2. POST Data

Hidden in forms, JSON, or multipart requests.


3. API Endpoints

/api/export?path=users/2024.csv

APIs are prime targets.


4. HTTP Headers

  • User-Agent
  • Referer
  • X-Filename

Anything logged or reused later.


5. File Uploads

Filename-controlled paths:

filename=../../shell.php

6. Backup / Export Features

“Download your data” features are traversal goldmines.


Real-World Path Traversal Hall of Fame

1. Apache Tomcat (CVE-2017-12615)

What happened: Tomcat allowed path traversal in PUT requests.

Impact:

  • Upload files outside web root
  • Drop web shells
  • Full server compromise

Lesson: Filesystem bugs turn into RCE fast.


2. Zip Slip (2018)

What happened: Archive extraction without path validation.

Affected:

  • Jenkins
  • Nexus
  • Thousands of Java, Python, Go projects

Impact: Remote code execution by uploading a zip file.

Lesson: Traversal isn’t always user-visible.


3. Steam Client (2019)

What happened: Path traversal in update logic.

Impact:

  • Arbitrary file overwrite
  • Privilege escalation to SYSTEM

Lesson: Traversal isn’t just a web bug.


4. Fortnite Launcher

What happened: Improper path handling in Windows installer.

Impact:

  • Arbitrary file overwrite
  • Malware persistence

5. NASA Public API

What happened: Traversal in API paths.

Impact:

  • Internal configs exposed
  • Credentials leaked

Lesson: APIs don’t get a free pass.


Vulnerable Code: The Hall of Shame

PHP – The Classic Mistake

$file = $_GET['file'];
readfile("/var/www/files/" . $file);

Attack:

file=../../../../etc/passwd

Python – Flask Disaster

filename = request.args.get("file")
open("/app/files/" + filename)

Node.js – Express Mess

res.sendFile("/app/files/" + req.query.file)

Java – Servlet Slip

new FileInputStream("/app/files/" + file);

C# – .NET Nightmare

PhysicalFile("/app/files/" + file);

Go – Fast but Fragile

ioutil.ReadFile("/app/files/" + file)

Same bug. Different language. Same result.


Advanced Exploitation: When Traversal Grows Teeth

1. LFI → RCE (Log Poisoning)

  1. Inject code into logs via User-Agent
  2. Traverse to log file
  3. Include it
  4. Code execution

2. Traversal + Upload = Game Over

Upload:

filename=../../shell.php

Then access it normally.


3. Traversal in Containers

Docker doesn’t save you.

  • Mounted secrets
  • /proc/self/environ
  • Kubernetes tokens

Traversal still works inside the container’s view.


4. Cloud Secrets Leakage

  • .env
  • AWS credentials
  • GCP service accounts
  • Mounted volumes

Traversal loves cloud apps.


Defense: How to Actually Fix Path Traversal

1. Stop Concatenating Paths

If you remember nothing else, remember this.


2. Whitelisting (Not Blacklisting)

ALLOWED = {"report.pdf", "manual.pdf"}
if filename not in ALLOWED:
    abort(403)

3. Path Normalization + Verification

base = "/app/files"
full = os.path.normpath(os.path.join(base, filename))
if not full.startswith(base):
    abort(403)

4. Use Safe Framework APIs

  • Flask: send_from_directory
  • Node: path.resolve
  • Java: Paths.get().normalize()

5. Least Privilege

Your app should not:

  • Read /etc
  • Read source code
  • Run as root

6. Sandboxing

  • Docker (properly)
  • AppArmor
  • SELinux
  • Read-only mounts

7. WAF Is Not Enough

WAFs:

  • Miss encodings
  • Miss logic bugs
  • Can be bypassed

Defense must be in code.


Testing for Path Traversal Like a Pro

Manual Mindset

Ask:

  • “Where is user input used as a path?”
  • “Where do files come from?”
  • “Where do files go?”

Payloads to Try

../
../../
..%2f
%2e%2e%2f
%252e%252e%252f
..\ 
/etc/passwd
C:\Windows\win.ini

Tools

  • Burp Suite
  • OWASP ZAP
  • ffuf
  • Custom scripts

Code Review Grep Targets

  • open(
  • readFile
  • send_file
  • sendFile
  • FileInputStream
  • ioutil.ReadFile

Common Developer Myths

  • “We filtered ../”
  • “It’s behind auth”
  • “It’s internal”
  • “It’s just read-only”
  • “The framework handles it”

Attackers love these sentences.


Final Thoughts

Path Traversal is not flashy. It doesn’t look like an exploit. It doesn’t feel advanced.

And that’s exactly why it keeps working.

Every time you trust user input with the filesystem, you’re handing over a map and hoping the user doesn’t know how directories work.

They do.

Normalize paths. Whitelist aggressively. Assume the attacker knows the filesystem better than you.

Because most of the time — they do.

Recommended Next Steps

If you want Path Traversal to move from “I understand it” to “I can reliably find and break it”, here’s what to do next.

  • Set up vulnerable labs
    • DVWA (Directory Traversal + File Inclusion modules)
    • WebGoat (Path Traversal lessons)
    • OWASP Juice Shop (file access & API abuse)
    • Custom mini-apps with unsafe file download/upload endpoints
  • Practice in real environments
    • Hack The Box (machines with LFI / traversal chains)
    • TryHackMe (Directory Traversal & File Inclusion rooms)
    • Focus on chaining , not just reading /etc/passwd
  • Practice mindset, not payloads
    • Look for where user input becomes a path
    • Look for exports, backups, logs, uploads
    • Always ask: “What happens if I walk out of this directory?”
  • Study real-world incidents
    • Zip Slip post-mortems
    • Tomcat traversal CVEs
    • Client-side traversal bugs (Steam, launchers, installers)
    • Cloud and container traversal writeups
  • Audit real code
    • Grep codebases for open() , readFile() , sendFile()
    • Review any place paths are constructed manually
    • Review archive extraction logic carefully
  • Harden your own projects
    • Remove all path concatenation
    • Enforce strict whitelists
    • Apply least privilege at the filesystem level
    • Log and alert on traversal attempts
  • Think beyond the web
    • Desktop apps
    • Installers and updaters
    • CI/CD pipelines
    • Containerized workloads
  • Make filesystem security part of your SDLC
    • Code review checklists
    • Security tests for file access
    • Developer education on traversal risks

References