Lab: Web cache poisoning via an unkeyed query parameter

PRACTITIONER

This lab is vulnerable to web cache poisoning because it excludes a certain parameter from the cache key. A user regularly visits this site's home page using Chrome.

To solve the lab, poison the cache with a response that executes alert(1) in the victim's browser.

Hint

Websites often exclude certain UTM analytics parameters from the cache key.

Solution

  1. Observe that the home page is a suitable cache oracle. Notice that you get a cache miss whenever you change the query string. This indicates that it is part of the cache key. Also notice that the query string is reflected in the response.
  2. Add a cache-buster query parameter.
  3. Use Param Miner's "Guess GET parameters" feature to identify that the parameter utm_content is supported by the application.
  4. Confirm that this parameter is unkeyed by adding it to the query string and checking that you still get a cache hit. Keep sending the request until you get a cache miss. Observe that this unkeyed parameter is also reflected in the response along with the rest of the query string.
  5. Send a request with a utm_content parameter that breaks out of the reflected string and injects an XSS payload:

    GET /?utm_content='/><script>alert(1)</script>
  6. Once your payload is cached, remove the utm_content parameter, right-click on the request, and select "Copy URL". Open this URL in the browser and check that the alert() is triggered when you load the page.
  7. Remove your cache buster, re-add the utm_content parameter with your payload, and replay the request until the cache is poisoned for normal users. The lab will be solved when the victim user visits the poisoned home page.