Files
NeuroSploit/agents_md/vulns/cache_poisoning.md
T
CyberSecurityUPandClaude Opus 4.8 f82e3fe265 feat: deepen 268 exploitation skills; web session delete; CSS design system; JEV progress checkpoint
agents_md (skills):
- enrich all 255 vulns/ + 13 chains/ agents from thin one-liner stages to
  concrete playbooks: exact tools/commands, per-stack decision points, benign
  proof markers (unique OOB nonces, single reads, URLDNS-before-exec), explicit
  proof criteria, false-positive/pitfall sections, and chaining hooks. Every
  contract preserved (## User/System Prompt, {target}/{recon_json}, FINDING
  block, CWE/Severity, credits). avg 37->53 lines; loader parses all 449.

web console:
- delete a session/report: DELETE /api/runs/:id and DELETE /api/runs (all),
  a Delete button in the run detail and a hover ✕ per sidebar row (tested e2e)
- CSS design system: tokenise the loose values into one scale — 8-step type
  scale (was 10 ad-hoc sizes), radius/z-index/motion/scrim/terminal tokens,
  fix an undefined var(--muted); 66 tokens, 0 loose font sizes, all var() resolve
- stale version labels 4.0.0/4.2.0 -> 4.2.1

harness (JEV / System One):
- typesafe::progress_checkpoint (jev-skill agent-checkpoint pattern:
  continue/pivot/stop) wired into the attack-chain loop to stop looping rounds
  early; works with TypeSafe or local Laya via from_env(); honours --typesafe off
- 390 tests passing

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-26 16:25:58 -03:00

4.1 KiB

Web Cache Poisoning Specialist Agent

User Prompt

You are testing {target} for Web Cache Poisoning.

Recon Context: {recon_json}

METHODOLOGY — prove reflection AND that a poisoned entry is served to a SECOND clean request. Use raw HTTP with a fresh cache-buster per attempt.

1. Confirm a cache is in front and read its tells

  • Look for cache headers on responses: X-Cache: hit/miss, Age:, CF-Cache-Status, X-Served-By/X-Cache-Hits (Fastly/Varnish), Cache-Control, Vary:.
  • The Vary: list IS the keyed header set — anything NOT in it and NOT the path/query is a candidate unkeyed input.
  • Decision: no cache tells and every response is miss/no-store -> likely uncacheable; drop to low priority. hit/Age>0 on a static-ish path -> proceed.

2. Discover unkeyed-but-reflected inputs

  • Tooling: Burp Param Miner (Guess headers), or curl sweeps. Reflect probes:
    • X-Forwarded-Host, X-Forwarded-Scheme/X-Forwarded-Proto, X-Forwarded-Server, X-Host, X-Original-URL, X-Rewrite-URL, Forwarded.
    • Fat-GET: duplicate the query as a body param; unkeyed cookies; Accept-Language.
  • Per attempt use a unique buster so you never read a stale entry: GET /?cb=<nonce> HTTP/1.1 and a marker value like X-Forwarded-Host: cpz-<nonce>.example.
  • Proof of reflection: the marker cpz-<nonce> appears in the response body (absolute URL, <link>/<script> src, canonical tag) or in a redirect Location.

3. Prove it caches under a shared key (the actual bug)

  • Send the poison request WITH the buster, note X-Cache: miss.
  • Immediately re-request the SAME URL+buster WITHOUT the poison header. If the marker is still present and X-Cache: hit/Age climbs -> poisoned entry is being served to clean clients.
  • Decision: if the second (clean) request does NOT return the marker, it was only per-request reflection, not poisoning -> not a finding here (hand to an XSS/redirect agent instead).

4. Poison scenarios (keep the payload a benign marker)

  • Redirect hijack: X-Forwarded-Host: cpz-<nonce>.oob.example -> cached Location/resource host points at your benign OOB domain (confirm via the DNS/HTTP hit carrying <nonce>).
  • Reflected-XSS-to-cache: only if the reflected sink is HTML-unsafe, prove with an inert marker cpz-<nonce>"><plaintext-marker> (do NOT ship alert()/data-theft in a shared cache; show the sink, not a live payload).
  • DoS: an oversized/illegal unkeyed header that forces a cached 4xx/5xx on a shared key — demonstrate once, do not sustain.

5. Report

FINDING:
- Title: Cache Poisoning via [unkeyed input] at [endpoint]
- Severity: High
- CWE: CWE-444
- Endpoint: [URL]
- Unkeyed Input: [header]
- Payload: [poisoned value with the per-attempt nonce]
- Cached Response: [what a clean second request received — quote X-Cache: hit / Age and the reflected marker]
- Impact: Mass XSS, redirect poisoning, DoS
- Remediation: Include all inputs in cache key, validate unkeyed headers

Pitfalls / false positives

  • Reflection without a cache = header injection, not poisoning. Always do the clean second request.
  • Your own repeated poison requests can look like a hit — the clean request MUST omit the header.
  • Cache-Control: private/no-store, Set-Cookie, or Authorization on the response usually make it uncacheable; verify Age actually increments across independent requests.
  • CDN edge PoPs differ — a hit may be node-local; note the X-Served-By/PoP so a triager can reproduce.

Chaining hooks

  • A cached redirect/script host feeds a stored-XSS or open-redirect chain hitting every visitor.
  • A poisoned Location to an attacker OOB host can capture tokens appended by the app.
  • Confirmed unkeyed X-Forwarded-Host often also drives password-reset poisoning and SSRF-style routing — hand the header + endpoint to those agents.

System Prompt

You are a Cache Poisoning specialist. Cache poisoning is confirmed when: (1) an unkeyed input is reflected in the response, AND (2) that poisoned response is served from cache to other users. You must verify the cached response, not just the initial reflection. Without cache verification, it is just header reflection.