TL;DR
Cookie security depends on proper attributes: HttpOnly prevents XSS access, Secure ensures HTTPS-only, SameSite prevents CSRF. Most session cookies should have all three. These prompts help you audit your cookies and set them up correctly.
Cookie Security Audit
Use this prompt to find every cookie your application sets and check its security attributes. Your AI will flag auth cookies missing HttpOnly, production cookies without Secure, and overly broad Domain scoping.
Audit Cookie Configuration
Audit all cookies my application sets for security issues.
For each cookie, check:
- HttpOnly: Is it set? (Required for auth cookies)
- Secure: Is it set? (Required for production)
- SameSite: What value? (Lax minimum for auth)
- Domain: Is it properly scoped?
- Path: Is it properly scoped?
- Max-Age/Expires: Appropriate lifetime?
Find all places cookies are set:
- res.cookie() calls
- Set-Cookie headers
- document.cookie assignments
- Framework session configuration
Flag issues:
- Session/auth cookies without HttpOnly
- Any cookie without Secure in production
- SameSite=None without Secure
- Overly broad Domain scope
- Very long expiration for session cookies
Secure Session Cookie
Copy this prompt to configure your session cookie with HttpOnly, Secure, and SameSite attributes. Your AI will generate framework-specific code with proper settings for both production HTTPS and local HTTP development.
Configure Session Cookie
Configure my session cookie with proper security attributes.
Framework: [Next.js/Express/Django]
Recommended settings: Set-Cookie: session=value; HttpOnly; Secure; SameSite=Lax; Path=/
Express example: res.cookie('session', sessionId, { httpOnly: true, // Not accessible via JavaScript secure: true, // HTTPS only sameSite: 'lax', // CSRF protection path: '/', // Available site-wide maxAge: 24 * 60 * 60 * 1000, // 24 hours // domain: omit unless needed for subdomains });
For development (HTTP localhost): secure: process.env.NODE_ENV === 'production'
Note: SameSite=Strict breaks OAuth flows SameSite=Lax is usually the right choice
HttpOnly is essential for auth cookies: Without it, any XSS on your site can steal session cookies. It's the difference between XSS being annoying and XSS being a full account takeover.
SameSite Attribute Guide
This prompt asks your AI to help you choose the right SameSite value for each of your cookies. You'll get a clear explanation of Strict, Lax, and None with concrete examples showing when each is appropriate.
SameSite Configuration
Choose the right SameSite value for my cookies.
SameSite options:
Strict:
- Cookie only sent for same-site requests
- Most secure but can break legitimate flows
- User clicking link from email won't be logged in
- Use for: high-security banking, admin panels
Lax (Recommended default):
- Sent for same-site + top-level navigation
- Good balance of security and usability
- User clicking link from email stays logged in
- Use for: most session cookies
None:
- Sent with all requests (cross-site too)
- Must be used with Secure
- Needed for: cross-site iframes, third-party contexts
- Use sparingly and only when required
Examples: // Standard session sameSite: 'lax'
// Admin session (extra security) sameSite: 'strict'
// Third-party widget that needs auth sameSite: 'none', secure: true
Leaving SameSite unset is not the same as setting it
Chrome treats a cookie with no SameSite attribute as Lax. That sounds like
you can skip the attribute and get the protection for free. You can't.
When Lax is applied as a default rather than written down, browsers use a
looser version of it: the cookie is still sent on cross-site POST requests
made within two minutes of being set. That two-minute window exists so old
login flows did not break overnight when the default changed. It is a
compatibility concession, and it is open on every cookie you forget to label.
Writing SameSite=Lax explicitly closes it. Same value, different behaviour,
and the audit prompt above will not flag the gap unless you ask it to, because
the cookie technically "is" Lax either way.
The default also varies by browser. Chromium applies Lax-by-default; not every engine does, and the two-minute POST carve-out is specific to the implicit case. A cookie that relies on the default is relying on each browser agreeing with Chrome. Set the attribute.
Cookie Lifetime Has a Hard Ceiling
The audit prompt asks whether your cookie lifetimes are appropriate. Here is the number it should be measured against: 400 days.
Since Chrome 104 (August 2022), any Max-Age or Expires value further out
than 400 days is clamped down to 400 days. The cookie is not rejected and no
error is logged, so a "remember me for 5 years" cookie looks like it worked and
quietly expires after thirteen months. Session cookies, the ones with no expiry
set at all, are unaffected: they still clear when the browsing session ends.
If you need a longer-lived login, refresh the cookie on each visit by setting it again with the same name rather than asking for a date the browser will ignore.
Why 400 and not 365? Chrome picked slightly over thirteen months so that a site someone visits once a year, on roughly the same date, still recognises them on the next visit.
Cookie Prefixes
Use this prompt to add __Secure- and __Host- prefixes to your cookies for browser-enforced security. Your AI will show you how to implement the strictest __Host- prefix, which prevents subdomain cookie injection attacks.
Use Cookie Prefixes
Use cookie prefixes for additional security enforcement.
Cookie prefixes tell browsers to require certain attributes:
__Secure- prefix:
- Cookie must have Secure attribute
- Must be set over HTTPS Set-Cookie: __Secure-session=value; Secure; ...
__Host- prefix (strictest):
- Must have Secure attribute
- Must NOT have Domain attribute
- Path must be /
- Prevents subdomain attacks Set-Cookie: __Host-session=value; Secure; Path=/
Using __Host- prefix: res.cookie('__Host-session', value, { httpOnly: true, secure: true, sameSite: 'lax', path: '/' // No domain attribute! });
Benefits:
- Browser enforces security even if code has bugs
- __Host- prevents subdomain cookie injection attacks
- Defense in depth
Pro tip: Test your cookies at https://securityheaders.com or in browser DevTools (Application > Cookies). You can see all attributes and quickly spot missing security flags.
Do You Still Need SameSite=None?
Short answer: yes, and it is no longer a temporary measure.
Google spent five years saying it would phase third-party cookies out of
Chrome. In April 2025 it stopped saying that. The Privacy Sandbox team
confirmed Chrome will keep its existing third-party cookie choice and will not
ship the standalone prompt that was supposed to replace it. So if your app
embeds an authenticated widget or runs inside someone else's iframe,
SameSite=None; Secure is the mechanism, and planning a migration off it is
work you do not need to do.
The catch is that Chrome is not the whole web. Safari and Firefox block
third-party cookies by default already, and no attribute you set changes that.
SameSite=None means "send this cross-site if the browser allows it", not
"make the browser allow it". If a cross-site feature has to work everywhere,
it needs a design that survives the cookie being dropped.
SameSite=None without Secure is not a weaker cookie, it is a rejected
one. Browsers refuse the whole Set-Cookie header. The usual symptom is a
login that silently never persists, with nothing in the server logs, because
the cookie was discarded on the client.
Why doesn't my cookie work in development?
Secure cookies only work over HTTPS. For localhost development, either use HTTPS (mkcert), or conditionally disable Secure in dev, but always enable it in production.
My OAuth login broke after adding SameSite. What do I do?
OAuth redirects are cross-site. Use SameSite=Lax (not Strict), which allows cookies on top-level navigations. If you authenticate inside an iframe, you need SameSite=None with Secure.
Is leaving SameSite unset the same as setting SameSite=Lax?
No. Chrome treats a cookie with no SameSite attribute as Lax, but it applies a more permissive version that still sends the cookie on POST requests made within two minutes of the cookie being set. Setting SameSite=Lax explicitly closes that window.
What is the longest a cookie can live?
400 days. Since Chrome 104 (August 2022), any Max-Age or Expires value beyond 400 days is silently clamped to 400 days rather than rejected. Session cookies with no expiry set are unaffected. For a longer-lived login, re-set the cookie on each visit.
Further Reading
Want to understand the vulnerability before fixing it? These guides explain what's happening and why.
- Cross-site scripting, the reason HttpOnly matters
- CSRF, the reason SameSite matters
- How to implement secure session management
Check Your Cookie Security
Scan your application for insecure cookie configuration.