Session cookies without the Secure, HttpOnly, and SameSite flags are the most common entry point for session hijacking. Dropping HttpOnly makes the cookie readable by any JavaScript on your page — a single XSS flaw anywhere on the domain hands an attacker every active session. Dropping Secure lets the cookie travel over unencrypted HTTP connections, where network attackers can intercept it. Missing SameSite exposes the session to CSRF attacks. Together these flags implement the three-sided defense OWASP A07 (Identification & Authentication Failures) and NIST 800-63B expect as a baseline for any session credential.
High because missing any one of these three flags creates a direct, exploitable path to session token theft and full account takeover.
Set all three flags explicitly in your auth library config rather than relying on defaults. In NextAuth, override the cookie options block:
// src/app/api/auth/[...nextauth]/route.ts
export const authOptions = {
cookies: {
sessionToken: {
options: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
path: '/'
}
}
}
}
For Supabase, use @supabase/ssr — it handles all three flags correctly. For any custom Set-Cookie header, append ; HttpOnly; Secure; SameSite=Lax before every response.
ID: saas-authentication.session-management.session-tokens-secure
Severity: high
What to look for: Examine auth/session configuration for cookie settings. Check auth library config (next-auth cookie options, Supabase cookie config, clerk config, lucia session config), middleware that sets cookies, and any manual Set-Cookie usage. Look for secure: true, httpOnly: true, and sameSite: 'lax' or 'strict' flags on the session/auth token cookie specifically. Count every cookie set by the application and enumerate each with its flags (HttpOnly, Secure, SameSite, Path). Classify as correctly configured or misconfigured. Before evaluating, extract and quote the cookie configuration code — the Set-Cookie header or cookie options object — to verify flag settings.
Pass criteria: Session and auth cookies are configured with Secure, HttpOnly, and an explicit SameSite value of Lax or Strict. Libraries that set these by default in production (e.g., NextAuth.js, Clerk) count as passing when no explicit override disables them. Managed auth libraries (@supabase/ssr, NextAuth.js, Clerk, Auth0 SDK) that handle session cookie configuration by default satisfy this check — result is PASS, not SKIP. At least 1 implementation must be confirmed.
Fail criteria: Session cookies are set without Secure, without HttpOnly, or without a SameSite attribute; or an explicit override in config disables any of these flags. Do NOT pass if session tokens are stored in localStorage — HttpOnly cookies are the only acceptable storage mechanism for session credentials.
Skip (N/A) when: No authentication library is detected in package.json AND no session/cookie-setting code is found in the codebase. The presence of a managed auth library such as @supabase/ssr, NextAuth.js, Clerk, or an Auth0 SDK means authentication is in use and this check must be evaluated, not skipped.
Cross-reference: The login-csrf check verifies the complementary cross-site protection that works alongside secure cookie flags.
Detail on fail: Identify which flags are missing and in what file. Example: "NextAuth session cookie configured without httpOnly: true in auth options at src/app/api/auth/[...nextauth]/route.ts" or "Manual Set-Cookie in api/session missing Secure and SameSite flags".
Remediation: The Secure flag ensures cookies are only sent over HTTPS, preventing interception on unencrypted connections. HttpOnly prevents JavaScript from reading the cookie, blocking XSS-based session theft. SameSite=Lax prevents most CSRF attacks. All three should be set together:
// NextAuth example — explicit cookie config
export const authOptions = {
cookies: {
sessionToken: {
options: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
path: '/'
}
}
}
}
For Supabase, configure the cookie via the SSR client helper — it handles these flags correctly when using @supabase/ssr. For manual cookie setting, always include all three flags.