Browse CTFs New CTF Sign in

Cookie Tampering (Static Artifact): Session Cookie Forgery and Authentication Bypass Techniques

crypto_tokens_protocols Difficulty 1–5 30 min certifiable

Theory

Why This Matters

Cookie security has been a recurring theme in web application breaches. The 2011 compromise of GitHub's cookie handling and the widely-exploited Flask debug-mode sessions (where the SECRET_KEY was left at its default or exposed in source code) demonstrated that cookies carrying serialised privilege data without integrity protection are direct privilege-escalation vectors. OWASP A07:2021 (Identification and Authentication Failures) explicitly cites improperly protected session tokens, and cookie tampering via Base64 decoding and role-field modification remains a staple CTF category precisely because it mirrors real-world vulnerabilities in production applications.

Core Concept

A session cookie is the primary bearer credential in web authentication: it is presented with every request and the server uses it to identify the authenticated user and their associated context. The security requirement for a session cookie is that its value must be opaque and tamper-evident — the client must not be able to read or modify the information encoded in it.

Base64-encoded JSON cookies violate opacity: the cookie value is simply base64({"user": "alice", "role": "user", "id": 42}). Base64 is a reversible encoding, not encryption or a MAC. An attacker who receives this cookie can decode it, modify the role field to admin, re-encode it, and submit the forged cookie. The server, if it trusts the decoded content without verification, grants administrative access.

Flask's default session cookie uses a slightly more sophisticated but still vulnerable pattern when the SECRET_KEY is weak or exposed: the cookie is structured as base64(header).base64(payload).HMAC-SHA1(key, payload). The signature provides integrity only if the key is secret and strong. If the key is the default dev, secret, changeme, or is committed to a public repository, an attacker can compute a valid HMAC for any forged payload using the same key — a direct analogy to the JWT HS256 weak-secret attack.

Cookie attribute analysis is a prerequisite step: the HttpOnly flag prevents JavaScript from reading the cookie (mitigating XSS-based theft); the Secure flag prevents transmission over plaintext HTTP (mitigating network interception); the SameSite attribute controls cross-site request inclusion (mitigating CSRF). Absence of these attributes is a reportable finding independent of whether the cookie value itself is tamper-resistant.

The algorithm:none analogy applies: just as a JWT implementation that accepts alg: none skips signature verification, a cookie implementation that decodes Base64 without verifying an HMAC accepts any client-crafted payload as authentic.

Technical Deep-Dive

Analysing a Base64 cookie:

# Cookie observed: session=eyJ1c2VyIjoiYWxpY2UiLCJyb2xlIjoidXNlciIsImlkIjo0Mn0=
echo "eyJ1c2VyIjoiYWxpY2UiLCJyb2xlIjoidXNlciIsImlkIjo0Mn0=" | base64 -d
# Output: {"user":"alice","role":"user","id":42}

# Forge an admin cookie
python3 -c '
import base64, json
payload = {"user": "alice", "role": "admin", "id": 42}
forged = base64.b64encode(json.dumps(payload).encode()).decode()
print(forged)
'
# Submit: Cookie: session=<forged_value>

Flask session cookie analysis with flask-unsign:

pip install flask-unsign

# Decode without verification
flask-unsign --decode --cookie "eyJ1c2VyIjoidGVzdCIsInJvbGUiOiJ1c2VyIn0.ZBk7Lg.abc123"

# Brute-force the SECRET_KEY
flask-unsign --unsign --cookie "<cookie_value>" 
             --wordlist /usr/share/wordlists/rockyou.txt 
             --no-literal-eval

# Sign a forged payload with the recovered key
flask-unsign --sign 
             --cookie '{"user": "admin", "role": "admin"}' 
             --secret 'dev'

Cookie attribute inspection in Burp:

HTTP/1.1 200 OK
Set-Cookie: session=eyJ1c2VyIjoiYWxpY2UifQ==; Path=/
-- Missing: HttpOnly, Secure, SameSite
-- HttpOnly absent → JavaScript can read document.cookie → XSS can steal it
-- Secure absent   → transmits over HTTP → network sniffing possible
-- SameSite absent → included in cross-site requests → CSRF risk

Security Assessment Methodology

  1. Collect all cookies — After login, open Burp Suite's Cookie jar or browser DevTools. List every cookie set, noting its name, value, expiry, domain, path, and attributes (HttpOnly, Secure, SameSite).
  2. Attempt Base64 decode — Pipe each cookie value through base64 -d. If the decoded output is valid JSON, XML, or a serialised object, the cookie is transparent and may be tamper-susceptible.
  3. Identify the signing mechanism — Count the dot-separated segments. One segment: pure encoding, no signature. Two segments: possible HMAC without header. Three segments: likely Flask or JWT format — identify which library is in use.
  4. Test with flask-unsign or jwt_tool — For Flask sessions, run flask-unsign --unsign against a wordlist. For JWT HS256, run jwt_tool -C -d /usr/share/wordlists/rockyou.txt. Confirm the key before forging.
  5. Forge and test the modified cookie — Once the structure is understood and any signing key is recovered (or absent), craft a cookie with elevated privileges and submit it in Burp Repeater to an authenticated endpoint. Document the before/after access level.
  6. Report all attribute deficiencies — Even if the cookie value is cryptographically sound, the absence of HttpOnly, Secure, or SameSite=Strict is a separate reportable finding affecting the confidentiality and integrity of the token.

Defensive Countermeasure — Store all privilege and identity data exclusively server-side keyed to an opaque, cryptographically random session ID stored in the cookie; if client-side session data is unavoidable, sign it with HMAC-SHA256 using a key of at least 256 bits generated by a CSPRNG and rotated on a scheduled basis — never with a static, committed, or default key.

Common Assessment Errors

  • Stopping at "it's Base64" — Recognising Base64 encoding is the start, not the end. Always decode, modify a privilege field, re-encode, and actually test whether the server accepts the tampered value.
  • Not testing with a non-admin account first — Forge the cookie to escalate from a regular user account to admin, not just from anonymous. This proves the application checks the cookie's role field rather than re-fetching from the database.
  • Missing the weak-key scenario — A cookie with an HMAC is not automatically secure. Test the key strength with a wordlist attack before concluding the signing is sufficient.
  • Ignoring serialisation formats — Some cookies use PHP serialisation, Python pickle, or Java serialisation rather than JSON. Tampering with these can lead to remote code execution as well as privilege escalation — recognise the format before modifying.
  • Not checking the HttpOnly flag programmatically — Manually reviewing cookie attributes in DevTools is error-prone. Use Burp's Scanner or a script to systematically verify all authentication cookies have HttpOnly and Secure set.
  • Forgetting SameSite=None implications — A cookie with SameSite=None and Secure is required for cross-origin use cases, but it reintroduces CSRF risk. Flag this configuration for review in the access control context.

NICE Framework Alignment

Code Knowledge/Skill/Task Statement How This Card Develops It
K0007 Knowledge of authentication, authorisation, and access control methods Explains the security requirements for session cookies and how transparent or weakly-signed cookies violate them
K0065 Knowledge of policy-based and role-based access controls Demonstrates direct privilege escalation by modifying role fields in tampered cookies
S0001 Skill in conducting vulnerability scans and recognising vulnerabilities in security systems Develops cookie analysis workflow using flask-unsign, base64 decoding, and Burp Suite
T0028 Conduct and/or support authorised penetration testing on enterprise network assets Provides a complete cookie security assessment methodology from attribute inspection through forged-cookie privilege escalation

Further Reading

  • OWASP Session Management Cheat Sheet — OWASP Foundation
  • Flask Security Considerations: SECRET_KEY — Pallets Project official documentation
  • The Web Application Hacker's Handbook, 2nd Edition — Stuttard & Pinto (Wiley)

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.