Hacker News new | ask | show | jobs
by jkrejcha 46 days ago
A lot of times local storage is much less secure than using cookies. Cookies have about 20 years of infra built around it (HttpOnly, SameSite, Secure, etc). There's some weird parts about cookies, but local storage really shouldn't be used for anything security sensitive
2 comments

20 years of security:

sqlite3 cookies.sqlite 'SELECT name, value FROM moz_cookies WHERE isSecure AND isHttpOnly'

And that's a supposedly a master password protected browser. They can't even bother encrypting cookies. Don't be ridiculous.

If the attacker can already execute code as you unrestricted, then you've kinda already lost.

Local storage isn't any better in this regard

That's why I wouldn't say the below.

> A lot of times local storage is much less secure

Without XSS, local storage is actually more secure. You don't have worry 'did I set up this right' because there is nothing to set up and CSRF is impossible to execute.

If you're still paranoid about XSS, CSP is your friend. Also check isTrusted on events.

If you exclude all of the flaws of one implementation and include all of the flaws of another, then of course you can say one is better than the other. But that's not a fair comparison of implementations

CSRF has incredibly simple mitigations with cookies (SameSite=strict) and can even work across different path segments (although this tends to be uncommon) and has mitigations against XSS which local storage does not. XSS is bad in either case (CSPs aren't usually an effective mitigation for a variety of reasons[1]) but being able to outright steal the session token is worse than being able to use it in a potentially more limited context

[1]: Primarily that they're generally just not implemented and that a lot of web frameworks require incredibly loose CSPs up to and including unsafe-eval since they often need to dynamically load JS. In addition, this doesn't protect from supply chain attacks (JS that is injected as the result of it being loaded from another domain, like from a CDN for example).

> XSS which local storage does not [mitigate]

True. However it's not impossible to mitigate that: https://news.ycombinator.com/item?id=48563286

But arguably it's harder to do so.

> this doesn't protect from supply chain attacks

It's a separate attack vector. It's easily mitigated by having a one week back-off before upgrading. (and as I have said already, also affects binary executables)

> unsafe-eval

Technically speaking, nothing prevents you from shipping a JS-in-JS runtime that proxies objects and bypasses eval, which is just eval without eval.

> True. However it's not impossible to mitigate that: https://news.ycombinator.com/item?id=48563286

It's not a perfect mitigation for session stealing, isn't available in all cases, requires custom code to implement, and also can in some cases completely break sessions (unless they have another place where it's stored)

> It's a separate attack vector. It's easily mitigated by having a one week back-off before upgrading. (and as I have said already, also affects binary executables)

A separate attack vector for the same problem. Which is also not mitigated by dependency back-off. If you load a 3rd party script into your site, you're relying on that 3rd party not getting compromised.

For example, if I have a page

<script src="https://example.com/accel.js" />

and if "accel.js" gets maliciously replaced, it can read all of the data out of local storage. No updates on your end required.

Not really. Difficulty of the attack matters. If your attack chain is silently doing an sql query over 20 year stable database format, vs something that may involve extraction of a master key from some hardened process, or tricking the user to reveal the master password to you, odds of you raising alarm in some anti-malware software raise significantly, because now you're not just reading a file, but you're using some deubgging APIs, etc., that common software does not use.
The only difference between the cookie scenario and localstorage scenario here is that you're reading "storage/default/<domain>/ls/data.sqlite"

It's even conveniently grouped by domain

There's no magic hardening going on with local storage (session storage is the same here), it's still SQLite

Even if so, calling ReadProcessMemory/process_vm_readv on another process really doesn't raise alarms that significantly because there are a lot of legitimate programs that do so

> A lot of times local storage is much less secure than using cookies.

Is it? If an attacker can't do XSS then it's as strong as cookies.

Supply chain attacks aren't an argument here because they can also happen with cookies. CSRF as well. The same can happen in actual executable binaries.

I don't get the 20 yr age argument:

- HttpOnly fights XSS which is impossible to execute with modern frontend frameworks.

- SameSite fights CSRF but the real solution is to disable loading the website in iframes (remember clickjacking?).

- Secure fights MITM which is already fixed by default when using local storage and HSTS is the real deal.

Having said that, I'd say that local storage is more secure than cookies (no need to remember whether you put Secure on or not). Unless you're still using PHP, which means touch grass.

> - HttpOnly fights XSS which is impossible to execute with modern frontend frameworks.

Eh. Frontend frameworks tend to make successful XSS much worse because they tend to require disabling HttpOnly for not very good reasons. HttpOnly is a nice defense in depth measure against the consequences of XSS.

> - SameSite fights CSRF but the real solution is to disable loading the website in iframes (remember clickjacking?).

Disabling iframes doesn't fix CSRF. You can still <form method="..." /> or <img /> tags or whatever. For an example, see these universal logout pages. SameSite helps with CSRF (you really should also using CSRF tokens as the primary control and maybe using the Sec-Fetch-X headers as well).

> they tend to require disabling HttpOnly for not very good reasons

First time I'm hearing that frameworks require disabling HttpOnly.

> Disabling iframes doesn't fix CSRF. You can still <form method="..." /> or <img /> tags or whatever.

Obviously. IMG tags don't work because of CORS (unless you explicitly allow this) nor script tags etc. Browsers send Origin and Sec-Fetch- headers which you can use to block POST navigation requests from other origins, like you mentioned.

But when you're using tokens in JavaScript then you don't have to worry because you already have your CSRF token, which is inaccessible to third parties and no form submit will include it. That's why local storage is more secure.

> First time I'm hearing that frameworks require disabling HttpOnly.

They effectively do in the case where you're using local storage because they need to grab the session token from somewhere. The thing about HttpOnly is that JS code never even gets to see the session token. Which is a mitigation for a whole class of vulnerabilities.

> ...CSRF

You have to mitigate CSRF server-side (with a CSRF token, checking the Sec-Fetch-* headers) or by using SameSite on the client side (ideally both)

There's a reason "don't use local storage for security sensitive stuff" is part of the OWASP cheatsheet[1]

[1]: https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Securit...

> There's a reason "don't use local storage for security sensitive stuff" is part of the OWASP cheatsheet

Local storage was released more than 16 years ago, and back then PHP was wayy too popular. XSS is almost impossible to execute these days (unless you do selfxss).

Discord has mitigations for grabbing the token from local storage: https://news.ycombinator.com/item?id=48563286

> You have to mitigate CSRF server-side (with a CSRF token

> when you're using tokens in JavaScript then you don't have to worry because you already have your CSRF token

No reason to have a dedicated CSRF token because your local storage token already works as a CSRF token.

It simply doesn't mitigate CSRF by itself