Path Traversal (Directory Traversal)
Path traversal lets an attacker escape an intended directory by smuggling sequences like ../ into a file path.
Definition
Path traversal (also called directory traversal or "dot-dot-slash") is a vulnerability in which an application takes a filename or path from user input and uses it to access a file on the server without checking that the resolved path is inside the intended directory. The classic payload is `../../../etc/passwd`: each `../` ascends one directory, eventually reaching system files the application never meant to expose.
Path traversal looks simple but defeats most naive defences. URL-encoding (`%2e%2e%2f`), double-encoding, Unicode normalisation tricks, and OS-specific separators (`..\` on Windows, `..` with a trailing space on some filesystems) all bypass string-level checks. The only robust approach is to resolve the full path and verify it stays under an allowed root.
How it works
The application accepts a user-supplied path component (a filename to download, a template to render, a log to view). It joins the input to a base directory: `/var/www/uploads/ + userFilename`. If `userFilename` is `../../etc/passwd`, the OS path-resolution layer happily collapses the result to `/etc/passwd` and the application reads that file.
Variants include arbitrary file write (an upload feature that lets the attacker land a webshell in `/var/www/html/`), arbitrary file delete (a "clear log" handler with the same flaw), and "zip slip" — when an archive-extraction routine writes member files using paths embedded in the archive without validating they stay inside the extraction directory.
Impact
Reading credentials, private keys, configuration, and source code. With write primitives, the attacker can plant webshells or modify scheduled-task files. Combined with a deserialisation bug or a code-injection sink, path traversal upgrades to remote code execution.
Mitigation
Resolve the user-supplied path to its canonical form (`filepath.Abs` in Go, `Path.resolve()` in Java, `os.path.realpath` in Python) and verify it lives under the intended root prefix. Reject any path containing path-separator characters when only a filename is expected. For archive extraction, validate every entry's resolved path before writing. Where possible, abandon the model of "user names a file" entirely — use opaque ids in the application that map to safe filenames internally.
Examples
- CVE-2021-41773 — Apache HTTP Server path traversal in mod_proxy.
- CVE-2022-24348 — Argo CD path traversal via crafted Helm chart.