CookieJar Lab - Lab Guide
Home Lab Docs Demo
Overview
This lab demonstrates a fundamental gap in web security: authentication protects the login, but not the session. Passwords, TOTP 2FA, and even Google OAuth all stop at the moment the server issues a session cookie. After that, the cookie IS the identity.
Prerequisites
- Docker and Docker Compose installed
- A TOTP authenticator app (Google Authenticator, Authy, 1Password, etc.)
- A modern web browser with DevTools (Chrome recommended)
Lab Exercises
Exercise 1: Understanding Session Cookies
Objective: See what a session cookie contains and how the browser stores it.
- Start the lab:
docker compose up - Open the vulnerable app (
http://localhost:3001orhttps://cookiejar.test:3001in HTTPS mode) - Register a user - scan the QR code with your authenticator
- Log in with username + password + TOTP code
- Open browser DevTools (F12) → Application → Cookies
- Find the
sessioncookie - notice:HttpOnlyis unchecked (false)SameSiteis NoneExpiresis 7 days from now
- Click “Cookie Vault” in the step bar
- Compare what you see in DevTools with what the Cookie Vault shows
Key takeaway: The session cookie is a JWT containing your full identity. JavaScript can read it because httpOnly is false.
Exercise 2: Cookie Theft via JavaScript
Objective: Demonstrate how infostealers read cookies.
- While logged in on the vulnerable app, open the browser console (F12 → Console)
- Type:
document.cookie - You’ll see the full session JWT - this is exactly what infostealer malware reads
- Now open the hardened app (
http://localhost:3002orhttps://cookiejar.test:3002) in a new tab - Log in and try the same:
document.cookie - Result: empty string - httpOnly prevents access
Key takeaway: httpOnly is the first line of defence against JavaScript-based cookie theft.
Exercise 3: Session Replay Attack
Objective: Impersonate a user using only their stolen session cookie.
- On the vulnerable app, go to Cookie Vault and click “Copy Cookie”
- Open the Attack Console (or open it in an incognito window for extra realism)
- Paste the token and click “Replay Session”
- Observe: full user profile returned, no password or 2FA required
- The banner confirms: “Authentication bypassed”
Key takeaway: A valid session token IS authentication. The server cannot tell the difference between the real user and an attacker holding the same token.
Exercise 4: Google OAuth - Same Vulnerability
Objective: Show that OAuth doesn’t protect the session.
- Log out of the vulnerable app
- Click “Sign in with Google” and pick any mock account
- After redirect, go to Cookie Vault
- Notice: the JWT payload says
authMethod: "google-oauth"and includes a mock access token - Copy this cookie and paste it into the Attack Console
- Same result - authentication bypassed
Key takeaway: Google OAuth protects the login flow (Google verified the user). But your app still issues its own session cookie, and that cookie is just as stealable.
Exercise 5: Hardened Defences
Objective: See each security control in action.
- Copy a token from the vulnerable app’s Cookie Vault
- Open the hardened app’s Attack Console (
/attack-console.htmlon the hardened app) - Paste the vulnerable app’s token and click “Attempt Replay”
- Read the defence-by-defence breakdown:
- HttpOnly: Cookie was never accessible to JS
- Token expiry: 15 minutes vs 7 days
- Server-side session: Session ID not found in hardened app’s store
- Device binding: IP/UA mismatch
- Now register and log in on the hardened app
- Try to copy the session cookie - you can’t (httpOnly)
- Check the Session Event Log from the dashboard - see your login event and any replay attempts
Exercise 6: Session Revocation
Objective: Compare logout behaviour.
- On the vulnerable app: log in, copy the session token, log out
- Paste the token into the Attack Console - it still works (JWT is self-contained, logout only cleared the browser cookie)
- On the hardened app: the server marks the session as inactive in the database
- Even if you somehow had the token, the server would reject it
Key takeaway: Without server-side session tracking, “logout” is cosmetic - the token lives on.
Exercise 7: Audit Trail (Bonus)
Objective: See anomaly detection in action.
- On the hardened app, log in and go to Dashboard
- Click “Session Event Log” - see the
session_createdevent - Go to Attack Console and attempt a replay with any token
- Go back to Session Event Log - see the replay attempt logged with IP, User-Agent, and timestamp
- In production, these logs would feed into a SIEM for automated alerting
Discussion Questions
- If httpOnly prevents JavaScript from reading cookies, how do real infostealers steal them?
- Answer: They read the browser’s cookie database file directly from disk - it’s an SQLite file at a known path.
- Does HTTPS (the
secureflag) prevent cookie theft by infostealers?- Answer: No. The
secureflag prevents the cookie from being sent over HTTP (protecting against network sniffing), but infostealers read the cookie from the filesystem, not from the network. This lab demonstrates this directly in HTTPS mode: the vulnerable app setssecure: truebuthttpOnly: false, sodocument.cookiestill returns the full JWT despite HTTPS being active.
- Answer: No. The
- What is Device-Bound Session Credentials (DBSC)?
- Answer: A Chrome proposal that binds session cookies to a device’s TPM, making them unexportable. Even if malware reads the cookie value, it can’t be used on another machine.
- Why are passkeys (FIDO2) considered more resistant to this attack?
- Answer: Passkeys involve a cryptographic challenge-response tied to the specific device and origin. However, they protect the authentication step - the session cookie issued afterward is still a potential target. The key difference is that passkeys can be combined with token binding to create a fully bound session.
- In a zero-trust architecture, how would continuous authentication help?
- Answer: Instead of trusting the session cookie for its entire lifetime, the server continuously evaluates risk signals (IP changes, behaviour anomalies, device posture) and can demand re-authentication or terminate the session mid-flight.
Further Reading
- OWASP Session Management Cheat Sheet
- Chrome Device-Bound Session Credentials
- NIST SP 800-63B: Authentication & Lifecycle Management
- Token Binding (RFC 8471)
- FIDO2/WebAuthn Specification
A CyberDesserts project - Learn Cybersecurity By Doing