cookie-jar-overflow.md (4682B)
1 --- 2 title: "Cookie Jar Overflow" 3 section: "Web Pentesting" 4 sectionSlug: "pentesting-web" 5 sourcePath: "src/pentesting-web/hacking-with-cookies/cookie-jar-overflow.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/hacking-with-cookies/cookie-jar-overflow.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Cookie Jar Overflow 14 15 Cookie jar overflow abuses the fact that browsers cap how many cookies they keep for one site/jar. If you can run JavaScript in the victim origin (typically via XSS), you can keep creating cookies until older entries are evicted, then recreate the target cookie with attacker-controlled data.<sup>[[1]](#references)</sup> 16 17 The exact threshold and eviction policy are browser-dependent. The cookie specification sets minimum implementation capabilities, not a required eviction threshold, while Chromium currently uses a 180-cookie per-domain limit for each unpartitioned or partitioned jar. Do **not** hardcode `700` cookies and assume it will always work.<sup>[[2]](#references)[[4]](#references)</sup> 18 19 ```javascript 20 const attrs = "Path=/"; 21 let prev = -1; 22 23 for (let i = 0; i < 400; i++) { 24 document.cookie = `junk${i}=${"A".repeat(32)}; ${attrs}`; 25 const visible = document.cookie ? document.cookie.split(/; */).length : 0; 26 if (visible === prev) break; 27 prev = visible; 28 } 29 ``` 30 31 `document.cookie` only shows non-`HttpOnly` cookies, so in practice it is common to go a bit above the visible plateau to force eviction of hidden cookies as well. 32 33 ## Overwriting `HttpOnly` Cookies 34 35 This technique can still be used to **evict an `HttpOnly` cookie and then recreate it without `HttpOnly`**, but only if you can **match the original scope** (`name`, `Path`, and host/`Domain` behavior):<sup>[[1]](#references)</sup> 36 37 ```javascript 38 const targetScope = "Path=/app; Secure"; 39 40 for (let i = 0; i < 250; i++) { 41 document.cookie = `junk${i}=${crypto.randomUUID()}; ${targetScope}`; 42 } 43 44 document.cookie = `session=attacker-controlled; ${targetScope}`; 45 ``` 46 47 If the original cookie was set for a different `Path` or with a wider `Domain`, you may only create a sibling cookie and the server will receive both. At that point, ordering rules and server parsing decide which one wins, so check [cookie tossing](/hacktricks/pentesting-web/hacking-with-cookies/cookie-tossing) as well. 48 49 > [!CAUTION] 50 > This attack does **not** let JavaScript modify `HttpOnly` in place. The practical primitive is: **evict first, then create a new non-`HttpOnly` cookie with the same scope**. 51 > 52 > Check the original lab in [**this post**](https://www.sjoerdlangkemper.nl/2020/05/27/overwriting-httponly-cookies-from-javascript-using-cookie-jar-overflow/).<sup>[[1]](#references)</sup> 53 54 ## Reliability Notes 55 56 - **Eviction is not always "oldest cookie first"**. In Chromium the garbage collector is LRU-like and tends to preserve more valuable cookies longer, especially `Secure` and higher-priority cookies. A recently used session cookie is usually harder to evict than a stale low-priority one.<sup>[[2]](#references)</sup> 57 - **Profile the real cookie first**. Before overflowing, capture the original `Set-Cookie` in Burp/DevTools and note `Path`, `Domain`, `Priority`, prefixes, and whether the cookie is `Partitioned`. 58 - **Prefer first-party execution**. Modern browsers increasingly isolate or block third-party cookies. If the cookie is partitioned (`Partitioned` / CHIPS, or browser-enforced third-party partitioning), overflowing the jar of `cdn.example` while embedded in `siteA.com` will not evict the cookie that the same origin uses as a top-level site or while embedded in `siteB.com`.<sup>[[3]](#references)</sup> 59 - **Prefixed cookies reduce the impact**. `__Host-` constrains scope, while browsers that enforce the newer `__Http-` and `__Host-Http-` prefixes require the cookie to be set through `Set-Cookie` with `Secure` and `HttpOnly`. JavaScript may still be able to evict one of these cookies, but it cannot recreate a conforming same-named replacement through `document.cookie`.<sup>[[4]](#references)</sup> 60 61 ## References 62 63 - [1] [Overwriting HttpOnly cookies from JavaScript using cookie jar overflow](https://www.sjoerdlangkemper.nl/2020/05/27/overwriting-httponly-cookies-from-javascript-using-cookie-jar-overflow/) 64 - [2] [Chromium eviction notes](https://blog.yoav.ws/posts/how_chromium_cookies_get_evicted/) 65 - [3] [CHIPS / partitioned cookies](https://privacysandbox.google.com/cookies/chips) 66 - [4] [HTTP State Management Mechanism (draft RFC 6265bis)](https://httpwg.org/http-extensions/draft-ietf-httpbis-rfc6265bis.html)