Skip to content

Commit b34261a

Browse files
authored
Merge pull request #1523 from HackTricks-wiki/research_update_src_pentesting-web_xs-search_cookie-bomb-+-onerror-xs-leak_20251026_082306
Research Update Enhanced src/pentesting-web/xs-search/cookie...
2 parents b6b9c99 + 87238e8 commit b34261a

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

src/pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ The following script (from a public writeup) abuses a feature that lets the atta
7979
Why the popup (window.open)?
8080
- Modern browsers increasingly block third-party cookies. Opening a top-level window to the target makes cookies first‑party so Set-Cookie responses from the target will stick, enabling the cookie-bomb step even with third‑party cookie restrictions.
8181

82+
2024–2025 notes on cookie availability
83+
- Chromium-based browsers still commonly send third‑party cookies unless the user or site opts out, but Safari and Firefox block most third‑party cookies by default. Plan for both: (1) use a first‑party cookie planting flow (window.open + auto-submit to a cookie-setting endpoint) and then (2) probe with a subresource that only succeeds when those cookies are sent. If third‑party cookies are blocked, move the probe into a same-site context (e.g., run the oracle in the popup via a same-site gadget and exfiltrate the boolean with postMessage or a beacon to your server).
84+
8285
Generic probing helper
8386
If you already have a way to set many cookies on the target origin (first-party), you can reuse this minimal oracle against any endpoint whose success/failure leads to different network outcomes (status/MIME/redirect):
8487

@@ -94,10 +97,44 @@ function probeError(url) {
9497
}
9598
```
9699

100+
Alternative tag oracle (stylesheet)
101+
```js
102+
function probeCSS(url) {
103+
return new Promise((resolve) => {
104+
const l = document.createElement('link');
105+
l.rel = 'stylesheet';
106+
l.href = url;
107+
l.onload = () => resolve(false);
108+
l.onerror = () => resolve(true);
109+
document.head.appendChild(l);
110+
});
111+
}
112+
```
113+
114+
Advanced: de Bruijn–based cookie packing (CTF-proven)
115+
- When the app lets you control large cookie values, you can pack guesses efficiently by appending a de Bruijn sequence to each probe. This keeps per‑probe overhead small while ensuring the heavy branch is consistently heavier only for the right prefix. Example generator for |Σ| symbols of length n (fits in a cookie value):
116+
```js
117+
const ALPH = '_{}0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
118+
function deBruijn(k, n, alphabet=ALPH){
119+
const a = Array(k * n).fill(0), seq=[];
120+
(function db(t,p){
121+
if(t>n){ if(n%p===0) for(let j=1;j<=p;j++) seq.push(a[j]); }
122+
else { a[t]=a[t-p]; db(t+1,p); for(let j=a[t-p]+1;j<k;j++){ a[t]=j; db(t+1,t);} }
123+
})(1,1);
124+
return seq.map(i=>alphabet[i]).join('');
125+
}
126+
```
127+
- Idea in practice: set multiple cookies whose values are prefix + deBruijn(k,n). Only when the tested prefix is correct does the server take the heavy path (e.g., extra redirect reflecting the long cookie or URL), which, combined with the cookie bloat, crosses limits and flips onerror. See a LA CTF 2024 public solver using this approach.
128+
97129
Tips to build the oracle
98130
- Force the “positive” state to be heavier: chain an extra redirect only when the predicate is true, or make the redirect URL reflect unbounded user input so it grows with the guessed prefix.
99131
- Inflate headers: repeat cookie bombing until a consistent error is observed on the “heavy” path. Servers commonly cap header size and will fail sooner when many cookies are present.
100132
- Stabilize: fire multiple parallel cookie set operations and probe repeatedly to average out timing and caching noise.
133+
- Bust caches and avoid pooling artifacts: add a random `#fragment` or `?r=` to probe URLs, and prefer distinct window names when using window.open loops.
134+
- Alternate subresources: if `<script>` is filtered, try `<link rel=stylesheet>` or `<img>`. The onload/onerror boolean is the oracle; content never needs to be parsed.
135+
136+
Common header/URL limits (useful thresholds)
137+
- Reverse proxies/CDNs and servers enforce different caps. As of October 2025, Cloudflare documents 128 KB total for request headers (and 16 KB URL) on the edge, so you may need more/larger cookies when targets sit behind it. Other stacks (e.g., Apache via LimitRequestFieldSize) are often closer to ~8 KB per header line and will hit errors earlier. Adjust bomb size accordingly. [Cloudflare docs show the 128 KB header limit.]
101138

102139
Related XS-Search tricks
103140
- URL length based oracles (no cookies needed) can be combined or used instead when you can force a very long request target:
@@ -127,4 +164,6 @@ Notes
127164
## References
128165
- XS-Leaks: Error Events (onerror/onload as an oracle): https://xsleaks.dev/docs/attacks/error-events/
129166
- MDN: 431 Request Header Fields Too Large (common with many cookies): https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431
167+
- LA CTF 2024 writeup note showing a de Bruijn cookie-bomb oracle: https://gist.github.com/arkark/5787676037003362131f30ca7c753627
168+
- Cloudflare edge limits (URLs 16 KB, request headers 128 KB): https://developers.cloudflare.com/fundamentals/reference/connection-limits/
130169
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)