Learn how fat GET requests enable web cache poisoning by exploiting mismatched cache key handling, and why this vulnerability can escalate into widespread XSS and cache-based attacks.
Disclaimer: The techniques described in this document are intended solely for ethical use and educational purposes. Unauthorized use of these methods outside approved environments is strictly prohibited, as it is illegal, unethical, and may lead to severe consequences.
It is crucial to act responsibly, comply with all applicable laws, and adhere to established ethical guidelines. Any activity that exploits security vulnerabilities or compromises the safety, privacy, or integrity of others is strictly forbidden.
Table of Contents
Summary of the Vulnerability
In this scenario, the application accepts GET
requests that contain a message body. While GET
requests are traditionally expected to be body-less, some servers and frameworks still allow them. The critical flaw lies in how the cache mechanism processes these requests: it ignores the body when generating the cache key.
This means that two GET
requests — one standard and one with a malicious body — are treated as identical by the cache. As a result, an attacker can inject harmful content into the response body, which gets cached and later served to unsuspecting users who load the same resource. In the lab setup, the attacker's objective is to poison the cache so that when a regular visitor loads the home page, a JavaScript payload (alert(1)
) is executed in the victim's browser.
Steps to Reproduce & Proof of Concept (PoC)
① Open the Lab
② Observe Requests in Burp HTTP History
When you load the home page (GET / HTTP/2
), you'll notice the response includes a reference to another script:
GET /js/geolocate.js?callback=setCountryCookie HTTP/2

This means we need to analyze both the homepage request and the geolocate.js
request. Send both of them to Repeater for further testing.
Please reference to this page as well : exploiting fat GET support.

③ Send Initial Requests in Repeater
Forward the homepage request in Repeater. Each time you do, the response includes the geolocate.js
script. Since this JavaScript file is pulled into the homepage, manipulating it is the key to poisoning the cache.

④ Inspect the JavaScript Request
Switch to the GET /js/geolocate.js?callback=setCountryCookie
request in Repeater. This is where we'll inject the payload. Because the lab accepts fat GET requests (GET with a body), we can supply parameters in the request body even though the method is GET
.
⑤ Inject Payload via Fat GET Body
Following the cache poisoning technique (parameter cloaking), add a malicious payload in the body while keeping the same parameter name.
Example body:
callback=alert(1)//

The cache key does not include the body, but the application still processes it — creating the mismatch we exploit.
⑥ Monitor Cache Behavior
Keep sending the modified geolocate.js
request until you see:
X-Cache: miss
This indicates the poisoned response is being stored in the cache.
⑦ Verify Poisoning on Homepage
Go back to the homepage request in Repeater. Send it until you see:
X-Cache: hit
Now refresh the browser. The cached geolocate.js
response is served, and the injected payload executes — triggering alert(1)
.


Impact
- Cross-Site Scripting (XSS) at Scale Injected scripts could execute in the browsers of all users served by the poisoned cache, turning a single exploit into a mass compromise.
- Malicious Distribution Poisoned responses could serve malicious scripts that load external resources, effectively turning a trusted website into a malware delivery mechanism.
📢 Enjoyed this post? Stay connected! If you found this article helpful or insightful, consider following me for more:
- 📖 Medium: bashoverflow.medium.com
- 🐦 Twitter / X: @_havij
- </> Github: havij13
🙏Your support is appreciated.