Insecure Cookies Explained

Share

TL;DR

Session cookies without proper flags can be stolen via XSS (missing HttpOnly), network attacks (missing Secure), or CSRF (missing SameSite). Always set all three flags on authentication cookies: HttpOnly, Secure, and SameSite=Lax or Strict.

FlagWhat It DoesPrevents
HttpOnlyCookie not accessible via JavaScriptXSS cookie theft
SecureCookie only sent over HTTPSNetwork interception
SameSite=StrictCookie only sent on same-site requestsCSRF attacks
SameSite=LaxSent on same-site + top-level navigationMost CSRF attacks

The Problem

Insecure cookie setting
// Missing all security flags!
res.cookie('session', token);

// What this actually means:
// - JavaScript can read it (XSS can steal it)
// - Sent over HTTP (can be intercepted)
// - Sent on cross-site requests (CSRF possible)

The Fix

Secure cookie settings
// Express example
res.cookie('session', token, {
  httpOnly: true,   // Can't be accessed by JavaScript
  secure: true,     // Only sent over HTTPS
  sameSite: 'lax',  // Not sent on cross-site requests
  maxAge: 7 * 24 * 60 * 60 * 1000,  // 7 days
  path: '/'
});

// Next.js API route
import { cookies } from 'next/headers';

cookies().set('session', token, {
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production',
  sameSite: 'lax',
  maxAge: 60 * 60 * 24 * 7
});

Should I use SameSite Strict or Lax?

Use Lax for most cases. Strict breaks legitimate flows like clicking links from emails. Lax allows cookies on top-level navigation while still blocking cross-site POST requests.

What about cookie prefixes like __Host-?

Cookie prefixes add extra security. __Host- requires Secure, no Domain, and Path=/. __Secure- requires the Secure flag. These prevent subdomain attacks.

Do I need Secure in development?

Localhost is usually exempted. Use secure: process.env.NODE_ENV === 'production' to apply the flag only in production.

Our scanner verifies your cookies have proper security flags.

Start Free Scan
Vulnerability Guides

Insecure Cookies Explained