An audit of an Express app’s cookie and session security focusing on JWT risks, missing revocation, CSRF and remediation patterns with concrete code fixes and prioritization.
This lesson demonstrates how to audit an Express application for cookie- and session-related weaknesses and provides concrete remediation patterns. The example focuses on JWT-based authentication (no server-side cookie sessions), highlights the security implications, and maps findings to prioritized fixes you can implement quickly.We ran an interactive analysis session (local assistant/REPL) to explore the repository and guide the audit. The session output looked like this:
Copy
/help for help, /status for your current setupcwd: /Users/jeremy/Repos/Claude Code Course/Express-login-demo> Try "refactor <filepath>"? for shortcuts
A shortened sample of the structured audit prompt used to direct the analysis:
Copy
• Update Todos ☐ Examine session configuration in server.js ☐ Analyze cookie security settings ☐ Check for CSRF protection implementation ☐ Review session storage configuration ☐ Examine route handlers for session security ☐ Create structured security findings report• Let me examine the codebase structure and analyze the session/cookie security implementation.• Read(server.js) └ Read 19 lines (ctrl+r to expand)• Read(package.json) └ Read 25 lines (ctrl+r to expand)• Search(pattern: "routes/**/*.js") └ Found 1 file (ctrl+r to expand)
Large or reusable prompts used for these audits are stored in a repository to avoid retyping long instructions each time.
Mitigates cross-site request forgery when cookies are used
Session storage
No in-memory store in prod, use Redis or DB, TTL cleanup
Durable and scalable revocation/invalidations
JWT-specific
Refresh tokens, blacklisting, secret strength
JWTs can be valid even after logout without revocation
The audit also produced a structured findings report with fields like Title, Severity, CWE, Evidence (file/line), Exploitability notes, and remediation snippets.
The app uses JWT-based authentication (no server-side cookie sessions), so many cookie-specific checks were N/A. However, JWTs introduce other risks that require operational controls.
Key issues discovered:
No server-side token revocation (no blacklisting).
No refresh token pattern — access tokens are long-lived or not rotated safely.
JWT secret management is weak or not validated (risk of brute-force or leaked secrets).
No CSRF middleware detected (relevant if cookies are introduced later).
No explicit guidance for secure client-side token storage (storing JWTs in localStorage is risky).
Example diagnostic notes:
No cookie usage found — Secure/HttpOnly/SameSite checks were marked N/A.
No CSRF middleware in server.js (server.js:1-19).
No refresh token implementation and no logout endpoint that invalidates tokens.
JWTs remain valid until expiry — no revocation mechanism in place.
Final (example) risk score: 8.5 / 10 (high). Immediate priorities: rotate JWT secret and add token blacklisting.
The report explicitly noted that many cookie checks were skipped due to JWT-only usage, but it stressed that any future introduction of cookies must include Secure, HttpOnly, and SameSite flags and CSRF protections. It also flagged missing logout/revocation endpoints and insecure secret handling.
Below are concrete, copy-paste-friendly code patterns you can adapt to your codebase. Keep your app structure and error handling in mind when integrating these.
Server-side session (cookie) configuration (only if you switch to cookie sessions)
const crypto = require('crypto');if (!process.env.JWT_SECRET || process.env.JWT_SECRET === 'your_jwt_secret_key_here') { throw new Error('JWT_SECRET must be set to a strong, random value');}if (process.env.JWT_SECRET.length < 32) { throw new Error('JWT_SECRET must be at least 32 characters long');}
Avoid storing access or refresh tokens in localStorage or any storage accessible to JavaScript. Prefer HttpOnly cookies for refresh tokens and keep access tokens short-lived and in memory. Storing tokens in localStorage increases your attack surface for XSS.
Guidance summary — secure token handling
Use HttpOnly, Secure, SameSite cookies for refresh tokens.
Keep access tokens short-lived (minutes) and refresh them via a secure refresh flow.
Store refresh tokens server-side (DB/Redis) or as HttpOnly cookies with rotation.
Validate JWT_SECRET at startup and rotate secrets on a regular schedule.