Insecure cookies are one of the top causes of session hijacking. Learn what Secure, HttpOnly, SameSite, and other cookie attributes do — with real examples for Express, Django, Laravel, and Next.js.
Anay Pandya
1,089 words
Anay Pandya
Founder of ZeriFlow · 10 years fullstack engineering · About the author
Key Takeaways
Cookies are the backbone of web authentication. Every time a user logs in, their session token is stored in a cookie. If that cookie is not properly secured, an attacker can steal it and impersonate the user. This is not a theoretical risk — session hijacking through insecure cookies remains one of the most common web attacks.
<div class="zf-stat-callout" style="background:#0d1117;border:1px solid rgba(16,185,129,0.25);border-left:3px solid #10b981;border-radius:4px;padding:16px 20px;margin:24px 0"> <p style="margin:0 0 4px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.15em;color:#10b981;font-family:monospace">ZeriFlow Data — 12,400+ sites analyzed</p> <p style="margin:0;font-size:13px;color:#e2e8f0;line-height:1.6;font-family:monospace">Our ZeriFlow's free scanner corpus of 12,400+ sites reveals 43% transmit session cookies without the HttpOnly flag, and 38% omit the Secure attribute — exposing session tokens to XSS and network interception.</p> </div>
Keep reading
Is your site actually secure?
Run a free check — 60 seconds
The good news is that securing cookies is straightforward. A handful of flags and attributes, properly configured, can eliminate entire categories of attacks. This guide covers every flag you need to know, explains what each one prevents, and shows you how to set them in the most popular web frameworks.
Before diving into the technical details, consider what an insecure session cookie enables:
Each of these attacks is preventable with the right cookie configuration.
The Secure flag ensures the cookie is only sent over HTTPS connections. Without it, the cookie will be transmitted in plain text over HTTP, where anyone on the same network can intercept it.
Set-Cookie: session=abc123; SecureWhen to use it: Always. Every cookie that contains sensitive data (especially session tokens) must have the Secure flag. There is no valid reason to send session cookies over HTTP in 2025.
Common mistake: Setting the Secure flag in production but not in local development, then forgetting to re-enable it. Use environment-based configuration to handle this automatically.
The HttpOnly flag prevents JavaScript from accessing the cookie via document.cookie. This is your primary defense against XSS-based session theft.
Set-Cookie: session=abc123; HttpOnlyWhy it matters: Even if an attacker finds an XSS vulnerability in your application, they cannot steal HttpOnly cookies. The cookie is still sent with requests, but it is invisible to client-side scripts.
When to skip it: Only for cookies that JavaScript legitimately needs to read, like theme preferences or UI state. Never skip HttpOnly for session tokens or authentication cookies.
The SameSite attribute controls whether the cookie is sent with cross-site requests. It is your primary defense against CSRF attacks.
Three values:
Set-Cookie: session=abc123; SameSite=LaxDefault behavior: Modern browsers default to SameSite=Lax if no attribute is set. However, explicitly setting it is best practice for clarity and compatibility.
The Domain attribute controls which domains receive the cookie. The Path attribute restricts the cookie to specific URL paths.
Set-Cookie: session=abc123; Domain=example.com; Path=/appBest practice: Set the Domain to your exact domain (not a wildcard that includes all subdomains) and the Path to the most specific path possible. This limits cookie exposure.
These attributes control how long the cookie persists. A session cookie (no Max-Age or Expires) is deleted when the browser closes. A persistent cookie lives for the specified duration.
Set-Cookie: session=abc123; Max-Age=3600Security guideline: Session tokens should have a short lifetime (1-4 hours for active sessions, 30 minutes for sensitive operations). Long-lived cookies increase the window for session hijacking.
app.use(session({
cookie: {
secure: true,
httpOnly: true,
sameSite: 'lax',
maxAge: 3600000,
domain: 'example.com',
path: '/'
}
}));SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
SESSION_COOKIE_AGE = 3600
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True// config/session.php
'secure' => true,
'http_only' => true,
'same_site' => 'lax',
'lifetime' => 60, // minutesres.setHeader('Set-Cookie', [
`session=${token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600`
]);Use this checklist for every cookie your application sets:
You can check your cookie configuration in several ways:
curl -I https://yoursite.com and inspect the Set-Cookie headersProper cookie flags are necessary but not sufficient. A complete cookie security strategy also includes:
Getting cookie security right is one of the highest-impact, lowest-effort improvements you can make. Set the flags, test them, and automate the verification with regular ZeriFlow scans.
<!-- zf-internal-links -->
Related resources
Website Vulnerability Scanner
Run a broader website security audit across headers, TLS, DNS, cookies, SEO, and disclosure checks.
Security Headers Checker
Check CSP, HSTS, X-Frame-Options, and other response headers.
SSL Checker
Review TLS certificate, HTTPS, and transport security signals.
DMARC Checker
Validate email authentication records for domain spoofing protection.
CSP Checker
Review Content-Security-Policy coverage and common gaps.
February 9, 2026
How to Get an A+ SSL Rating: Complete TLS Configuration Guide
Monitor your security score
Schedule recurring scans and catch regressions after deployments.