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

แชร์
ฝัง
  • เผยแพร่เมื่อ 28 ธ.ค. 2024

ความคิดเห็น • 236

  • @ivands16
    @ivands16 4 ปีที่แล้ว +93

    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.

  • @paymankhayree8552
    @paymankhayree8552 4 ปีที่แล้ว +71

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

    • @martapfahl940
      @martapfahl940 ปีที่แล้ว

      all examples I saw worked through innerHTML… how is your code vulnerable without it?

  • @McGono
    @McGono 5 ปีที่แล้ว +127

    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.

    • @aidemalo
      @aidemalo 4 ปีที่แล้ว +1

      This is partially wrong, *without* http-only cookie, and open XSS, you need simple one-stringer which will fit even in url to get the cookie = full access to the session/account. Else you limited to simple actions and the script required becomes more complicated.

    • @ProtectedClassTest
      @ProtectedClassTest 4 ปีที่แล้ว +7

      False. If you own a house do you just fortify your door? Saying well if they open the door were already doomed so no need for other emergency security measures anyway. Just fortify the fucking door. Do you do that?

    • @barricuda
      @barricuda 3 ปีที่แล้ว +13

      @@ProtectedClassTest If you have an XSS vulnerability, you don't own your house, I own your house. Go ahead and secure my new lamp, it's a dumb lamp anyways.

    • @ProtectedClassTest
      @ProtectedClassTest 3 ปีที่แล้ว +8

      @@barricuda maybe you own the house but if i got a vault my money is still safe. Keep the house, its dumb anyway

    • @EidosGaming
      @EidosGaming 3 ปีที่แล้ว +6

      @@ProtectedClassTest
      Why would an attacker want your token? To impersonate you and perform actions. How do they perform actions? Through API calls. But if they've XSSed you they can fetch freely from your computer, whether you use httponly cookies or local storage.
      In the house analogy it's more like if they mind controlled you. It doesn't matter what kind of protection you've got, if YOU can go through the doors and the vault, then they'll just use you to do as they wish.
      The only thing you're protected against is if they want to perform some action at a specific time, they depend on you being online and XSSed at that time.

  • @alexnezhynsky9707
    @alexnezhynsky9707 5 ปีที่แล้ว +32

    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¢

  • @MarcoBiedermann
    @MarcoBiedermann 5 ปีที่แล้ว +9

    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

    • @nafiulawal1443
      @nafiulawal1443 2 ปีที่แล้ว

      What happens if the attacker edits your html to include a js input, say with a click anchor tag and then makes a request. I think the main problem here is to increase security on the front-end because the back-end will have no idea. Maybe 2FA is the best option here.

    • @louca6549
      @louca6549 2 ปีที่แล้ว

      @@nafiulawal1443 frontend validation is always useless from a security standpoint. If anything it's a (easily-defeated) deterrent.

  • @ГлебГончаренко-п3ь
    @ГлебГончаренко-п3ь 3 ปีที่แล้ว +7

    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.

  • @hannessteffenhagen61
    @hannessteffenhagen61 3 ปีที่แล้ว +6

    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.

  • @bulantut
    @bulantut 5 ปีที่แล้ว +6

    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.

    • @bawad
      @bawad  5 ปีที่แล้ว +9

      sure but the whole point of stealing someones token/cookie is to do something as them on the site

  • @felleg4
    @felleg4 4 ปีที่แล้ว +5

    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.

  • @harishankar5901
    @harishankar5901 3 ปีที่แล้ว +6

    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...

    • @LorenzoLeonardini
      @LorenzoLeonardini 3 ปีที่แล้ว +5

      In general you get user content. A username, for example. Generally you sanitize your inputs, both in the front end and in the back end, but maybe a specific version of a library/framework you're using is vulnerable to something. As far as I'm concerned nowadays XSS is researched on sanitization libraries. The thing is, if you do everything properly, people shouldn't be able to perform XSS, but you can never know for sure. The only websites which are safe from XSS vulnerabilities are websites with no user content, i.e. static websites

  • @lmfao7224
    @lmfao7224 5 ปีที่แล้ว +3

    One thing to note if you store the JWT token in local storage and an attacker gets in, they can use the token to make AJAX requested outside of your infected website whereas if it was stored in a Http only cookie AJAX requests would have to be made on your infected website
    Implication of this? If you have a react front end and a backend and say a mobile app the front end gets hacked by XSS and it’s stored in Http only, shutting down the website temporarily will temporarily solve the issue as no more Ajax requests can be made with the cookie
    If you stored it in local storage the attacker can send this to a remote server and use it to make Http requests with or without your website meaning you would have to either shut down your backend or change your signing key while your website is down, this would affect all your other microswrvjcws and would make all your mobile / api uses log out

    • @FilipCordas
      @FilipCordas 4 ปีที่แล้ว

      One thing to note on cookies they are open to CSRF cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html.

    • @rewire6468
      @rewire6468 9 หลายเดือนก่อน

      Yes, you're correct. Unless your use a simple CSRF token on user-end. Say a random 16 character length cryptographically generated code which is keyed to each user (one different code per user). You store this nowhere else but in a simple JS var. This is always cleared if you leave the site. Thus, another domain or server cannot make requests on your behalf, even if they have your auth tokens, since they do not have this code. You simply refuse any request that does not contain the user's CSRF token, on your back-end.

  • @DavidBadilloMusic
    @DavidBadilloMusic ปีที่แล้ว

    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.

  • @JoshCarpenterVO
    @JoshCarpenterVO 3 ปีที่แล้ว +1

    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

  • @syedalimehdi-english
    @syedalimehdi-english 3 ปีที่แล้ว +2

    What if we encrypt JWT token before sending it to user?
    An encrypted token would be useless for attacker if we have some decryption method at the front end.

    • @Mr_BetaMax
      @Mr_BetaMax 3 ปีที่แล้ว +3

      The JavaScript is exposed in the browser, so the hacker could , arguably, just copy the js from the sources tab and use your own decryption 🤔

  • @andrewlee6142
    @andrewlee6142 4 ปีที่แล้ว +2

    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.

    • @ferco0
      @ferco0 4 ปีที่แล้ว +1

      not good for long-live jwt, like ip's are not a fix value, when changed brokes the token.

    • @Nikola9517
      @Nikola9517 4 ปีที่แล้ว +3

      I’ve done that and it works. I’ve put ip in secure http only cookie, encrypted it with custom encryption and only after i decrypt it i becomes valid jwt, in my auth middleware i’m checking from which domain it is coming from (only my) and checking ip. It does log you out almost always if you are using vpn but it’s safer

    • @Nikola9517
      @Nikola9517 4 ปีที่แล้ว +1

      also since it’s double encryption it is very cpu heavy so keep that in mind, encryption key is unique to user and it is stored in server memory and automatically refreshed, also good idea to use 2fa if you are allowing/not checking users ip

  • @jaredjewitt2917
    @jaredjewitt2917 4 ปีที่แล้ว +2

    So I understand how using third party libraries which are bundled in your JS can make your app vulnerable to XSS. Such as a library looping through localstorage and sending it to their own API / database. But what I don't understand is how this specific example could make your app vulnerable. If a hacker were to replicate what you did, wouldn't they just see their own localstorage being printed? The same goes for phishing scams. Localstorage is domain specific, so if I clicked on a link to some-hacker.com how would they get access to my localstorage for my-site.com?

  • @jcmusik7495
    @jcmusik7495 5 ปีที่แล้ว +6

    Couldn’t you use some regex validation on the input fields that wouldn’t allow users to enter html or javascript?

    • @bawad
      @bawad  5 ปีที่แล้ว +3

      cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html

    • @dealloc
      @dealloc 5 ปีที่แล้ว +3

      Don't parse HTML with regex. Why? You will never get 100% spec compliance without a massive regex-which means there are different ways to circumvent the validation-and even then, you'll likely end up making a mistake that allows an attacker to use regex as another attack vector like RDoS (Regex Denial of Service).
      If you want to validate content-and you absolutely _need_ users to be able to write HTML, CSS or JS directly in your application-use a html sanitizer that parses HTML with a proper parser.
      But the best thing you can do is just not allow any HTML, CSS or JS (yes CSS is also an attack vector).

    • @nickwoodward819
      @nickwoodward819 5 ปีที่แล้ว +2

      Obviously you want to sanitize fields, but XSS vulnerability doesn't have to come from your site, could be present in a 3rd party package or cdn, so you still need to worry about it

    • @exactzero
      @exactzero 4 ปีที่แล้ว

      Yes, that's sanitizing inputs which is a whole different topic. This video is after the fact of being hacked due to not implementing them.

    • @christianaustria741
      @christianaustria741 4 ปีที่แล้ว +1

      i think in addition to that, you can just encode the output when displaying it inside the templates. I'm not very familiar with react but i feel like every SPA js library has built-in functionality for that.

  • @Meleeman011
    @Meleeman011 4 ปีที่แล้ว +1

    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

  • @Dev_Everything
    @Dev_Everything 3 ปีที่แล้ว +1

    So how do you prevent javascript from being injected? That seems like the biggest problem.

  • @ridingtigers
    @ridingtigers 3 ปีที่แล้ว +1

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

  • @sbrugby1
    @sbrugby1 5 ปีที่แล้ว +7

    ty sir, nother great explanation. cool demo

  • @tafelito
    @tafelito 5 ปีที่แล้ว +1

    how you are vulnerable using in memory token with a refresh token in http only cookie like you did on your prev vid? The only downside I found, is that using TokenRefreshLink will only check if the token is valid when you do a request to the server, but if you get the data from the cache, it won't be checked. So maybe adding a timer with the token expiration date would cover that as well

  • @SimonSezRide
    @SimonSezRide 3 ปีที่แล้ว

    How about we store the token in the application level variables. Will an XSS attacker be able to access that using some malicious JavaScript ? Is there a way to go that route where we don't use local or session storage or cookies. App makes a request for token every first call it makes to the server. I understand we will not be able to use features like stay logged in etc. but wont it be much secured ? I may be wrong please shed some light if possible. I know it is a very old video to comment now :)

  • @abdicodes
    @abdicodes 4 ปีที่แล้ว +4

    What happened to the solution where you store the token in memory?

    • @bawad
      @bawad  4 ปีที่แล้ว +6

      still vulnerable

    • @abdicodes
      @abdicodes 4 ปีที่แล้ว +6

      @@bawad no one is safe

    • @janjanusz8271
      @janjanusz8271 4 ปีที่แล้ว

      Not really. You can keep the token out of the global scope, so the attacker cant access the scope. It happens automatically with webpach. Each modules are anonymous functions indeed and cant be accessed from global scope. (function(){all login scope with no console.log that haker can hook up to})()

    • @ivands16
      @ivands16 4 ปีที่แล้ว +3

      @@janjanusz8271 Keeping it out of the global scope would work. But getting the token in the first place is probably an operation that can be done in any scope. So you have the same problem again. Plus you don't want your customers to be logged out each time they refresh the page or click on a link.

  • @ValtteriKaresto
    @ValtteriKaresto 5 ปีที่แล้ว +6

    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.

  • @Brad10
    @Brad10 2 ปีที่แล้ว

    Awesome explanation and demonstration. Thank you!

  • @CPlayMasH_Tutoriales
    @CPlayMasH_Tutoriales 4 ปีที่แล้ว

    Http only cookies mitigate the majority of xss attacks because of the cross origin requests prevention that browsers have enabled by default

  • @htmixl
    @htmixl 4 ปีที่แล้ว +2

    what about httpOnly cookie? Im learning about authentication and recently found a nice article explaining the best way is to have jwt in a regular variable, and a refresh token in a httponly cookie

    • @Mr_BetaMax
      @Mr_BetaMax 3 ปีที่แล้ว

      HttpOnly cookies are sent with the fetch request. So sending it to localhost:4000 ( which would presumably be the hackers own server) they could read the token on the server from cookies

    • @deltakapp676
      @deltakapp676 3 ปีที่แล้ว +1

      @@Mr_BetaMax But if you use samesite="strict" then the cookie can't be sent to the hacker's server, right?

  • @agussluzenti9596
    @agussluzenti9596 4 ปีที่แล้ว +4

    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.

  • @seth_sesu
    @seth_sesu 2 ปีที่แล้ว

    What about indexedDB? I assume this is less vulnerable to attacks?

  • @ryanholton961
    @ryanholton961 4 ปีที่แล้ว

    JWT is a popular choice for authentication and is implemented in many websites using web storage. Honestly, the site should be handling XSS (and most do), be aware of it, but unless it happens, localStorage and web storage in general is fine.

  • @hatrick3117
    @hatrick3117 5 ปีที่แล้ว +1

    Hey Ben, wanted to ask you to do something like your "chosing framework" video but about authentication (the one where you presenting a login behind choosing Gatsby CRA or Next). Do you think there is some thought process that we can have to go with cookie/local/memory, or it's all just semantics?

    • @bawad
      @bawad  5 ปีที่แล้ว +2

      really just depends on your situation
      inmemory is probably the most secure because it's not persisted, cookies are great overall but if you use an httpOnly one you can't access it, localStorage let's you access the token but is tricky for SSR

  • @JuanVasquezq
    @JuanVasquezq 3 ปีที่แล้ว

    these are the vids we need

  • @czypherth
    @czypherth 4 ปีที่แล้ว +1

    is it possible to prevent this by actually making regex middleware or something and check whether the query strings are most likely javascript code and reject it if it is

    • @brandtleymcminn
      @brandtleymcminn 3 ปีที่แล้ว +1

      It's not feasible to do this. You'd be playing whackamole trying to tamp out any attempts to circumvent your checks and probably catch a lot of valid data in the crossfire. If you did manage to get around this, an attacker would just obfuscate the syntax making it more difficult to detect.
      The more proactive approach is to ensure you have layers of validation and leverage modern sanitization strategies afforded by your language or framework of choice.
      Secondarily, make sure you aren't storing sensitive information in the token itself. Publicly available info like a username or userId value is one thing, but you shouldn't store emails, phone numbers, personally identifiable info not pertinent to the operation of your application in an authtoken.
      Form here any request made to your API should be run through a pre-auth check to validate the token and validate any roles/permissions related to the userid that your endpoint handles accordingly. Like if a user doesn't have admin privileges, they shouldn't be allowed to query other user data.

    • @ozzyfromspace
      @ozzyfromspace 3 ปีที่แล้ว

      @Zyper there’s an entire class of attacks called “regex attacks” that focus on the fact that regex is actually a really compact algorithm, and if you know what you’re doing, you can make a regex filter damage the server. Yesterday, I saw a guy (on TH-cam) tailor a string for a regex that messed it up real good… put it into a logical loop for like 30 seconds, which caused his little demo server to stress. The thing is, security vulnerabilities only work because we don’t see them as such.

  • @faiztheawesomeguy
    @faiztheawesomeguy 3 ปีที่แล้ว

    Usually what i will do will encrypt the data when storing on cookies or localstorage. If hacker manage to get access to storage or cookies, then they need to decrypt those value in order to use the JWT.

    • @erik50468
      @erik50468 3 ปีที่แล้ว

      But you will need to storage the decrypt key somewhere in the code, because I think that hash won't work for that case.
      Unless you encrypt in the server before send to client, but it's not will be like a classic server session?

  • @BHFJohnny
    @BHFJohnny 2 ปีที่แล้ว

    Ok, Ben, now what? You just told be that it doesn’t matter if I store my token in local storage, because if I'm vulnerable to XSS, they could also, you know, get access to that or just do the fetches on my account without my permission, right?

  • @LawZist
    @LawZist 5 ปีที่แล้ว

    Realy good and simple example of xss attack

  • @amirhoseinfarhadi2268
    @amirhoseinfarhadi2268 3 ปีที่แล้ว +2

    Can't belive stackoverflow didnt have dark mode back then

  • @swyxTV
    @swyxTV 5 ปีที่แล้ว +1

    i agree that if you're xss'ed you're pwned. like swapnesh said in the comments, cookies can have an expiration time, however even more than that, there is a serverside session as well that you can terminate if you believe you've been compromised (and so even unexpired, valid cookies will fail to do anything). whereas JWTs are typically accepted on without any further check (this is what lets serverless functions be scalable and stateless, altho some people do implement session checks) and therefore its riskier to keep long lived JWTs around in localstorage OR cookies. i had more great discussions in this thread mobile.twitter.com/swyx/status/1133780714988736512

    • @bawad
      @bawad  5 ปีที่แล้ว

      yeah I think it's a good idea with any kind of long lived token to have some functionality to be able to revoke it

  • @chzmo
    @chzmo ปีที่แล้ว

    What if you store a token in an encrypted format? Which can be decrypted by environmental variables 🤔? What do you think?

    • @Thabang_Kgatla1
      @Thabang_Kgatla1 20 วันที่ผ่านมา

      That's why I'm thinking too

    • @chzmo
      @chzmo 20 วันที่ผ่านมา

      @Thabang_Kgatla1 I tried on a certain project it was working.

  • @eyesight2073
    @eyesight2073 4 ปีที่แล้ว

    I really did not get the point.
    How the attacker gets access to clients browser in the first place?
    Lets say I'm client to your application, logged with username & password on my browser. Now JWT is stored in my browser's local storage.
    Now how can an attacker has access to my browser to execute js?
    Those vulnerable input boxes are available to me only & not for attacker right?

    • @conradooliveira1214
      @conradooliveira1214 4 ปีที่แล้ว +1

      Yes, but the attacker can send to the client a link that when the client enters that link, the injected js reads the user token from local storage and sends the token back to the attacker. Then the attacker can send requests to the server as if he was the logged in user.

  • @okitsalex
    @okitsalex 4 ปีที่แล้ว

    Whats your opinion on the double cookie method?
    1. Separate the header & payload from the signature.
    2. Store the header & payload into a secure cookie, as a string. Optional: including a random string, which can act as the redis key for scaling user session.
    3. Store the signature as a httponly, secure cookie, as a string. Optional: with the random string from step 2, store the signature into redis, where the key is the random string and value is the signature.
    That way the client will never have 100% access to the token, but then again as I'm typing this, if you are vulnerable to XSS then it doesnt matter lol.

    • @bawad
      @bawad  4 ปีที่แล้ว +1

      😂 exactly

  • @arthurbruel5545
    @arthurbruel5545 4 ปีที่แล้ว

    "It's not really that difficult to write code that is vulnerable", he says, while staring at a div with the "dangerouslySetInnerHTML" prop being used.

  • @gcxs
    @gcxs 2 ปีที่แล้ว

    its ok to always open the third gate

  • @justcurious1349
    @justcurious1349 4 ปีที่แล้ว

    Hi Ben, what if we use httpOnly, secure and samesite=strict with cookies. Can we not prevent cookies with these attributes from xss

    • @FilipCordas
      @FilipCordas 4 ปีที่แล้ว

      Not with xss, since it's your site making the request and anything you can the attacker can do. Local storage can in fact be somewhat safer from CSRF.

  • @dailymeow3283
    @dailymeow3283 3 ปีที่แล้ว

    How to prevent that please, is there any video for that,
    Maybe i could prevent that in nginx headers ?

  • @shilangyu
    @shilangyu 5 ปีที่แล้ว

    Here's a counter example: Let's assume a hypothetical situation. An app sanitizes ALL user input without exception. Is it still unsafe to store jwt in localstorage? It seems like the XSS example doesn't really apply to modern webpages, as you have shown you need to go out of your way to even make your site vulnerable in React. Waiting for your feedback, thanks :)

    • @Vaielab
      @Vaielab 5 ปีที่แล้ว +2

      To sanitize everything is simply impossible. Even google have some xss vulnerability (google "google xss vulnerability"). Some are browser based, other are brand new and not yet published. Unless you only accept alphanumeric chars, you most likely have some vulnerability somewhere.

    • @shilangyu
      @shilangyu 5 ปีที่แล้ว +1

      @@Vaielab what you're saying is new ways of performing an XSS, and yes it is browser based (ie. img tag or plain script tag). However they all rely on one thing: to work they need to embed themselves on your site as html. If one always treats user input as plain text none of these will work.

    • @filipitskov3742
      @filipitskov3742 5 ปีที่แล้ว

      i think react always does sanitize the rendered jsx, unless you do, dangerouslySetInnerHtml

    • @swyxTV
      @swyxTV 5 ปีที่แล้ว +1

      @@shilangyu correct, but you might be missing just how many people add third party scripts to their site that may be compromised, and can therefore listen in on all user input. react doesnt save you from that

    • @shilangyu
      @shilangyu 5 ปีที่แล้ว

      @@swyxTV i agree, its very hard to have every library and piece of code in control. However i feel like excluding localStorage token method is: yes, better safe than sorry but at the same time not always necessary.

  • @petersrule
    @petersrule 5 ปีที่แล้ว +2

    How would you get someone else to run those codes in their browser? I see you just using those codes in your own browser.

    • @Pikoro09
      @Pikoro09 5 ปีที่แล้ว +4

      When you have a site that allows users to submit anything. If this comment box had the dangerouslysetinnerhtml prop you could do that and run a script in the next persons browser that runs it.

    • @PJo336
      @PJo336 5 ปีที่แล้ว

      I have the same question, don't really get it.

  • @nsambataufeeq1748
    @nsambataufeeq1748 4 ปีที่แล้ว +1

    Just don't keep tokens around for too long, validate your inputs, both front and backend

  • @blueice3124
    @blueice3124 3 ปีที่แล้ว

    That's why you setup input sanitization before officially deploying

  • @CodeWithVlad
    @CodeWithVlad 3 ปีที่แล้ว

    This would not happen if you sanitize the HTML before dangerously setting it in that div.

  • @Liz3_
    @Liz3_ 5 ปีที่แล้ว

    but like if you render unsafe without a clear reason and respective measures you should go back to the drawing board. ive maybe experienced it 1-2 times that this feature had to be used

  • @Luxcium
    @Luxcium 5 ปีที่แล้ว

    What is the difference with going from the textarea again compared to the console ? It’s only dangerous when it’s from the url ?

    • @DeadlyDragon_
      @DeadlyDragon_ 5 ปีที่แล้ว

      Its dangerous either way from my understanding, its the same XSS vulnerability.

    • @pipertripp
      @pipertripp 5 ปีที่แล้ว

      all that matters is that the user has injected some bad code into your site so that the code executes as part of your site's operation. A really common attack is adding attack code to a board post. If the system does escape that content and neutralize it, then whenever someone reads the post, they will get affected. So however the user gets bad code into your site, you need to escape it or strip it out so that it can't execute. This is an old problem that's been round for ages.

    • @exactzero
      @exactzero 4 ปีที่แล้ว

      No difference

  • @swapneshsinha
    @swapneshsinha 5 ปีที่แล้ว

    I believe its the expiration time on cookies that makes them little better than localStorage. Rest you are totally right that once front end compromised it doesn't matter u store data in cookie / localStorage either.

    • @elie2222
      @elie2222 5 ปีที่แล้ว +1

      swapnesh sinha jwt stored in local storage has an expiration too. Jwt has it itself

    • @swapneshsinha
      @swapneshsinha 5 ปีที่แล้ว

      @@elie2222 Yes you are right but I didn't mentioned my comment about JWT specifically

    • @TheGryphon14
      @TheGryphon14 4 ปีที่แล้ว

      @@elie2222 cookie expiration is a default browser feature but jwt is not. You have to implement your own server-side logic to "invalidate" the jwt.

    • @elie2222
      @elie2222 4 ปีที่แล้ว +1

      @@TheGryphon14 You always have to have server side logic 🤷‍♂️

    • @TheGryphon14
      @TheGryphon14 4 ปีที่แล้ว

      ​@@elie2222 we can use Expires or Max-Age with Set-Cookie header. That's what I mean by default browser feature. But how do we tell browsers to "expire" a local storage item?

  • @onions5113
    @onions5113 3 ปีที่แล้ว

    About indexeddb how can attacker inject some payload on it?

    • @hypergraphic
      @hypergraphic 3 ปีที่แล้ว

      That's what I've been thinking about. The only problem with that is the files are probably unencrypted on the user's computer in a well-known location. So if that user has any malware on their computer, in theory, it's vulnerable, but at least you might cut down your attacks from the web.
      Based on what everyone has said, I think for apps where security is a priority, just have to do 2FA, not necessarily at signup, but definitely around critical operations.

  • @reapi_com
    @reapi_com 5 ปีที่แล้ว

    Different domain cannot get cookie from original domain? Browser won’t send it.

    • @bawad
      @bawad  5 ปีที่แล้ว

      if you make it http only, no javascript can access it

    • @gveresUW
      @gveresUW 5 ปีที่แล้ว +1

      @@bawad do you really need the javascript to access it? If it gets set as an http-only token and is sent to your server with each request, why does JS need access? BTW, i have your 3 hour video in my to watch list. So if you answered this question there, you can just point me back to that video.

  • @ibrahimmohammed3484
    @ibrahimmohammed3484 5 ปีที่แล้ว

    i still can't wrap my head about how a hacker target executing js on a victim's machine targeting my specific app or even if the attacker spoiled the victim machine and got his localstorage content, how would he relate to which app or website this token belongs !!

    • @bawad
      @bawad  5 ปีที่แล้ว +7

      he could check window.location to see the url of the website

  • @IsaiahGamers
    @IsaiahGamers 4 ปีที่แล้ว

    Can subdomains access the same localstorage from the main domain?

    • @bawad
      @bawad  4 ปีที่แล้ว +1

      I don't think so

  • @mrvectorhc7348
    @mrvectorhc7348 5 ปีที่แล้ว

    There are ways to block inline javascript completely in html. This can solve the problem if your app is written in a separate app.js file.

    • @nickwoodward819
      @nickwoodward819 5 ปีที่แล้ว +1

      The vulnerability doesn't have to be in your code though, just code you use

    • @mrvectorhc7348
      @mrvectorhc7348 5 ปีที่แล้ว

      @@nickwoodward819 if hacker manages to insert malicious code into your website that does something in js it probably will be inline js (otherwise you can block 3rd party js origins) in which case it simply won't work

    • @nickwoodward819
      @nickwoodward819 5 ปีที่แล้ว

      @@mrvectorhc7348 Can the code not be in a dependency that you need?

  • @pulga961
    @pulga961 4 ปีที่แล้ว

    Another hacker example can be:
    browser.downloads.download(urlToVirus)
    will work in case browser has acess to device storage which most people grant.

  • @DiegoArcega1
    @DiegoArcega1 4 ปีที่แล้ว

    How would you be vulnerable using cookie httpOnly and domain?

    • @FilipCordas
      @FilipCordas 4 ปีที่แล้ว +2

      If you use fetch or any other way of sending http requests it will send that request with all the cookies. That is why you have to use Anti-CSRF Tokens.

    • @FilipCordas
      @FilipCordas 4 ปีที่แล้ว +1

      Just to add something on csrf the browsers now do support SameSite staff but if this is done with xss that site is the same so it will still send even with strict level.

    • @DiegoArcega1
      @DiegoArcega1 4 ปีที่แล้ว

      @@FilipCordas makes a lot of sense Filip, thank you very much for replying

    • @TheGryphon14
      @TheGryphon14 4 ปีที่แล้ว

      @@FilipCordas so the point is, make sure our site doesn't have any xss vulnerabilities right?

    • @FilipCordas
      @FilipCordas 4 ปีที่แล้ว

      @@TheGryphon14 Well sure you should not have any xss on your web app but sometimes things get overlooked so it's always best to to try and allow minimal amount damage even if you have a security flaw.

  • @victorbjorklund
    @victorbjorklund 5 ปีที่แล้ว

    Good explanation. I had never thought about the risk with query-strings on the URL.

  • @Aquazifyy
    @Aquazifyy 5 ปีที่แล้ว +1

    Hello Ben, is your previous video still a safe solution?

    • @bawad
      @bawad  5 ปีที่แล้ว +5

      Yes

  • @maxlimgj
    @maxlimgj 3 ปีที่แล้ว

    can u also share your source codes?

  • @sneak9407
    @sneak9407 2 ปีที่แล้ว

    I Still prefer cookie storage. You still can't read the cookies, you can only make request with them.
    JWT on local storage can be read and then taken to another PC and properly impersonate a user.
    Secondly if the frontend is XXS free, they will have no way to make request on behave of a user using cookies. While if storing JWT in local storage, if an XSS runs on your machine, they can still take those tokens and simulate authentication on their machine.

    • @daviddoyle7580
      @daviddoyle7580 7 หลายเดือนก่อน

      If the xss is running though they still have access to the cookie to make requests to endpoints even if they can't read the access tokens it doesn't matter, they still have the cookies to make the request. The cookie has an expiration though you might say but so does the jwt so it seems that local versus cookie is the same safety wise I think

  • @himanshushekhar3694
    @himanshushekhar3694 4 ปีที่แล้ว +1

    thanks for the video really helpful

  • @diamondminer81
    @diamondminer81 3 ปีที่แล้ว

    Remember XSS is always possible with an extension.

  • @JLarky
    @JLarky 4 ปีที่แล้ว +7

    Reading comments makes me extremely sad

  • @carlosjosejimenezbermudez9255
    @carlosjosejimenezbermudez9255 4 ปีที่แล้ว

    The best approach I have come to learn is to not store it anywhere but in memory. This would cause your app to be unable to refresh without losing session, but there is a browser event that runs before refresh. You can essentially put your JWT in sessionStorage or localStorage during this event and remove it as soon as your app reloads. That way you only keep you token in insecure storage when it is absolutely necessary. And you give very little time for an attacker to use your token if at all.

    • @ivands16
      @ivands16 4 ปีที่แล้ว +4

      haha funny fix. But not really usable. Your get weird bugs like when you open a second tab. The second tab will be logged out.

  • @suryapratimpaul
    @suryapratimpaul 4 ปีที่แล้ว +2

    Cookie with fixed domain and secure cannot get xss. Plus JS can be disabled for some cookie, I mean JS can't access such cookies.

  • @elmehdiaa2882
    @elmehdiaa2882 5 ปีที่แล้ว

    does the use of Auth0 solve the problem?

    • @bawad
      @bawad  5 ปีที่แล้ว +2

      I wouldn't say solve but it does things to help mitigate

    • @elmehdiaa2882
      @elmehdiaa2882 5 ปีที่แล้ว

      @@bawad Thanks

    • @carlosjosejimenezbermudez9255
      @carlosjosejimenezbermudez9255 4 ปีที่แล้ว

      @@elmehdiaa2882 OpenId Connect and anything that implements it solves this issue.

  • @AshwinKJosephperez
    @AshwinKJosephperez 4 ปีที่แล้ว

    Can we not restrict the domain to which the cookies are sent?

    • @TheGryphon14
      @TheGryphon14 4 ปีที่แล้ว

      we can. developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

  • @MrTarantino47
    @MrTarantino47 5 ปีที่แล้ว +1

    Hey Ben, thanks for the video!
    Can we store our JWT token in .env file?

    • @bawad
      @bawad  5 ปีที่แล้ว +1

      The token itself?!

    • @MrTarantino47
      @MrTarantino47 5 ปีที่แล้ว

      Ben Awad , yes

    • @bawad
      @bawad  5 ปีที่แล้ว +3

      why would you want to do that?

    • @hannad
      @hannad 5 ปีที่แล้ว

      No no no noooooooo

    • @weltmeister
      @weltmeister 5 ปีที่แล้ว +4

      I'm curious to how did you get that idea?

  • @Nerketur
    @Nerketur 3 ปีที่แล้ว +1

    What you say is true, but I will retort that localStorage is a lot easier to read and access than cookies are, or any type of session.
    localStorage, if I'm not mistaken, is readable from anyone's session. Fred can read Daphne's token as long as they use the same computer, with or without XSS, XSS just makes it easier. Session storage is a lot harder to read without being the user, especially if the session is stored server-side.

  • @impulse8170
    @impulse8170 5 ปีที่แล้ว

    You could use XSRF/CSRF pattern as a parity token. For example store your auth token in cookies (http only and secure - only https) and a second jwt token in your local/session storage, that way an attacker can possibly only get one token at a time, so either XSS or XSRF... but your API expects both tokens. JWT can be set to be vaild for a certain time period, the XSRF token does not need to be as strikt as the auth token.

  • @UTonesOfficial
    @UTonesOfficial 4 ปีที่แล้ว

    Hey Ben, thanks for all your vids. I have this idea, I don't know if this will work, just a newbie here trying to learn things and all. What if before we store the token locally, we encrypt it first, so that the available "token" locally is not the actual token itself. You know, just thinking. Sorry, newbie here.

    • @bawad
      @bawad  4 ปีที่แล้ว +1

      Same problem, I'll just send the encrypted token to the server

    • @midsummerstation3345
      @midsummerstation3345 4 ปีที่แล้ว +3

      The jwt token itself is encrypted by default

  • @manengelo8427
    @manengelo8427 3 ปีที่แล้ว

    But some one might as well just do to developer tools.. and get it... if in pc

  • @TowfiqIslam1
    @TowfiqIslam1 5 ปีที่แล้ว +1

    What about storing the JWT in Redux Store?

    • @RafaKoodziejczyk
      @RafaKoodziejczyk 5 ปีที่แล้ว

      Isn't redux store just using localStorage as it's backend? (Yes, you probably can change backend storage, but still it's still the same, as user JavaScript have access to the same data in that domain however it's executed or wrapped, until it's an in-memory storage as it's only one that can't be accessed by injected third party code.)

    • @z-aru
      @z-aru 5 ปีที่แล้ว

      Once you close the tab, the token will be gone.
      Unless you have some session mechanism like refreshToken, you still need to store the refreshToken

    • @hatrick3117
      @hatrick3117 5 ปีที่แล้ว +1

      That is what he refered as "storing in memory", so it's all the same :)

  • @xushenxin
    @xushenxin 3 ปีที่แล้ว

    how about this: save the token in memory. save to local storage when page is unloading. When page is open again, read token from local storage to memory, then delete local storage. So when single page app is running, there is nothing in localstorge.

    • @neloka4313
      @neloka4313 3 ปีที่แล้ว +1

      Yeah sure, that way I cannot have two tabs of your website opened at the same time while still being logged in.

  • @nyume815
    @nyume815 4 ปีที่แล้ว +1

    I'm always hungry so I get cookies

  • @artem_skok
    @artem_skok 3 ปีที่แล้ว

    The http only cookies are only sent to the origin that have created them. So the request to another domain will not have cookies in it and it occurres to be safer then localstorage . Please correct me if I am wrong.

  • @timothyebiuwhe5209
    @timothyebiuwhe5209 4 ปีที่แล้ว

    Have you tried setting the httpOnly flag on your cookies?

    • @Chaosweaver667
      @Chaosweaver667 4 ปีที่แล้ว

      From what I recall, it's up to the browsers to abide by httpOnly, not an actual rule. I'm pretty sure most cookie extensions allow you to modify httpOnly cookies. I could be completely wrong.

    • @31redorange08
      @31redorange08 4 ปีที่แล้ว

      To achieve what?

  • @TheDestroDevShow
    @TheDestroDevShow 4 ปีที่แล้ว +1

    The New "SameSite" cookie will help to fix the issue for the cookie scenario you mentioned.

    • @AndersonSilvaMMA
      @AndersonSilvaMMA 4 ปีที่แล้ว

      Can you elaborate on that?

    • @mateuszciupa8141
      @mateuszciupa8141 4 ปีที่แล้ว +3

      well, if its xss attack its still the "same site" xd

    • @ivands16
      @ivands16 4 ปีที่แล้ว

      No it won't

  • @DiogoOliveira-kz7wu
    @DiogoOliveira-kz7wu 5 ปีที่แล้ว

    what is the solution?

    • @bawad
      @bawad  5 ปีที่แล้ว +4

      protect against xss the best you can cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html

    • @carlosjosejimenezbermudez9255
      @carlosjosejimenezbermudez9255 4 ปีที่แล้ว

      @@bawad Also, look into Identity Server 4 and OpenId Connect. Okta as an Auth provider is a potential solution.

  • @JLarky
    @JLarky 4 ปีที่แล้ว +3

    Big oof.
    1. csrf tokens in headers
    2. http only, secure cookies
    3. content policy
    p.s. bonus point, Google PASETO

    • @31redorange08
      @31redorange08 4 ปีที่แล้ว +1

      What does this change?

  • @dpaulflavius
    @dpaulflavius 3 ปีที่แล้ว

    I hope till today, you won't save jwt in localStorage :))

  • @KiwiCoke
    @KiwiCoke 2 ปีที่แล้ว

    Encrypting values in localstorage is a great option

  • @tambolaking5383
    @tambolaking5383 4 ปีที่แล้ว

    One can run javascript even by editing inspect > element

  • @nickwoodward819
    @nickwoodward819 5 ปีที่แล้ว

    I'm new to all this, but the OWASP cheat sheet seems to say you can defend against this using a 'fingerprint' or user context: github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/JSON_Web_Token_Cheat_Sheet_for_Java.md#token-sidejacking
    Explained a bit better here in the update this year: stackoverflow.com/questions/54258233/do-i-have-to-store-tokens-in-cookies-or-localstorage-or-session
    Would love to see a JS implementation of the first link

    • @bawad
      @bawad  5 ปีที่แล้ว

      that'll protect you if they steal the token and try making requests on their on server
      but they can just make requests from your browser

    • @nickwoodward819
      @nickwoodward819 5 ปีที่แล้ว

      @@bawad Well that sucks. So you're saying that just simply storing a JWT token is no less safe than any other available option? I guess I should just make sure that any important action requires actual login credentials?
      Thanks for the videos btw, great help!

    • @bawad
      @bawad  5 ปีที่แล้ว +1

      1. From what I could figure out, if your vulnerable to XSS you're screwed no matter how you store your token
      2. That's a good idea

    • @nickwoodward819
      @nickwoodward819 5 ปีที่แล้ว

      @@bawad Yeah, from what I've read the past couple of days you're right.
      RE an admin account - Does creating a local server that they log into, which then communicates with the webserver, cutting out the browser, sound like a good approach?

    • @bawad
      @bawad  5 ปีที่แล้ว

      If your building a website, I don't think having it communicate with a local server adds much value

  • @volkanakincom
    @volkanakincom 3 ปีที่แล้ว

    The title of the video is misleading. This video is about xss. But you get attention from people to watch the vide bu giving a wrong title.

  • @eddie_writes96
    @eddie_writes96 5 ปีที่แล้ว

    Clean your inputs y'all. Don't let your users write any javascript.

    • @eddie_writes96
      @eddie_writes96 5 ปีที่แล้ว

      But even if we clean our inputs, team black hat would still be able to munipulate the DOM.

  • @subvind
    @subvind 5 ปีที่แล้ว

    look up the definitions. one is time based (session/activity) the other is space based (local/area).

  • @jairodavemejia4057
    @jairodavemejia4057 ปีที่แล้ว

    use BFF instead, don't trust the client ever

  • @AdrianDucao
    @AdrianDucao 4 ปีที่แล้ว

    the thing is you should never store something important on localstorage, sessionStorage or on cookies, use those as storage for something else.

  • @Vaielab
    @Vaielab 5 ปีที่แล้ว

    So here is my 2 cents (and I might be completly wrong here, and I havent seen your other video about this yet)
    When you store your information in localstorage, you can get your session stolen. So someone else can be connected as you and do some sort of multi-step hack (do a request, have to wait for someone to accept your request do something else). And they can do it at anytime of the day when ever they want to.
    If you store your information in a http only cookie, the only time you can get hacked, is when you are currently on a hacked paged. As soon as you close the page, the hack is over. There is no way for the hacker to make other requests.
    With this idea, if you hacked thousands of account that were stored in localstorage, you could later launch a attack against the website where everybody do the same action at the same time, but if you used http only cookie, even if you haved hacker thousands of account, there might be only 20 currently online that will launch the attack.
    But then again, not a security expert, and I might be wrong.

    • @RafaKoodziejczyk
      @RafaKoodziejczyk 5 ปีที่แล้ว

      You are correct, but still it's all about a target, if your page is using cookie and to do an action you need just to execute a GET request then you can just post an image with the URL and once person open page with that image that action is done, and this works with cookies even if your site doesn't have any XSS vuln.
      For example to delete account your site just need to execute GET /user/delete/123
      Then simple image on external site would remove that user, while storing cookie in storage then this attack would fail as you need to send with token that attacker doesn't have on every request.
      So for critical requests you should avoid using get, use POST instead and validate http referer.
      But overall if your site have xss then your users are screwed, and it's better to use cookies but with httponly and secure flags, as it deny JS access to cookies and prevents sending cookies plain text without encryption. Or even use both ;)

  • @vitor14
    @vitor14 5 ปีที่แล้ว +1

    I think a good way to fight against xss maybe is save some sort of device information hash, detect if the device changed to ask re enter the password.

    • @filipitskov3742
      @filipitskov3742 5 ปีที่แล้ว +1

      Sry, what?🧐 Can you please explain what you meant here because i cant get a thing

    • @TheAngoRun
      @TheAngoRun 5 ปีที่แล้ว +4

      The device itself doesn't change. Attacker performs the attack on behalf of the user.

    • @vitor14
      @vitor14 5 ปีที่แล้ว

      @@filipitskov3742 If I understood correctly the idea of the xss attack is to obtain the credentials to impersonate the user and to be able to access their personal data. So if we keep some kind of extra information, such as device information, or places where the user is usually connected, it would be easy to identify if someone is trying to enter with that stolen token.

    • @dealloc
      @dealloc 5 ปีที่แล้ว +2

      @@vitor14 Now you have other problems, especially in EU (GDPR). But that aside, this wouldn't solve your problem; any client-side information can be changed/faked-this is easy for an attacker to research before doing the attack, so you haven't really solved a problem.
      The best thing you can do is treat the client as always potentially malicious. Don't trust the client. Always sanitize data before passing the data through any of your services (validation, parsing, etc.). XSS may be the least of your problems.

  • @Yahyazini
    @Yahyazini 4 ปีที่แล้ว

    Cookies are definitely better for storing jwt tokens with the added level of security using HttpOnly which prevents JS from seeing the cookie and Same-Site which only allows same domain to see the cookie. But again if you're writing code that's vulnerable there's no helping that.

  • @nomadshiba
    @nomadshiba 4 ปีที่แล้ว

    why not just use CSP: connect-src?
    try to send a fetch request on twitter, somewhere other than twitter

  • @MikeEnRegalia
    @MikeEnRegalia 5 ปีที่แล้ว +1

    Lol - of course it’s not hard to write a vulnerable react app if you use dangerouslySetInnerHtml. Duh.

  • @VishnuASankaran
    @VishnuASankaran 4 ปีที่แล้ว

    You should do HTTP only cookies!