RoastMyOpsec

Safety

Cookie Max-Age vs Session Cookies for Login Lifetime

August 19, 2022

Cookie Max-Age vs session cookies is how long the browser is asked to keep the cookie, not how well it is locked: omit Max-Age and Expires for a session cookie, or set Max-Age in seconds when you want a clock, knowing Chromium session restore can still revive a 'session' cookie after a restart. Auth cookies still need Secure, HttpOnly, and SameSite on the name that proves login. RoastMyOpsec grades those three flags on session-like Set-Cookie names on the landing response and does not fail a site for Max-Age versus a session cookie.

The practical difference

A session cookie is a Set-Cookie with no Max-Age and no Expires. The user agent keeps it until it considers the browsing session over. That is a browser policy, not a server-enforced logout, and session restore can make the cookie outlive 'I quit the app.'

Max-Age is a delta in seconds from when the cookie is stored. Expires is an absolute date. If both are present, Max-Age wins. Zero or negative Max-Age is how you delete a cookie you already set, matching name, Path, and Domain. Neither attribute replaces HttpOnly, Secure, or SameSite, and neither stops a stolen cookie from working until the server session is revoked.

How to choose based on what you shipped

Pick lifetime from the product, then lock the cookie. Short-lived auth with refresh (minutes to a day of Max-Age) fits most public logins. A session cookie fits 'stay signed in only while this browser is open' — if you accept restore. Preference cookies can live longer; they should not be the login.

Do not use a year-long Max-Age on a session-shaped name to skip logout design. Server-side expiry and rotation still matter. Prefixes (__Host- / __Secure-) and Path=/ are separate contracts.

OptionWhen it winsWatch-outTakeaway
Session cookie (no Max-Age/Expires)You want the jar empty after a real browser quitSession restore can keep it; not a security flagFine for 'this sitting' if the server still expires sessions
Max-Age in secondsYou want a known clock and easier clock-skew behavior than ExpiresHuge Max-Age is a stolen-cookie window, not a featureDefault for new auth cookies with refresh
Expires dateLegacy stacks that only speak ExpiresServer/client clock skew; Max-Age overrides it if both are setPrefer Max-Age when you can
Max-Age=0 on logoutYou must drop this name nowPath/Domain mismatch leaves a twin cookie aliveMatch the original setter; still revoke the server session

When a session cookie still wins

A session cookie still wins on a kiosk-style or shared-device flow where you do not want a calendar reminder sitting in the jar after quit — as long as you also expire the server session and you accept restore. It does not win as a substitute for HttpOnly on an XSS-prone marketing origin.

Persistent Max-Age wins when users expect to come back tomorrow without a full login, or when you rotate refresh tokens on a clock. Keep the lifetime honest in your privacy copy. A public roast of the homepage often never sees the login Set-Cookie at all.

Common mistakes

The first mistake is treating a session cookie as automatically safer than Max-Age.

The second mistake is a 400-day auth Max-Age because the browser cap exists, not because the account should live that long in the jar.

The third mistake is deleting with Max-Age=0 on Path=/ while the original cookie was Path=/app.

What a URL roast can prove

Paste a URL you own into RoastMyOpsec for a free read of landing headers, HTTPS scheme, session-like cookie flags, sensitive paths, and public JavaScript secrets. Cookie grading is Secure, HttpOnly, and SameSite on names that look like session, auth, token, jwt, or sid — not Max-Age versus session as a standalone F, not cookie Priority, and not a login walkthrough. No Set-Cookie on the homepage is an info result, not a pass on logout hygiene. The scan does not score GPC, does not submit HSTS preload, and does not run exploit payloads.

Free audit the URL you own

RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.

Free audit now

FAQ

Is a session cookie more secure than Max-Age?
No. Lifetime and flags are different jobs. Session cookies can persist across restore. Set Secure, HttpOnly, and SameSite either way, and expire the server session on logout.
Does RoastMyOpsec fail missing Max-Age on auth cookies?
No. Max-Age versus a session cookie is not a standalone fail. The free cookie check looks for Secure, HttpOnly, and SameSite on session-like names on the audited response.
Should login cookies use Max-Age or stay session cookies?
Use Max-Age when you want a known lifetime and refresh. Use a session cookie when you truly want browser-session semantics and accept restore. Do not pick either to skip HttpOnly.

Sources

Related guides