Why LocalStorage is Vulnerable to XSS (and cookies are too)

preview_player
Показать описание
I go over how to perform an XSS attack and discuss how you're screwed no matter where you store your access token. Therefore, you might not need to worry about XSS when you decide whether to store your token in local storage.


----
#benawad
Рекомендации по теме
Комментарии
Автор

A users login session can be stolen in so many ways. The best think you can do is accept the fact that your vulnerable to XSS attacks. And think about ways to mitigate the damage that can be done when your users session has been hijacked. One example banks use is to ask for some kind of 2FA step each time you make a money transaction. The attacker might have the login session but probably not the 2FA code.

ivands
Автор

Completely agree with this, if you've got an XSS vuln then you've already lost the battle regardless of where you're storing things.

McGono
Автор

Jeah XSS attacks are always possible and the solution is to do enough input validation both on the client-side and on the server

paymankhayree
Автор

Some sites have dedicated pages with zero JS where you make a payment or enter sensitive info like a CC number (often on a subdomain). Can't use JWT, but cookies will still work. Just my 2¢

alexnezhynsky
Автор

Correct me if I'm wrong, as I mostly had an experience as a backend dev, but I believe that xss attack and problem with local storage is quite different then what you describe. Practically if we have any vulnerability that allows for execution of malicious JavaScript on our side we practically screwed and yes, we can't do anything about it if attacker knows our auth flow. But problem with local storage as I understand it lies in that it's actually accessible to all JavaScript code without any domain protection, so if user goes to a site that attacker set up for him, then code on that site can read anything from local storage.
Also even if you have authentication credentials split to protect user from both xss and csrf attacks and your own app is fine there are theoretical ways for an attacker to deal with it if he targets specific user/app, so like any security measures it's just a way of minimizing risks.

ГлебГончаренко-пь
Автор

I agree. I does not matter if you store any information locally, no matter if it is sensitive or not. Also it does not matter if you store it in a cookie or in localStorage. You can manipulate both.
When it comes to expiration, this can also be replicated using both methods but it has to be invalidated / checked on the server.
So I guess it really does not matter where you store user data as long as you escape any vulnerable input.
This can also be implemented using multiple layers:
E.g. validate input on frontend if possible or validate request params / body by type (number, string, boolean) and format (isEmail, isUUID, isLowercase)
Next would be to validate before inserting into your database on a model / entity level. Most ORMs provide this feature out of the box.
Last option would be to validate against any database schema (Database Datatypes).
Of course you should catch as many validation checks upfront but just in case, you have multiple layers of security

MarcoBiedermann
Автор

The reason why a HttpOnly cookie would be better is because the attacker doesn't get the actual JWT. For a single application you're right in that it won't make such a big difference, but the same JWT may be valid across different services so even if one service is vulnerable you'd want to avoid this extending to all other services sharing the same authentication method too.

hannessteffenhagen
Автор

Content-Security-Policy response http header can be a added security for this, as this http header limits the outside requests of your img, link, scripts, etc.. to only allowed domains. That way even if an attacker can do something on the site but he wont get anything since he is not able to do a request on some domain that is not defined on your CSP.

bulantut
Автор

I completely agree.
Having a stash of money under the mattress is not safer than leaving that stash of money on the kitchen table if you haven't prevented the robber from getting into your house, to begin with.

DavidBadilloMusic
Автор

while being a beginner web developer and exploring the ways of safe authentication and authorization, this topic makes me frustrated.
but the fart sound under your video makes me a bit calmer, and gives me a mystical hope.

felleg
Автор

I know this is old, but seeing this in 2021 . . .
Two things off the top of my head to consider -
*if a request should ONLY be done based on a user's intent, it should require a second factor authentication, this makes this type of vulnerability significantly weaker
*if a token could somehow be exfil'd to an external location rather than just have requests sent on your behalf while the app/tab/etc is open, they can make unrestricted requests regardless of app status, also offline introspection of the quality of the token (encryption methods, etc) is easier

JoshCarpenterVO
Автор

I believe that SameSite cookies address this problem. In this case the cookie is only sent when making a request to the hosting server

ridingtigers
Автор

i've seen csrf tokens being used, and those are assigned to the user at random by the server after each request while a user could steal that token, you can also make sure input is escaped, and use request validation, for example nobody can inject any scripts into you db for either xxs or sql injections. you can also sanitize the input so that commands are rendered as harmless strings. these work relatively well i think, although defeating a csrf token system might not be so difficult if you know what the token is before teh user makes a request

Meleeman
Автор

ty sir, nother great explanation. cool demo

sbrugby
Автор

wait maybe im not understanding this, but are xss attacks only possible if you implement something that allows users to run any html? I can't really picture myself doing that in any scenario...

harishankar
Автор

Awesome explanation and demonstration. Thank you!

Brad
Автор

Really good example why one shouldn’t use dangerouslySetInnerHTML. One good practice is to use CSP headers which will prevent attacker ”calling home” with malicious code (eg. sending your JWT to attacker). This also protects you from similar attacks if third party libraries would contain malicious code. But even with CSPs attacker can still make calls on your whitelisted endpoints.

ValtteriKaresto
Автор

Can't belive stackoverflow didnt have dark mode back then

amirhoseinfarhadi
Автор

You can bake in IP address into the JWT payload. If the request comes from a IP that is not identical from the JWT payload IP, you can automatically deny it. This would dissallow the usage of the JWT from a different IP. rarbg enforces something similar, but for the purposes of preventing web crawlers, and non-human access.

andrewlee
Автор

Wow, it's a great video! I found it really useful and learned a couple of things. However, I think in production there are other things about authentication that are just so very difficult to do without a provider. I mean, web security is a whole another world, as developers we can make our best efforts to secure it. My point is, it's not as easy as say, I'm going to use jwt and store it there, for example, if you use JWT as authentication, how do you persist session securely? How invalidate a stolen jwt? All those things can be overwhelming to do it manually, Auth0 for example and other providers have a lot of security mitigations to help with that.

agussluzenti