3 ms·
I feel like the author doesn't mention one thing that I always thought was one the best advantages of using tokens stored in browser localstorage instead of coo
by damon_c 5y ago
I feel like the author doesn't mention one thing that I always thought was one the best advantages of using tokens stored in browser localstorage instead of cookies which is that the risks of CSRF attacks are lower/gone?
Cookies _always_ get sent with every request, so an attacker site can make a request to your API and if the user is logged in there, they can do as they please with that user's session... so CSRF tokens then need to be sent with any request which adds a bunch of other complexity.
If authentication is handled with a token stored in localstorage rather than a cookie, no other site has access to the token and thus through more authentication hoops one need not jump.
Am I just horribly confused and wrong about all this?
- arkadiyt 5y agoIt's an orthogonal issue - you can store JWTs in cookies and you can store session ids in local storage.
- shakna 5y agoThis is only true for cookies that do not have the SameSite=strict attribute. Cookies that have that value won't be sent by a cross-origin request.
- anaphor 5y agoNo, you're not wrong. But I would go further and say JWTs should be obsoleted by using an object-capability model (see: http://habitatchronicles.com/2017/05/what-are-capabilities/ http://habitatchronicles.com/2017/05/what-are-capabilities/ ) which is a more fleshed out way of using unique unforgeable "tokens" to access things. The ocap model is tailor made to solve the problem that CSRF is an instance of (confused deputy attacks).
- monocasa 5y agoI was under the impression that the right way to use JWTs is as object capabilities, much like Kerberos tickets. Can you expand a little more on how you believe they should be used versus how they shouldn't?
- anaphor 5y agoI guess it depends on how you use it yeah, like the token can be used to refer to a specific resource, which is then granted to whoever has the token. But obviously you can just treat them as a way of doing traditional identity based access control if you want, which isn't the most effective way of using them. JWTs don't let you easily revoke them, or narrow access to specific resources. That's something you have to do yourself, or rely on a library to do, but that would be built into an ocap based system.
- benlivengood 5y agoDo you know of any proposals for browsers to directly use capabilities? Servers can implement a strict capability model for server-side objects but the browser's granularity for a capability owner is almost useless. To be fair, no popular operating system makes much of a distinction between the human operator, the operator's actions via I/O, the behavior of applications ostensibly started by the user, and various other automatically started software, so at least browsers provide the concept of a domain for separate ownership.
- anaphor 5y agoThe most promising things I know of are Google Fuchsia (which is a mobile OS), and Goblins, which is a Scheme library for doing distributed programming. There is something called Realms which is being worked on for JS, but I haven't dug into it too deeply yet. It might provide a good foundation for building ocaps into the browser, though. https://github.com/tc39/proposal-realms https://github.com/tc39/proposal-realms https://en.wikipedia.org/wiki/Google_Fuchsia https://en.wikipedia.org/wiki/Google_Fuchsia https://docs.racket-lang.org/goblins/index.html https://docs.racket-lang.org/goblins/index.html
- solitus 5y agoLocalstorage is prone to XSS. You can split the JWT to have parts stored in cookie and another in localstorage. Stich the two together on the server.
- jfgiogktkt 5y agoWhat's the advantage over storing it just in the cookie then, since you need to look at it anyway, and since the localstorage storage half is useless on it's own (thus not useful from JS)?
- jakelazaroff 5y agoIf you're securing an API, you can mitigate CSRF by simply requiring a custom HTTP header: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#use-of-custom-request-headers https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Re...
- colinclerk 5y agoYes, unfortunately you've picked the wrong issue to be scared about. The CSRF attacks you're describing have been solved by browsers with the SameSite attribute on cookies. If you set SameSite=Lax or SameSite=Strict, cookies will not be sent with requests originating from a different site. In choosing localstorage over HttpOnly cookies, you've put yourself at greater risk in the event of an XSS attack (meaning, an attacker running their javascript code on your own domain). When your users' session tokens are in localstorage, an XSS attacker can exfiltrate the tokens from localstorage, and potentially transfer them off your site to their server, where they can then cause more havoc. HttpOnly cookies prevent this problem because the XSS code can't access the cookie value, so they can't be exfiltrated and transferred elsewhere. I recently wrote a little bit about this here: https://www.clerk.dev/blog/how-httponly-cookies-help-mitigate-xss-attacks https://www.clerk.dev/blog/how-httponly-cookies-help-mitigat...
- hmsimha 5y ago> The CSRF attacks you're describing have been solved by browsers with the SameSite attribute on cookies. This is only partially true; It requires the users to have browsers which respect this. Which is probably true for 99% of users now, but not 100% (pasting a comment from a project I worked on recently): /* 'lax' means cookies will not be sent for cross-domain requests on modern browsers, except from top-level navigations with a GET or HEAD request (which are safe). This mitigates CSRF without any additional token handling in browsers Edge (since 2017), Firefox (since 2018), Chrome (since 2016), and Safari (since 2018) */ > In choosing localstorage over HttpOnly cookies, you've put yourself at greater risk in the event of an XSS attack (meaning, an attacker running their javascript code on your own domain). XSS an issue regardless of whether SameSite is set, they just can't access the session cookies via Javascript (assuming HTTPOnly is also set). An attacker that was able to inject a script into a user's browser on your own domain can get around CSRF protection, and session cookies will be sent. The only disadvantage localstorage has over this is that it can be sent to the attacker's server as well. I agree cookies are much better for auth* information; if we're using JWT, those can fortunately be put in localstorage also right?
- seanieb 5y ago
- SigmundA 5y agoHow do you authenticate the request if you don't send the token with it?
- hangonhn 5y agoThat's a bad tradeoff. Local and session storage are not secure. They were never meant to be. In storing JWT in local or session storage you've trade CSRF away for XSS in return. The latter is MUCH harder to secure against. Any scripts loaded on your page, whether served by you or a third party, can access local or session storage. You can even try to save the JWT in "memory" by saving it to a Javascript object but that's still vulnerable to any script that runs from your page and knows where to look. It turns out the only really secure storage mechanism on a browser is... cookie with httpOnly, SameSite, and Secure flags set. If you're going to use cookies to store your JWT, well, you might as well just use cookies? JWT has its place but it's a bad trade to give up cookies in favor of that.
- inopinatus 5y agoMany of the concerns about JWT are pointing to the problematic governance and questionable choices of the standards committee, such as being unencrypted by default, and the reliance on defeatable browser safeguards (e.g. CORS, even localstorage(!)), rather than primary behaviours (like HttpOnly), to preclude theft of credentials. From a risk perspective, JWTs consequently present a larger attack surface, have greater intrinsic potential for inadvertent screwup, and they skew towards a larger blast radius if compromised. The decision frame for security hats is never (willingly) "can this mechanism be made secure enough", but "what's the worst that can happen?". Anecdotally, once you've started finding design misfeatures in something, it's only a matter of time before more (and perhaps more subtle) issues, come home to roost. Security folks can be super judgemental about competence, and some will even give voice to this outcome by deriding the maker as much as the thing made, but there's a bayesian truth to it as well.
- CodesInChaos 5y agoThere are two orthogonal choiceshere: 1. Cookies vs localstorage and an explicitly set auth header (or even a combination) 2. Stateful session token vs stateless JWT