Web Application Security: Hands-On Practice (Chapter 10 from The Web Application Hacker’s Handbook)
Note: This write-up reflects my learning and hands-on practice based on the book The Web Application Hacker’s Handbook: Discovering and Exploiting Security Flaws by Dafydd Stuttard and Marcus Pinto.
Exploiting Path Traversal:
Path traversal vulnerabilities occur when a web application improperly uses user input to access files, allowing unintended navigation within the file system. Such flaws can expose sensitive data, enable file modification, or even lead to full system compromise. They are often difficult to detect because applications may implement partial or flawed defenses that appear secure but can still be bypassed.
Common Vulnerabilities:
When something is called a common vulnerability, it means:
· It appears frequently in real-world applications
· Developers often make this mistake unintentionally
· Attackers know it well and actively look for it
Path traversal vulnerabilities occur when applications unsafely use user-controlled input to access files or directories on a server. By manipulating file paths with traversal sequences, attackers can read or overwrite sensitive system files, potentially gaining full control of the server. Although many applications attempt to defend against these attacks, poorly designed input validation often leaves them vulnerable to bypasses.
Finding and Exploiting Path Traversal Vulnerabilities:
When something is called a common vulnerability, it means:
Locating Targets for Attack:
Locating path traversal targets involves identifying application features that interact with the server’s file system, especially those influenced by user input. Obvious file uploads and downloads, as well as subtle behaviors like template loading or document display, can all expose attack surface. By carefully analyzing parameters, error messages, and file system activity — especially when local access is available — testers can efficiently identify areas vulnerable to path traversal.
Locating Targets for Attack on a local website:
Browser:
Step1: (Goal: Normal behaviour)
We can see the report content.
Step2: (Goal: Controlled failure)
· Error message
· File-related exception
· Often shows partial file paths
This confirms file access is happening.
Step3: (Goal: Unique test string technique) Insert a unique marker
· Error message contains traversaltest
· Confirms our input reached a file API
Repeat it for other endpoints:
Also,
These parameters are confirmed targets.
Step4: (Goal: Path traversal vulnerability)
Also,
This confirms the path traversal vulnerability.
Detecting Path Traversal Vulnerabilities:
App.py:
Hello.txt:
Terminal:
Browser:
Step1: (Goal: Normal traversal)
http://127.0.0.1:5000/read?file=hello.txt
Step2: (Goal: Canonicalization test)
Important detail:
· Python does NOT canonicalize the path
· It passes the string as-is to the OS
· Windows tries to open directories in order
Step3: (Goal: Straight up file access)
Circumventing Obstacles to Traversal Attacks:
App.py:
Step1: (Goal: Baseline tests)
Now, open the blocked:
So far, looks “secure”.
Step2: (Goal: Absolute path bypass)
Works immediately
Why?
· No ../
· Passes all filters
· os.path.join() ignores BASE_DIR
Step3: (Goal: Double URL encoding bypass)
Why it works:
· App decodes once
· Traversal appears after filtering
· OS resolves it
Step4: (Goal: Backslash bypass)
If filter blocks / but not \
Step5: (Goal: Prefix bypass)
Step6: (Goal: Extension-based bypass)
Coping with Custom Encoding:
Browser:
Step1: (Goal: Baseline test)
When clicked on “Upload Note” button:
We get:
· A download token (looks random)
Get Aditya Kumar’s stories in your inbox
Join Medium for free to get updates from this writer.
· A download link
Click the link. The note content is returned.
Step2: (Goal: Basic path traversal tests)
Classic traversal: http://127.0.0.1:5000/download?file=../../../../etc/passwd
Windows traversal: http://127.0.0.1:5000/download?file=..\..\..\Windows\System32\drivers\etc\hosts
Absolute path: http://127.0.0.1:5000/download?file=C:\Windows\System32\drivers\etc\hosts
Why?
· Input is Base64-decoded
· Then validated as UUID
· Traversal never reaches filesystem
Step3: (Goal: Token tampering tests) Take a valid token: NWNkMWEyOTUtZDU3Yi00OWVjLTkxYTctNGNlMGU1ZmVlZTY5 then change it a bit, and try to enter it.
Why?
· Base64 decode fails OR
· UUID validation fails OR
· Path boundary fails
Preventing Path Traversal Vulnerabilities:
Core problem
· Path traversal is not about ../
· It happens when user input influences filesystem paths
· Once user data reaches file APIs, exploitation becomes possible
· Encoding tricks (URL, Unicode, null bytes) are just ways to confuse path resolution
Best possible defense
· Do not accept user-supplied paths at all
· Use identifiers (IDs) instead of filenames
· Map IDs to files server-side
· Examples:
o UUIDs
o Database IDs
o Base64 tokens
When filenames must be accepted
· Common in:
o Upload/download features
o Export tools
o Backup systems
· Requires defense in depth, not a single filter
Decode and canonicalize first
· Attackers use encoded traversal sequences
· Filtering before decoding is ineffective
· Correct processing order:
1. URL decode
2. Unicode normalize
3. Canonicalize path
4. Validate
- Prevents:
1. Double encoding
2. Unicode tricks
3. Overlong UTF-8
4. Mixed slashes
Reject traversal outright (don’t sanitize)
· Never “clean” input by removing ../
· Sanitization can be bypassed using nested sequences
· If traversal is detected:
o Reject the request
o Stop processing
o Do not modify input
· Sanitization introduces new vulnerabilities
Restrict allowed file types
· Use a hard-coded allowlist of file extensions
· Reduces impact if traversal succeeds
· Prevents access to:
o System files
o Executable scripts
- Not sufficient alone due to:
o Null byte attacks
o Newline truncation
o Runtime differences
Enforce canonical path boundaries (most important)
· Resolve the final absolute path
· Ensure it stays within the allowed base directory
· Reject if it escapes
· Defeats:
o Encoded traversal
o Absolute paths
o Many symlink attacks
- This is the strongest runtime defense
Use filesystem isolation (damage control)
· Chroot or equivalent directory isolation
· Limits what traversal can access even if exploited
· Turns critical vulnerabilities into low-impact ones
· More common on Unix, possible on Windows via drive mounting
· This is containment, not prevention
Use filesystem isolation (damage control)
· Chroot or equivalent directory isolation
· Limits what traversal can access even if exploited
· Turns critical vulnerabilities into low-impact ones
· More common on Unix, possible on Windows via drive mounting
· This is containment, not prevention
Defense-in-depth mental model
1. Avoid filesystem paths entirely (best)
2. Use identifiers instead of filenames
3. Decode before validating
4. Reject malicious input, don’t sanitize
5. Enforce canonical directory boundaries
6. Isolate filesystem access
7. Log and alert on attacks
Contact Me
📧 Email: adii.utsav@gmail.com
🔗 LinkedIn: https://www.linkedin.com/in/aditya-kumar-3241b6286/
💻 GitHub: https://github.com/Rememberful









