Merge pull request #1404 from HackTricks-wiki/update_Cache_Deception___CSPT__Turning_Non_Impactful_Find_20250914_012031

Cache Deception + CSPT Turning Non Impactful Findings into A...
This commit is contained in:
SirBroccoli 2025-09-30 14:18:47 +02:00 committed by GitHub
commit 438d959dd7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 111 additions and 0 deletions

View File

@ -294,6 +294,89 @@ Note that the **cache proxy** should be **configured** to **cache** files **base
Learn here about how to perform[ Cache Deceptions attacks abusing HTTP Request Smuggling](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception).
### 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 victims 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 victims token JSON under a public key.
- Anyone can then GET that same cache key without authentication and retrieve the victims 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..."}
```
- Static-looking suffix flips CDN to cacheable:
```
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 attaches auth header and allows traversal:
```js
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. Lure victim to a URL that injects dot-segments into the SPA path parameter, e.g.:
- [https://example.com/user?userId=../../../v1/token.css](https://example.com/user?userId=../../../v1/token.css)
2. The SPA issues an authenticated fetch to:
- [https://api.example.com/v1/users/info/../../../v1/token.css](https://api.example.com/v1/users/info/../../../v1/token.css)
3. Browser normalization resolves it to:
- [https://api.example.com/v1/token.css](https://api.example.com/v1/token.css)
4. The CDN treats .css as a static asset and caches the JSON with Cache-Control: public, max-age=...
5. Public retrieval: anyone can then GET https://api.example.com/v1/token.css and obtain the cached token JSON.
Preconditions
- 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.
Validation checklist
- 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**](https://github.com/xhzeem/toxicache): Golang scanner to find web cache poisoning vulnerabilities in a list of URLs and test multiple injection techniques.
@ -309,6 +392,11 @@ Learn here about how to perform[ Cache Deceptions attacks abusing HTTP Request S
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
- [Burp Proxy Match & Replace](https://portswigger.net/burp/documentation/desktop/tools/proxy/match-and-replace)
- [watchTowr Labs Sitecore XP cache poisoning → RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/)
- [Cache Deception + CSPT: Turning Non Impactful Findings into Account Takeover](https://zere.es/posts/cache-deception-cspt-account-takeover/)
- [CSPT overview by Matan Berson](https://matanber.com/blog/cspt-levels/)
- [CSPT presentation by Maxence Schmitt](https://www.youtube.com/watch?v=O1ZN_OCfNzg)
- [PortSwigger: Web Cache Deception](https://portswigger.net/web-security/web-cache-deception)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -13,6 +13,29 @@ A client side path traversal occurs when you can **manipulate the path of a URL*
- Check this [**CSPT playground**](https://github.com/doyensec/CSPTPlayground) to try the technique.
- Check [**this tutorial**](https://blog.doyensec.com/2024/12/03/cspt-with-eval-villain.html) on how to use the browser extension in the playground.
## CSPT-assisted web cache poisoning/deception
CSPT can be chained with extension-based CDN caching to exfiltrate sensitive JSON leaked by authenticated API calls:
- A frontend concatenates user-controlled input into an API path and attaches authentication headers in fetch/XHR.
- By injecting dot-segments (../) you can retarget the authenticated request to a different endpoint on the same origin.
- If that endpoint (or a path variant with a static-looking suffix like .css) is cached by the CDN without varying on auth headers, the victims authenticated response can be stored under a public cache key and retrieved by anyone.
Quick recipe:
1) Find SPA code building API URLs from path parameters while sending auth headers.
2) Identify sensitive endpoints and test static suffixes (.css, .js, .jpg, .json) to see if the CDN flips to Cache-Control: public/max-age and X-Cache: Hit while returning JSON.
3) Lure the victim to a URL that injects traversal into the SPA parameter so the authenticated fetch hits the cacheable path variant (for example, ../../../v1/token.css).
4) Read back the same URL anonymously to obtain the cached secret (token → ATO).
See details and mitigations in the Cache Deception page: [Cache Poisoning and Cache Deception](cache-deception/).
## References
- [Cache Deception + CSPT: Turning Non Impactful Findings into Account Takeover](https://zere.es/posts/cache-deception-cspt-account-takeover/)
- [CSPT overview by Matan Berson](https://matanber.com/blog/cspt-levels/)
- [PortSwigger: Web Cache Deception](https://portswigger.net/web-security/web-cache-deception)
{{#include ../banners/hacktricks-training.md}}