How to Secure Cookies
Cookies store session tokens and user preferences. Insecure cookies can be stolen via XSS, intercepted over HTTP, or abused in CSRF attacks. This guide covers every cookie security attribute and when to use each one.
Find security issues automatically before attackers do.
Follow These Steps
Always set the HttpOnly flag on session cookies
HttpOnly prevents JavaScript from reading the cookie, blocking XSS-based session theft.
res.cookie('session', token, {
httpOnly: true // Cannot be accessed by document.cookie
})Only omit HttpOnly if JavaScript genuinely needs to read the cookie (rare). CSRF tokens may need to be readable by JS.
Always set the Secure flag
Secure ensures the cookie is only sent over HTTPS connections.
res.cookie('session', token, {
httpOnly: true,
secure: true // Only sent over HTTPS
})Set SameSite to Lax or Strict
SameSite prevents the cookie from being sent with cross-origin requests, mitigating CSRF.
// Lax: sent with top-level navigations, blocked for cross-origin POSTs
// Use for most applications (works with OAuth redirects)
res.cookie('session', token, {
httpOnly: true,
secure: true,
sameSite: 'lax'
})
// Strict: never sent with cross-origin requests
// Use only if your app never uses OAuth or external redirects
res.cookie('session', token, {
httpOnly: true,
secure: true,
sameSite: 'strict'
})Set appropriate expiration
Session cookies should have reasonable lifetimes. Shorter is more secure.
res.cookie('session', token, {
httpOnly: true,
secure: true,
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000, // 24 hours
path: '/' // Available on all paths
})Use the __Host- prefix for extra security
The __Host- prefix forces the cookie to be Secure, have no Domain, and have Path=/.
res.cookie('__Host-session', token, {
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/'
// Cannot set domain with __Host- prefix
})Verify cookie configuration
Check your cookies in browser DevTools.
// DevTools > Application > Cookies
// Verify each cookie has:
// - HttpOnly: checked (for session cookies)
// - Secure: checked
// - SameSite: Lax or Strict
// - Reasonable expirationWhat You'll Achieve
All cookies are configured with HttpOnly, Secure, SameSite, and appropriate expiration. Session cookies are protected against XSS theft, interception, and CSRF abuse.
Common Mistakes to Avoid
Mistake
Not setting HttpOnly on session cookies
Fix
Without HttpOnly, XSS attacks can steal session tokens via document.cookie. Always set HttpOnly for session and authentication cookies.
Mistake
Using SameSite=Strict with OAuth
Fix
Strict blocks the cookie during OAuth redirect flows. Use Lax for applications that use OAuth, magic links, or any external redirects.
Mistake
Setting SameSite=None without Secure
Fix
SameSite=None requires the Secure flag. Browsers reject the cookie without it.
Frequently Asked Questions
Should I use HttpOnly on all cookies?
Use HttpOnly on session and authentication cookies. Cookies that JavaScript needs to read (like CSRF tokens or UI preferences) cannot use HttpOnly.
What is the difference between SameSite Lax and Strict?
Lax sends the cookie with top-level navigations (clicking links) but blocks it for cross-origin POST requests. Strict blocks the cookie for all cross-origin requests, which can break OAuth flows.
Ready to Secure Your App?
VAS automatically scans your deployed app for the security issues covered in this guide. Get actionable results in minutes.
Start Security Scan