Cookie Tampering (Static Artifact): Session Cookie Forgery and Authentication Bypass Techniques
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
- 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).
- 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. - 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.
- Test with flask-unsign or jwt_tool — For Flask sessions, run
flask-unsign --unsignagainst a wordlist. For JWT HS256, runjwt_tool -C -d /usr/share/wordlists/rockyou.txt. Confirm the key before forging. - 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.
- 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.