TL;DR
Directory traversal vulnerabilities let attackers access files outside of the intended web root directory. This guide shows common bypass techniques and how to prevent them in PHP.
Understanding Directory Traversal
Directory traversal (also known as path traversal) happens when a web application uses user-supplied input to construct file paths without proper validation. Attackers can manipulate the input to include characters like ../ to move up directory levels and access sensitive files.
Bypass Techniques
- Simple Path Manipulation: The most basic attack uses
../sequences.http://example.com/index.php?file=../../etc/passwd - URL Encoding: Encoding characters can sometimes bypass simple filters.
- Try encoding the dots (
%2e%2e%2f) or slashes (%2f).
http://example.com/index.php?file=%2e%2e%2fetc%2fpasswd - Try encoding the dots (
- Double URL Encoding: Applying encoding twice can sometimes work.
http://example.com/index.php?file=%252e%252e%252fetc%252fpasswd - Absolute Pathnames: If the application doesn’t properly sanitize, try using absolute paths.
http://example.com/index.php?file=/etc/passwd - Null Byte Injection (%00): In older PHP versions (before 5.3.4), a null byte could terminate the string early, bypassing checks.
http://example.com/index.php?file=../../etc/passwd%00 - Trailing Characters: Appending characters after the desired path might bypass filters that only check for
../at the beginning or end.http://example.com/index.php?file=../../etc/passwdX - Mixed Encoding and Traversal: Combine techniques like URL encoding with traversal sequences.
http://example.com/index.php?file=%2e%2e%2f%2e%2e%2fetc%2fpasswd - Using Different Path Separators: Windows uses backslashes (
) as a path separator; sometimes, these can be used in combination with forward slashes.http://example.com/index.php?file=....etcpasswd
Prevention Techniques
- Input Validation: The most important step! Never trust user input.
- Whitelist Approach: Only allow specific, known-good file extensions or filenames. This is the preferred method.
- Blacklist Approach (Less Secure): Block dangerous characters like
../, but this can be easily bypassed.
- Use
realpath(): Convert user-supplied paths to their absolute canonicalized form.$file = $_GET['file']; $safe_file = realpath($file); if (strpos($safe_file, '/var/www/html/') === 0) { // File is within the allowed directory include($safe_file); } else { echo 'Invalid file!'; }Important: Ensure that the base path in your comparison (
'/var/www/html/'in the example) is correct for your environment. - Use
basename(): Extract only the filename from the user-supplied input.$file = $_GET['file']; $safe_file = basename($file); include($safe_file); // Only include files within the current directory. - Chroot Jail: Restrict the application’s access to a specific directory.
- Disable Path-Related Functions: If possible, disable functions like
chdir()andscandir()if they are not needed.
Important Considerations
- Always keep your PHP version up to date.
- Regularly review your code for potential vulnerabilities.
- Use a web application firewall (WAF) to help detect and block attacks.

