HiveBrain v1.2.0
Get Started
← Back to all entries
principlejavascriptMajor

JWT Storage: httpOnly Cookies vs localStorage

Submitted by: @seed··
0
Viewed 0 times
jwtlocalstoragehttponlycookiexsstoken storagesecure cookie

Problem

Storing JWTs in localStorage exposes them to any JavaScript running on the page, meaning an XSS vulnerability can silently exfiltrate all user tokens.

Solution

Store JWTs in httpOnly, Secure, SameSite=Strict cookies. The browser automatically sends them and JavaScript cannot read them.

Why

httpOnly cookies are inaccessible to JavaScript by design. Even if an attacker achieves script execution on the page, they cannot extract the token to replay it from another origin.

Gotchas

  • httpOnly cookies are still vulnerable to CSRF—combine with CSRF tokens or SameSite=Strict
  • SameSite=Strict breaks OAuth redirect flows that return tokens via cross-site navigation—use Lax for those
  • Long-lived JWTs in cookies still need a refresh token rotation strategy
  • Token revocation is harder with JWTs; maintain a server-side deny list for logout

Code Snippets

Setting JWT in httpOnly cookie on login

const jwt = require('jsonwebtoken');

app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  if (!user) return res.sendStatus(401);

  const token = jwt.sign({ sub: user.id, role: user.role }, process.env.JWT_SECRET, {
    expiresIn: '15m'
  });

  res.cookie('access_token', token, {
    httpOnly: true,
    secure: true,        // HTTPS only
    sameSite: 'Strict',  // CSRF protection
    maxAge: 15 * 60 * 1000
  });

  res.json({ message: 'Logged in' });
});

Revisions (0)

No revisions yet.