| Field | Detail |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Type | Web Cache Poisoning — Fat GET Request, Unkeyed Body |
| Difficulty | Practitioner |
| Objective | Poison the cache with a response that executes alert(1) in the victim's browser |
| Note | A user regularly visits the home page using Chrome |
Web Cache Poisoning via a Fat GET Request¶
Requesting / showed the same JSONP pattern as the parameter cloaking lab:
<script type="text/javascript" src="/js/geolocate.js?callback=setCountryCookie"></script>
The lab description hints at GET requests carrying a body — a "fat GET" — being accepted by the backend. HTTP semantics technically permit it even though it's unusual, and some backends will read and act on a GET body while caches treat GET requests as bodiless for keying purposes entirely. I intercepted the /js/geolocate.js?callback=setCountryCookie request and added a body parameter directly:
GET /js/geolocate.js?callback=setCountryCookie HTTP/2
Host: 0aac009303d43942805717aa00500062.web-security-academy.net
callback=teto
teto({"country":"United Kingdom"});
The backend read callback from the request body and let it override the query string value. The cache stored this poisoned response under the same key as the normal request — because the request body isn't part of the cache key at all. The query string still shows callback=setCountryCookie, looking completely legitimate, but the backend's effective behavior was driven by the body value instead. That's the actual vulnerability: not the fat GET itself, but the body being entirely unkeyed.
The injection technique from here is the same JSONP callback exploitation as the parameter cloaking lab — the novelty is purely in where the unkeyed input lives. Swapping in the real payload:
GET /js/geolocate.js?callback=setCountryCookie HTTP/2
Host: 0aac009303d43942805717aa00500062.web-security-academy.net
callback=alert(1)
That response got cached. Every subsequent load of / pulled in the poisoned geolocate.js resource and executed alert(1).
Lab solved :P