FlawOpen

flawopen.com/Reference/JWT vs. HttpOnly Cookies

JWT in localStorage vs. HttpOnly cookies: which is safer?

Authentication Guide
Short answer

For many browser applications, a server-managed session delivered in an HttpOnly cookie is a strong default. JavaScript cannot read that cookie, which limits token extraction, but it does not neutralize XSS: injected same-origin code may still make authenticated requests and read data available to the page.

The Security Trade-Offs

Storage / transportXSS exposureCSRF behaviorRevocation
localStorage bearer tokenSame-origin JavaScript can read it; XSS can steal it or act as the user.Not attached automatically to cross-site requests; XSS and client-side CSRF remain risks.A self-contained JWT may remain valid until exp unless revocation is checked.
HttpOnly cookieJavaScript cannot read the cookie value; XSS can still issue authenticated requests.Sent automatically under cookie rules; SameSite is only one CSRF layer.An opaque server session can be invalidated server-side; a JWT cookie needs its own revocation policy.

Recommended Architecture

Separate token format, storage, and session state

A JWT is a token format; localStorage and cookies are browser storage and delivery mechanisms. A JWT can be stored in either. An opaque session identifier in a cookie usually points to server-managed session state. “JWT vs cookie” is not a direct either-or comparison.

What each choice changes

The browser does not automatically attach localStorage values to cross-site requests, but same-origin XSS can read a stored bearer token or act through the application. Cookies are attached automatically under browser rules; HttpOnly hides the value from JavaScript but does not stop injected code from using the signed-in page. SameSite=Lax is one CSRF layer, not a complete guarantee: safe-method top-level navigations and same-site requests still matter. Keep state changes off GET and use an appropriate CSRF defense, such as validated tokens and/or Origin checks.

Revocation depends on server state and token validation, not storage location. A server-side session can be invalidated by deleting its record. A self-contained JWT may remain accepted until expiry unless the verifier checks revocation; short lifetimes reduce but do not remove that window.

Practical starting point

Sources and further reading

See also Cross-Site Request Forgery (CSRF, CWE-352): How It Works and How to Prevent It — flawopen.com Next.js Server Actions CSRF: Origin and Proxy Safety Does SameSite=Strict Replace CSRF Tokens? CSRF Tokens for GET Requests: When Are They Needed?