Abusing HTTP Misconfigurations
Advanced Cache Poisoning Techniques
In the previous sections, we have discussed basic techniques for identifying and exploiting web cache poisoning vulnerabilities. In this section, we will discuss two advanced web cache poisoning techniques that exploit misconfigurations in the web server to make otherwise secure configurations vulnerable.
Fat GET
Fat GET requests are HTTP GET requests that contain a request body. Since GET parameters are by specification sent as part of the query string, it might be weird to think that GET requests can contain a request body. However, any HTTP request can contain a request body, no matter what the method is. In the case of a GET request, the message body has no meaning which is why it is never used. We can confirm this in the RFC 7231 which states in section 4.3.1:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing implementations to reject the request.
Therefore, a request body is explicitly allowed, however, it should not have any effect. Thus, the following two GET requests are semantically equivalent, as the body should be neglected on the second:
GET /index.php?param1=Hello¶m2=World HTTP/1.1
Host: fatget.wcp.htb
and
GET /index.php?param1=Hello¶m2=World HTTP/1.1
Host: fatget.wcp.htb
Content-Length: 10
param3=123
If the web server is misconfigured or implemented incorrectly, it may parse parameters from the request body of GET requests though, which can lead to web cache poisoning attack vectors that would otherwise be unexploitable.
Let's have a look at our example web application. It is the same web application from the previous section, however, this time the ref GET parameter is keyed so we cannot execute the same web cache poisoning attack as before. Let's investigate if the web server supports fat GET requests. To do so, we can send a request similar to the following:
GET /index.php?language=en HTTP/1.1
Host: fatget.wcp.htb
Content-Length: 11
language=de
The language GET parameter is set to English, so we would expect the page to display English text. However, upon inspection, the response contains German text. So the web server seems to support fat GET requests and even prefers the parameter sent in the request body over the actual GET parameter. Now we need to confirm if this creates a discrepancy between the web cache and the web server. To do so, we can send the following request:
GET /index.php?language=en HTTP/1.1
Host: fatget.wcp.htb
We should now get a cache hit and the web cache returns the German page although we set the language parameter to English. This means our first request poisoned the cache with our injected fat GET parameter, but the web cache correctly uses the GET parameter in the URL to determine the cache key. We can use this flaw in the web server to exploit web cache poisoning once again.
After confirming that the reflected XSS vulnerability in the ref parameter is still present, we can use web cache poisoning to escalate this into a stored XSS vulnerability that forces the admin user to reveal the flag for us, just like we did in the previous section. Since the ref parameter is now keyed, we need to set it in a fat GET request with the following request:
GET /index.php?language=de HTTP/1.1
Host: fatget.wcp.htb
Content-Length: 142
ref="><script>var xhr = new XMLHttpRequest();xhr.open('GET', '/admin.php?reveal_flag=1', true);xhr.withCredentials = true;xhr.send();</script>
This should poison the cache for us. We can confirm this by sending the following request. We can see that we get a cache hit and the response contains our poisoned payload:

After waiting for a while, the admin user should access the page, execute our injected XSS payload and reveal the flag for us.
Note: fat GET requests are typically a misconfiguration in the web server software, not in the web application itself.
Parameter Cloaking
Another type of misconfiguration that can lead to a setup being vulnerable to web cache poisoning is parameter cloaking. Just like with fat GET requests, the goal is to create a discrepancy between the web server and the web cache in a way that the web cache uses a different parameter for the cache key than the web server uses to serve the response. The idea is thus the same as with fat GET requests.
To exploit parameter cloaking, the web cache needs to parse parameters differently than the web server. In the following, we will have a look at a real-world vulnerability in the Python web framework Bottle which was disclosed under CVE-2020-28473. As we can see from the vulnerability description, Bottle allows a semicolon for separation between different URL parameters. As an example, let's consider a GET request to /test?a=1;b=2. Since Bottle treats the semicolon as a separation character, it sees two GET parameters: a with a value of 1 and b with a value of 2. The web cache on the other hand only sees one GET parameter a with a value of 1;b=2. Let's have a look at how we can exploit this to achieve web cache poisoning.
When starting the web application, we can see that it is the same web application we exploited with fat GET requests but ported to Python Bottle. We can apply the knowledge from the previous sections to determine the following key points:
- the parameters
language,content, andrefare keyed - the reflected XSS vulnerabilities in the parameters
contentandrefare still present
Now let's create a discrepancy between the web cache and web server by exploiting the vulnerability discussed above. To do so we need an unkeyed parameter. In this case, we can assume that the parameter a is unkeyed with the methodology discussed previously so we will be using that parameter. We can create a proof of concept with the following request:
GET /?language=en&a=b;language=de HTTP/1.1
Host: cloak.wcp.htb
The response displays the German text, although the request contains the parameter language=en. Let's investigate why this happens. The web cache sees two GET parameters: language with the value en and a with the value b;language=de. On the other hand, Bottle sees three parameters: language with the value en, a with the value b, and language with the value de. Since Bottle prefers the last occurrence of each parameter, the value de overrides the value for the language parameter. Thus, Bottle serves the response containing the German text. Since the parameter a is unkeyed, the web cache stores this response for the cache key language=en. We can send the following follow-up request to confirm that the cache was poisoned:
GET /?language=en HTTP/1.1
Host: cloak.wcp.htb
The response should now be a cache hit and contain the German text. Thus, we successfully poisoned the cache.
Note: To poison the cache with parameter cloaking we need to "hide" the cloaked parameter from the cache key by appending it to an unkeyed parameter.
Now let's build an XSS exploit that forces the admin user to reveal the flag for us, just like we did before. Since Bottle treats the semicolon as a separation character, we need to URL-encode all occurrences of the semicolon in our payload:
GET /?language=de&a=b;ref=%22%3E%3Cscript%3Evar%20xhr%20=%20new%20XMLHttpRequest()%3bxhr.open(%27GET%27,%20%27/admin?reveal_flag=1%27,%20true)%3bxhr.withCredentials%20=%20true%3bxhr.send()%3b%3C/script%3E HTTP/1.1
Host: cloak.wcp.htb
After sending this request and confirming our payload has been cached for the URL /?language=de, the admin should trigger our exploit and the flag should be revealed after a few seconds.
/ 1 spawns left
Questions
Answer the question(s) below to complete this Section and earn cubes!
Click here to spawn the target system!
Target:
Click here to spawn the target system!
-
fatget.wcp.htb -
cloak.wcp.htb
+10 Streak pts
+10 Streak pts
Table of Contents
Introduction to HTTP Misconfigurations
Introduction to HTTP MisconfigurationsWeb Cache Poisoning
Introduction to Web Cache Poisoning Identifying Unkeyed Parameters Web Cache Poisoning Attacks Advanced Cache Poisoning Techniques Tools & PreventionHost Header Attacks
Introduction to Host Header Attacks Authentication Bypass Password Reset Poisoning Web Cache Poisoning Bypassing Flawed Validation Host Header Attacks PreventionSession Puzzling
Introduction to Session Puzzling Weak Session IDs Common Session Variables (Auth Bypass) Premature Session Population (Auth Bypass) Common Session Variables (Account Takeover) Session Puzzling PreventionSkills Assessment
Skills Assessment - Easy Skills Assessment - HardMy Workstation
OFFLINE
/ 1 spawns left