I know that HTTP requests made by the site get the browser's localStorage for a site, and document.cookie is encrypted for HTTPs websites, but I'm still wondering the risk of storing sensitive information, because even if the hacker got the information, what could they do with it? They don't know the user.

And if the localStorage doesn't send information to the server (of course without encryption) how is it possible that someone can get the information over the internet?


1 Answer 1


There are several few confusions here, which I'll try to clear up for you.

  1. HTTP/HTTPS requests don't get access to storage at all. However, scripts running on a page get access to storage for the domain of the page they're running on (completely regardless of where that script comes from originally). The scripts can make requests, including using the info from localstorage. However, anything from localstorage that a script wants to have present on a request, the script has to explicitly put it there.
  2. Cookies, on the other hand, are sent automatically with requests, based on where the request is sent to (not where it's sent from)! The cookies are sent whether or not they are exposed to script (that is, they're sent even if they are marked "httponly", in which case they wouldn't show up to document.cookie for a script running on the destination domain). If a cookie is set for domain A (and not yet expired), there are only three common reasons it might not attend a request that is sent to A:
    • The cookie is marked "secure" but the request is over unsecured HTTP
    • The cookie is marked "samesite" but the request is coming from a totally different domain
    • The request is being made cross-origin using a script, and the script did not specify to send "credentials" with the request
    • (There are other less-common reasons, like the "path" property, but those are the most relevant three).
  3. Every aspect of an HTTPS request - not just the cookies but also all other headers, the entire body, and the entire URL except for the port, IP address, and maybe the domain name - is encrypted for HTTPS requests. That means if you stick a value from localstorage into an HTTPS request anywhere - as part of the URL path/query, in a header including a cookie, or in the body - it will be encrypted such that only the destination server can read it.
  4. Stealing data from localstorage generally requires injecting a script (a.k.a. "cross-site scripting" or XSS) into a page running on that origin (because "scripts on pages from that origin" are the only things that have access to localstorage). If my script is running on your site's page, I can almost certainly figure out who the user is! Either the page itself will tell me (e.g. through the presence of the user's name somewhere on the page, which a script can pull out of the DOM), or from a JWT or similar that I can read it out of or by using either the page's cookies, or using secrets in localstorage to make an authenticated request to the server in a way that reveals the user's identity (e.g. by requesting and parsing their profile page).

With that context established, let's talk about cookies vs. localstorage. There are a few other questions about that on this site, but it boils down to this:

  • For authentication tokens (JWTs, opaque session tokens, API keys, etc.) the advantage of using cookies is that they can be marked "httponly" in which case a malicious script injected into the page (XSS) can't steal them (though it can still use them, because they're added to every request to the relevant site automatically!). The downside of cookies is that they make you vulnerable to CSRF.
  • Using localstorage inverts these risks (no CSRF, but impossible to prevent stealing the token if XSS happens). There are other ways to prevent CSRF, though, and they're usually easier than preventing XSS (although there are ways to do that too, and of course "can't steal the token" doesn't mean XSS isn't a problem!).
  • For data that needs to be visible to client-side scripts, but not necessarily sent to the server on every request, use localstorage.
  • For data that needs to be sent to the server (or at least to some particular server) with every request but isn't used client-side, use a cookie. Scope its domain as tightly as possible, set the "secure" and "httponly" flags, and set the "samesite=lax" flag unless it needs to be sent on cross-site requests ("samesite" on a cookie holding the access token will prevent CSRF, at least from third-party domains, for modern browsers).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .