hunt-cache-poison
The hunt-cache-poison Claude Code skill identifies cache poisoning vulnerabilities in CDN-fronted applications and web caches. It provides structured attack surface signals (caching headers, URL patterns, dangerous headers like X-Forwarded-Host), reconnaissance methodology, and eight specific exploitation techniques derived from real bug bounty reports. Use this skill when targeting e-commerce platforms, SaaS applications, gaming update servers, or any infrastructure serving cached content where a single poisoned response could impact thousands of users simultaneously.
git clone --depth 1 https://github.com/elementalsouls/Claude-BugHunter /tmp/hunt-cache-poison && cp -r /tmp/hunt-cache-poison/skills/hunt-cache-poison ~/.claude/skills/hunt-cache-poisonSKILL.md
## Crown Jewel Targets Cache poisoning is high-value because a single poisoned cache entry can affect thousands or millions of victims simultaneously — one request, mass exploitation. Payout scales with blast radius. **Highest-value targets:** - **CDN-served assets** (cdn.shopify.com, cloudfront distributions, Fastly/Akamai edges) — poisoning these affects every visitor globally - **E-commerce platforms** with affiliate/referral flows (Shopify, WooCommerce storefronts) — session hijack or affiliate fraud potential - **Gaming platforms with update servers** (rockstargames updates.* domains) — DoS on update delivery = widespread client breakage - **Authentication endpoints** served through caches — leads to account takeover (the highest severity variant) - **Asset CDNs** (JS/CSS delivery) — XSS payload delivery at scale - **SaaS multi-tenant platforms** — one poisoned response bleeds into all tenants sharing a cache key **Asset types that pay most:** CDN hostnames, subdomain-per-tenant patterns, update/download servers, login/account pages cached incorrectly, affiliate link shorteners. --- ## Autonomous Testing Priority **Two distinct attacks live under this skill — target the simpler one first.** **Attack 1 — Password Reset Poisoning (Host header injection):** The app uses the `Host` header to construct the password reset link in the email. Inject an attacker-controlled hostname; the victim's reset email contains a link to your server. ``` POST /forgot-password Host: attacker.com X-Forwarded-Host: attacker.com X-Host: attacker.com email=victim@target.com Content-Type: application/x-www-form-urlencoded ``` Use a distinctive hostname you control or can identify in the response. **Proof:** the injected hostname appears in the response body (some apps reflect the generated reset link), or the action succeeds (2xx with a "reset email sent" message) after injection — confirming the poisoned link would be sent to the victim. Try multiple host headers — apps vary in which one they trust (`X-Forwarded-Host` is most common, but `Host` itself also works when the proxy passes it through). **Attack 2 — Web Cache Poisoning:** Inject the attacker-controlled hostname into `X-Forwarded-Host` on a GET request for a cacheable page. If the hostname is reflected in the response body AND the response gets cached, subsequent visitors receive the poisoned response. Check for cache signals in the response: `X-Cache: HIT`, `CF-Cache-Status: HIT`, `Age: <nonzero>`, or `Via: cloudfront/varnish/fastly`. **Proof for both:** injected value reflected in response body, or action completed successfully despite the manipulated header. --- ## Attack Surface Signals **URL patterns to look for:** - `cdn.`, `assets.`, `static.`, `updates.`, `downloads.` subdomains - URL path structures with extensions that look static: `/path/to/page.css`, `/account.php/nonexistent.jpg` - Affiliate/link shortener endpoints: `/link/`, `/go/`, `/ref/`, `/out/` - Paths that mix dynamic content with cacheable-looking URLs **Response headers that signal a cache:** ``` X-Cache: HIT / MISS X-Cache-Status: HIT CF-Cache-Status: HIT / MISS (Cloudflare) Age: <nonzero> Via: 1.1 varnish / cloudfront / fastly Cache-Control: public, max-age=... Surrogate-Control: max-age=... X-Served-By: cache-... ``` **JS/tech stack signals:** - Fastly, Varnish, Cloudfront, Akamai, Nginx proxy_cache in response headers - Shopify/Linkpop stacks with third-party integrations - Platforms using path-based routing without normalizing trailing segments - Servers that reflect unvalidated headers into responses (Host, X-Forwarded-Host, X-Original-URL) **Dangerous header candidates (unkeyed inputs):** ``` X-Forwarded-Host X-Host X-Forwarded-Scheme X-Original-URL X-Rewrite-URL Forwarded X-HTTP-Method-Override ``` --- ## Step-by-Step Hunting Methodology 1. **Map cache infrastructure.** Send a GET to the target and inspect response headers. Identify the caching layer (Cloudflare, Fastly, Varnish, Nginx). Note `Age`, `X-Cache`, `CF-Cache-Status` headers. 2. **Identify cache key components.** Send two identical requests — if `Age` increments, the response is cached. Vary headers one-by-one (e.g., add `X-Forwarded-Host`) to determine which headers are NOT included in the cache key (unkeyed). 3. **Test unkeyed header reflection.** Add `X-Forwarded-Host: evil.com` and check if the value appears in the response body (redirects, canonical links, CSP headers, JS src attributes, meta tags). Append a unique cache-busting query parameter (e.g. `?cb=<random>`) so the probe lands on a cache MISS under a throwaway key — this verifies reflection without prematurely storing a live poison entry under the real, victim-shared cache key. (Param Miner's "Guess headers" mode is the canonical Burp tool for discovering these unkeyed headers/parameters automatically.) 4. **Test URL path manipulation (Web Cache Deception).** Append fake static extensions to dynamic endpoints: - `GET /account/profile.css` - `GET /dashboard/settings.jpg` - `GET /affiliate-link/target.js` Check if the server returns dynamic content AND the cache stores it. 5. **Test for DoS via cache poisoning.** Send a request with a header that causes a 4xx/5xx error and check if that error response gets cached: - Malformed `Host` header - `X-Forwarded-Host` pointing to an invalid host - Oversized headers that trigger backend errors 6. **Confirm unkeyed parameter poisoning.** Try query parameter fatigue or HTTP parameter pollution: - `GET /page?utm_source="><script>alert(1)</script>` Check if the param is reflected and cached for clean requests to `/page`. 7. **Validate cache storage.** After sending a potentially poisoned request, immediately request the same URL WITHOUT the malicious header from a different IP or incognito session. If you receive the poisoned response — it's confirmed. 8. **Measure cache TTL.** Check `Cache-Control: max-age` and `Age` to understand how long the poison
Run autonomous hunt loop on a target — scope check → recon → rank surface → hunt → validate → report with configurable checkpoints. Usage: /autopilot target.com [--paranoid|--normal|--yolo]
Build an exploit chain — given bug A, finds B and C to combine for higher severity and payout. Knows common chain patterns: IDOR→ATO, SSRF→cloud metadata, XSS→ATO, open redirect→OAuth theft, S3→bundle→secret→OAuth. Usage: /chain
Active vulnerability hunting. Two-track dispatcher — asks Red Team vs WAPT, hands off to hunt-dispatch skill and sibling commands. Usage: /hunt target.com | /hunt *.target.com | /hunt targets.txt [--vuln-class X] [--source-code P] [--chrome]
On-demand intelligence fetch for a target — CVEs, disclosed reports, new features. Pulls NVD/GitHub-Advisory CVEs + bundled disclosed reports + hunt memory context. Usage: /intel target.com
Inspect or rotate the autopilot ledger JSONL files (findings.jsonl, negatives.jsonl). Caps file size and keeps N rotated backups so memory does not grow unbounded.
Pick up a previous hunt on a target — shows hunt history and untested surface from the autopilot ledger. Usage: /pickup target.com
Run full recon pipeline on a target — subdomain enum (Chaos API + subfinder), live host discovery (dnsx + httpx), URL crawl (katana + waybackurls + gau), gf pattern classification, nuclei scan. Outputs to recon/<target>/ directory. Usage: /recon target.com
Optional manual note on a target or the last confirmed finding. Capture is automatic during autopilot; this is for extra context. Usage: /remember