Course contentsShow
← Node.js
Lesson 1006 of 1,9809. Authentication and Identity ManagementFree lesson

Securing Client-Side Storage

Determine the safest browser storage APIs for handling sensitive tokens in JS-heavy apps.

In this lesson, you will learn how to select the safest browser storage mechanisms for your sensitive authentication tokens to minimize the risk of Cross-Site Scripting (XSS) attacks.

When building JS-heavy applications, the natural instinct is to store access_tokens in localStorage or sessionStorage for easy retrieval. However, these APIs are globally accessible to any JavaScript running on your page. If a malicious script (injected via an XSS vulnerability) executes, it can read your tokens immediately and exfiltrate them. Because your application code needs access to these tokens to attach them to API requests, this exposure is an inherent design risk.

The safest approach is to treat the browser as an untrusted environment by moving token handling to HttpOnly and Secure cookies.

Why Cookies Beat localStorage

When you set an HttpOnly cookie, the browser prevents client-side JavaScript from accessing the token directly. Even if an attacker successfully injects a script, they cannot use document.cookie to steal the session credential.

Here is how you would set this up on your Node.js backend:

// Example using Express.js
res.cookie('access_token', token, {
  httpOnly: true,    // Prevents JS access
  secure: true,      // Ensures delivery over HTTPS only
  sameSite: 'Strict', // Mitigates CSRF risks
  maxAge: 3600000    // 1 hour expiry
});

Handling the Trade-off

While HttpOnly cookies protect your tokens from theft, they introduce a challenge for your JS-heavy frontend: your client-side code can no longer "see" the token to attach it to an Authorization header. To bridge this, your frontend must rely on the browser automatically including the cookie in cross-origin requests. Ensure your API is configured to handle credentials: 'include' for fetch requests and that your CORS policy explicitly allows the domain, rather than using the wildcard *.

If your architecture strictly requires token visibility, you are essentially accepting the risk of XSS-based token theft. In such cases, use an in-memory variable to store the token, which—while volatile—is harder to exfiltrate than persistent localStorage entries.

Key Takeaway: Never store sensitive authentication tokens in localStorage or sessionStorage; always prefer HttpOnly, Secure cookies to render tokens invisible to client-side scripts.