daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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)