Cache Poisoning via URL discrepancies

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

This is a summary of the techniques proposed in the post https://portswigger.net/research/gotta-cache-em-all in order to perform cache poisoning attacks abusing discrepancies between cache proxies and web servers.

The goal of this attack is to make the cache server think that a static resource is being loaded so it caches it while the cache server stores as cache key part of the path but the web server responds resolving another path. The web server will resolve the real path which will be loading a dynamic page (which might store sensitive information about the user, a malicious payload like XSS or redirecting to lo load a JS file from the attackers website for example).

Delimiters

URL delimiters vary by framework and server, impacting how requests are routed and responses are handled. Some common origin delimiters are:

  • Semicolon: Used in Spring for matrix variables (e.g. /hello;var=a/world;var1=b;var2=c/hello/world).

  • Dot: Specifies response format in Ruby on Rails (e.g. /MyAccount.css/MyAccount)

  • Null Byte: Truncates paths in OpenLiteSpeed (e.g. /MyAccount%00aaa/MyAccount).

  • Newline Byte: Separates URL components in Nginx (e.g. /users/MyAccount%0aaaa/account/MyAccount).

Other specific delimiters might be found following this process:

  • Step 1: Identify non-cacheable requests and use them to monitor how URLs with potential delimiters are handled.

  • Step 2: Append random suffixes to paths and compare the server's response to determine if a character functions as a delimiter.

  • Step 3: Introduce potential delimiters before the random suffix to see if the response changes, indicating delimiter usage.

Normalization & Encodings

  • Purpose: URL parsers in both cache and origin servers normalize URLs to extract paths for endpoint mapping and cache keys.

  • Process: Identifies path delimiters, extracts and normalizes the path by decoding characters and removing dot-segments.

Encodings

Different HTTP servers and proxies like Nginx, Node, and CloudFront decode delimiters differently, leading to inconsistencies across CDNs and origin servers that could be exploited. For example, if the web server perform this transformation /myAccount%3Fparam/myAccount?param but the cache server keeps as key the path /myAccount%3Fparam, there is an inconsistency.

A way to check for these inconsistencies is to send requests URL encoding different chars after loading the path without any encoding and check if the encoded path response came from the cached response.

Dot segment

The path normalization where dots are involved is also very interesting for cache poisoning attacks. For example, /static/../home/index or /aaa..\home/index, some cache servers will cache these paths with themselves ad the keys while other might resolve the path and use /home/index as the cache key. Just like before, sending these kind of requests and checking if the response was gathered from the cache helps to identify if the response to /home/index is the response sent when those paths are requested.

Static Resources

Several cache servers will always cache a response if it's identified as static. This might be because:

  • The extension: Cloudflare will always cache files with the following extensions: 7z, csv, gif, midi, png, tif, zip, avi, doc, gz, mkv, ppt, tiff, zst, avif, docx, ico, mp3, pptx, ttf, apk, dmg, iso, mp4, ps, webm, bin, ejs, jar, ogg, rar, webp, bmp, eot, jpg, otf, svg, woff, bz2, eps, jpeg, pdf, svgz, woff2, class, exe, js, pict, swf, xls, css, flac, mid, pls, tar, xlsx

    • It's possible to force a cache storing a dynamic response by using a delimiter and a static extension like a request to /home$image.png will cache /home$image.png and the origin server will respond with /home

  • Well-known static directories: The following directories contains static files and therefore their response should be cached: /static, /assets, /wp-content, /media, /templates, /public, /shared

    • It's possible to force a cache storing a dynamic response by using a delimiter, a static directory and dots like: /home/..%2fstatic/something will cache /static/something and the response will be/home

    • Static dirs + dots: A request to /static/..%2Fhome or to /static/..%5Chome might be cached as is but the response might be /home

  • Static files: Some specific files are always cached like /robots.txt, /favicon.ico, and /index.html. Which can be abused like /home/..%2Frobots.txt where the cace might store /robots.txt and the origin server respond to /home.

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Last updated