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

Поделиться
HTML-код
  • Опубликовано: 21 ноя 2024

Комментарии • 234

  • @ivands16
    @ivands16 4 года назад +92

    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.

  • @McGono
    @McGono 5 лет назад +126

    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.

  • @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?

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

    • @loucadufault6549
      @loucadufault6549 Год назад

      @@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 4 года назад +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  4 года назад +8

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

  • @felleg4737
    @felleg4737 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.

  • @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

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

  • @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 8 месяцев назад

      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.

  • @ridingtigers
    @ridingtigers 2 года назад +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

  • @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

  • @Meleeman011
    @Meleeman011 3 года назад +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

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

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

  • @victorbjorklund
    @victorbjorklund 4 года назад

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

  • @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 3 года назад +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 3 года назад +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

  • @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

  • @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

  • @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

  • @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?

  • @blueice3124
    @blueice3124 3 года назад

    That's why you setup input sanitization before officially deploying

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

  • @Brad10
    @Brad10 2 года назад

    Awesome explanation and demonstration. Thank you!

  • @amirhoseinfarhadi2268
    @amirhoseinfarhadi2268 3 года назад +2

    Can't belive stackoverflow didnt have dark mode back then

  • @SimonSezRide
    @SimonSezRide 2 года назад

    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 :)

  • @sbrugby1
    @sbrugby1 5 лет назад +7

    ty sir, nother great explanation. cool demo

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

  • @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?

  • @Dev_Everything
    @Dev_Everything 3 года назад +1

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

  • @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

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

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

  • @htmixl
    @htmixl 3 года назад +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?

  • @LawZist
    @LawZist 5 лет назад

    Realy good and simple example of xss attack

  • @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?

  • @nsambataufeeq1748
    @nsambataufeeq1748 3 года назад +1

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

  • @TheALEXiSounds
    @TheALEXiSounds 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

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

  • @JLarky
    @JLarky 4 года назад +7

    Reading comments makes me extremely sad

  • @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 RUclips) 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.

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

  • @diamondminer81
    @diamondminer81 3 года назад

    Remember XSS is always possible with an extension.

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

  • @chzmo
    @chzmo Год назад

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

  • @seth_sesu
    @seth_sesu Год назад

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

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

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

  • @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?

  • @dailymeow3283
    @dailymeow3283 3 года назад

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

  • @Liz3_
    @Liz3_ 4 года назад

    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

  • @suryapratimpaul
    @suryapratimpaul 3 года назад +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.

  • @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 5 месяцев назад

      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

  • @IsaiahGamers
    @IsaiahGamers 4 года назад

    Can subdomains access the same localstorage from the main domain?

    • @bawad
      @bawad  4 года назад +1

      I don't think so

  • @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

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

  • @CodeWithVlad
    @CodeWithVlad 3 года назад

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

  • @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

  • @Aquazifyy
    @Aquazifyy 5 лет назад +1

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

  • @gcxs
    @gcxs 2 года назад

    its ok to always open the third gate

  • @himanshushekhar3694
    @himanshushekhar3694 4 года назад +1

    thanks for the video really helpful

  • @JuanVasquezq
    @JuanVasquezq 3 года назад

    these are the vids we need

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

  • @TheDestroDevShow
    @TheDestroDevShow 4 года назад +1

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

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

  • @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?

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

  • @maxlimgj
    @maxlimgj 3 года назад

    can u also share your source codes?

  • @KiwiCoke
    @KiwiCoke 2 года назад

    Encrypting values in localstorage is a great option

  • @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

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

  • @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

  • @nyume815
    @nyume815 4 года назад +1

    I'm always hungry so I get 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.

  • @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 4 года назад +4

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

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

  • @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

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

  • @dpaulflavius
    @dpaulflavius 3 года назад

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

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

  • @manengelo8427
    @manengelo8427 3 года назад

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

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

  • @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?

  • @jairodavemejia4057
    @jairodavemejia4057 Год назад

    use BFF instead, don't trust the client ever

  • @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 ;)

  • @subvind
    @subvind 5 лет назад

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

  • @VishnuASankaran
    @VishnuASankaran 3 года назад

    You should do HTTP only cookies!

  • @volkanakincom
    @volkanakincom 2 года назад

    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.

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

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

  • @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

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

  • @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 :)

  • @tambolaking5383
    @tambolaking5383 4 года назад

    One can run javascript even by editing inspect > element

  • @nomadshiba
    @nomadshiba 3 года назад

    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.