REFERENCE GUIDE
Path traversal and canonicalization boundaries
Traversal happens when an attacker-controlled path escapes an intended filesystem root.
Also known as: directory traversal · LFI
Mechanism
Traversal happens when an attacker-controlled path escapes an intended filesystem root. The vulnerable operation may be reading, writing, extracting an archive, or resolving a template. Percent decoding, separator conversion, dot-segment removal, and symlink resolution can occur in different layers. A string-prefix check is weaker than checking the final resolved path against the allowed directory boundary.
Practical method
Find the parameter that names a file and first request a known allowed file. Test dot segments and encoding separately while keeping the suffix constant. Establish whether the application appends an extension or prepends a directory. Use a harmless fixture outside the allowed root in a local lab to distinguish traversal from an ordinary missing-file response.
from pathlib import Path
root = Path("fixtures/public").resolve()
candidate = (root / user_path).resolve()
if not candidate.is_relative_to(root):
raise ValueError("outside allowed root")
Interpreting evidence
Compare returned bytes with the expected fixture, not just the HTTP status. Error paths can expose server-side names without permitting reads. For write operations, verify the actual destination after all archive or filename transformations.
Pitfalls and limits
The resolved-path check can still race with symlink changes in writable directories. OS-specific separators, drive prefixes, and case rules matter. A normalizing proxy may remove a candidate before the backend sees it.
Selected licensed upstream examples
These equivalent-looking path fragments intentionally remain distinct: they test literal traversal, platform separator handling, one decoding pass, and two decoding passes. Apply them to a harmless fixture path and determine which layer normalizes each form. Overlong UTF-8 and historical null-byte variants from the broader collection are omitted because support is implementation-specific and often obsolete.
../
..\
%2e%2e%2f
%252e%252e%252f
Attribution: PayloadsAllTheThings; MIT. Selected lines, explanatory notes added. Pinned upstream file.