What It Is
Path Traversal escapes the intended directory via ../. LFI (Local File
Inclusion) is when the app doesn't just read but includes a local file (PHP
include/require), which can even lead to code execution. Same root cause as any
injection: user input used as part of a path without validation.
How It Works
$file = $_GET['page'];
include("/var/www/pages/" . $file);
?page=../../../../etc/passwd resolves to /etc/passwd. Each ../ climbs a level.
What to Read First
/etc/passwd— confirm the bug.- App source code — often holds secrets:
../config.py,../.env,../app.py. A FlaskSECRET_KEYlets you forge sessions. - Logs,
/proc/self/environ, SSH keys.
Filter Bypasses
- Encoding:
%2e%2e%2f, double-encoding%252e. - Null byte /
....//(legacy PHP). - Absolute path if the prefix isn't enforced.
- PHP wrappers:
php://filter/convert.base64-encode/resource=index.phpto dump source.
Defense
- Don't build paths from input. Use a whitelist (
id → path), not the raw name. - Canonicalize and verify:
os.path.realpath()must stay inside the allowed dir. - Stripping bad chars alone isn't enough (encoding bypasses it).
- Least privilege for the process.
Practice: the LFI → Secret Key → Session Forgery lab.