Stop using JSON Web Tokens. Use Cookies & Server Sessions instead

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so if you think gwts are awesome think again because in this particular video tutorial we're gonna see best practices that you should follow as a developer to secure your gwts and use applications and also we're to see how hackers or malicious users can use those gwts that can steal them from your application from your users that in ways that you don't know so in this one we're going to take a look on all of those also going to take a look on the best implementation to invalidate or blacklist different gwts but still use the actual feature of dwt as being stateless on the server using different stuff like redis and keeping that cache and middlewares and express and all of that so without further ado guys let's go ahead and jump right into it so in order to get started with gwts and understand what are the best practices we need to apply to secure our servers our apis and to make our applications a lot more secure with gwts we need to go through the basic aspects of how dwt's are generated and how they work and why actually we use dwt's in the first places so in this particular site in here i got like a brief introduction to our gw2 i'm not going to go through all of those but if you are not familiar with gwts just yet and you can read more about this and how they work of course dwt's are just like tokens and we sign the tokens we encrypt the tokens and we return them and the terminals are going to just basically represent or allow users to authenticate into our api and access different resources that's what it is of course they are generated up and log in so if every user when it provides the password and email or username he can get a gwt back and he can log in and when we generate a token there's a specific library specific set of standards and algorithms we use to encrypt those and sign them off and and we use those particularly so that's that's all being handled for us pretty well and once we got the gwt and once the user wants to access something he can authenticate and of course we're going to verify that particular token so this is a basic block workflow verification the token now i want to go deeply into like why is it used wrongly and what what is going on wrong with this particular way and like how you should probably secure this and how you should think about it so if we take a look on gwts that they are just tokens and they allow you to like use those tokens in a stateless way that means unit needs to keep states on the server side and that's why gw issues exist that's why they just keep this particular payload that keeps for example the user id that is currently authenticated and everything and of course they are encrypted and everything so one thing or like there's always three things that you should consider in authentication signing tokens mean encrypting the tokens and making sure the tokens data is not accessible by anyone on only your server or yourself uh you need to have a secure transport and this of course this can be happening just like in https or using ssl so make sure to do that and last but not least which is the most vulnerable part of all of this is securing the storage and what i mean by screen storage is actually putting or saving those dwt's in a secure place because if you don't save them in a secure place you're going to have you know a lot of pitfalls and a lot of issues regarding that and you're going to allow like side parties or hello hackers or anybody else with bad intentions to use those gwts of your users and to actually access their resource on behalf and it can do plenty of stuff like from xss to csrf and and session hijacking and plenty of stuff that you don't want to have in the other hand if you jump to the diagram like a user who wants to log into a server they basically just of course logs into the server the server is gonna send back the gwt token is gonna sign the token and everything and this is just gonna be a short-lived token so like it has a pretty small expiry date and that's that's that's one point i want to talk about so once you've got the token in here the browser needs to handle storing the token so it can send that token with every request made after login so you know you can to allow basically users to authorize after login you have to send that token and tell the server hey i got this particular token i can access these particular resources and they have the authority to do so so for that particularly what happens you can actually save it into two places one is the local storage which is the easiest and the most simple place but still it's actually so vulnerable and it's so bad practice to store it on a local storage and you can do it on cookies and particularly http only cookies so you can save them on two places in here and i'm gonna give you this like in this particular video an example between a difference between storing to the local storage and what other vulnerabilities from xss to a csrf that's going to you know just going to expose your server when you do it on local storage versus when you do it on http only cookies and why the benefits or what are the benefits in this particular so for our demo projects in here we got actually two projects we got the front end project which runs react and uses axios to you know just do the http request and authenticate and everything in the other hand we got express.js in here with passport.js in here and password.js of course if you're not familiar with this it's going to allow you just to basically authenticate and use like gwt authentication and do plenty of stuff so we are using in here to do gwc authentication and to extract that from a beer token so i'm using this as simple as possible using the local storage both of these projects right here like you know read from the local storage no cookies included just a local storage and this is the basic way most of people just implement authentication this particular way so you can find of course the projects in github in here just to see it yourself so i'm just going to go through like the basically how the projects works and for the demo application it's just basically a login so a login screen here that allows you to authenticate and everything so once you head over to this you can just go ahead and click onto um like the email or the password and you can enter that you can see we'll come back authenticating and it's going to store the api token so it's gonna say this is the api token this is the gwt this has been stored into the local storage right for that particular website localhost 3000 and of course some user information in here which doesn't really matter so we've got just the api token this is what we need for now and this is the gwt so this is one using local storage of course and now once i for example go to the dashboard i will be able to authenticate and the dashboard in here is going to do a play of requests one of these requests is going to do is the payment so it's going to do a request of the payments api and it's going to send like not response but request hitters it's going to send the authorization as a hitter right as a beer hitter in here and this is basically what the authentication works and how gwc actually works from a local storage so you send it on the header and the server is going to authenticate against return 200 it's going to allow you to access resource for example a payment gateway or payment endpoint that is protected by that api pretty simple and that's how it works and if you quickly take a look on the login form in here what we're doing is basically using the local storage and storing both the api token and the user and of course the user in here as long as you're not storing like sensitive information or like um password or encryption keys or anything related to the security side you know you're just basically good in here if you're just storing just metadata info most likely like ninety percent gonna be good but you know if there's always a ten percent you can be compromised so there is an api token in here and this is what we care about this is our jb dwt token and it's being stored on the local storage so once you log in once the submit in here once the request a response is came back so once you've got the response in here of course you're going to just like navigate to the dashboard whatever you're going to store the authentication and you can call it a day that's the simplest part and that's how it works if we jump back to the like the server in here it's basically using the strategy i said before the passport strategy which basically checks that or like extracts that from the hitter as a beer token remember we're sending it on the authorization header and of course it has the max age and everything it looks for the user it finds the user then it's going to allow you to authenticate if if you use this particular middleware in here just to do password authenticates it's going to allow you to access this because of course the gwt is valid and everything is working fine now why this approach is absolutely bad and you should always always avoid this at any cost so if i jump back in here and i'm just going to give you a quick example of xss and how this could be very very bad so since this particular application is pretty small right you can't have xss unless you implement that and that's what i did in here i implemented an xss vulnerable input and if i jump back to this particular input in here that should be on the dashboard and if you head over that's a just like sets in inner html right because reacts by default escapes any html stuff but once you do dangerously set in your html you're you just like have no warranty anymore so that's what i'm doing here i'm just creating this xss but if you are having this big application a medium-sized location even a small application you can have xss anywhere in your inside of your inputs like you can't imagine how like you can get an xss and you can't actually figure it out so it's very very bad to do that and you can always assume your application has an xss okay so i have an xss in here and i have an xss vulnerable input i don't care how but you can execute xss on your application and that's all i care about so i got particularly different payloads in here just to try access payloads particularly so i'm going to try this particular payload that's going to run an alert just to check that it's this one has an xss and it's closing e when i put an image in here soc and i can run custom javascript code and that's what actually happening here that's pretty good i just have an alert now what can an alarms how like hurt me because that doesn't sound like really dangerous because you're just doing it a lot just you know hear me out with an alert like you can start from an honor but what you can end on you can have an alert but this alert can have the dwt token like that's crazy that's your token in here and if you head over to um the application right over here you can find this is the exact same token and anybody can access that token because they can run suspicious or malicious kind of javascript code inside of your application and they can access local storage because javascript can access local storage and that's a pretty bad bones so just putting this xss in here which can run and do and everything that's pretty bad i mean like you can get the local storage you can get the api token you can do plenty of stuff so as long as you can execute javascript and you can access the underlining gwt token which is the local storage you can do whatever you want and the hackers can have fun with your website and i've got another payload that is pretty suspicious and and it's actually you can it can actually steal your gw token you can send it to a server and it can save it on a server so this payload in here just it's an image again it uses xss vulnerability and it does one error then it just uses xml http request module it opens a new request to a particular api and i've actually implemented the particular or simple api to steal a token then he just like appends that token from the local storage api token to the token and he adds it to the http request then he sends that request all just by executing it on your input and why is that just because you have your gw token on local storage hackers can actually do that if i jump to my server i got a simple endpoint in here that allows you to steal a token and you can grab the token from a query and plenty of stuff and this is this is actually very dangerous and you can just like you can grab it from a query you can save your own database and this api reference can be a hacker's api and it can steal different gw tokens and you can use them for evil stuff so yeah keep in mind in this so let's go and try this particular payload i've got the input in here i'm just going to click on this i pasted it i see nothing really like nothing happened okay if i go to the network tab i'm gonna see something suspicious there's an like a hidden some like a hidden network call made and there's token is stolen and the hitters are pretty simple but the payload is actually our token wow if i jump to the server if i go to the logs because i'm console logging this i got the stolen gw token and this is actually the stolen gw token it's it's actually this is what it is and why this particular one happened in the first place i'm not going to say exercise because xss could be like happening in every application and you can't mitigate xss so it's very hard to mitigate a very hard to fix your exercise even though you need to find and fix those particular exercises vulnerabilities you still can't control that endless or in the other side or on the other hand what you can actually control as a developer and the easiest way of course he needs a little bit of just you know changing hearing there but the easiest way and the most actual way to do authentication to implement authentication is to use http only cookies so if you're still using gwt tokens and saving them on your local storage the first thing or the easiest part that you can mitigate just right away is actually to make these gwg tokens expiry date just like too little like two hours or maybe five hours something like this something or like a timing window that cannot affect that much then later on you can actually change it to http only cookies so just like a quick resort you can just you know change the expiry date or the expiration time for this and just make it a lot lower now for http only cookies or just cookies in general and particularly http only cookies and particularly for example in here the login in here this i changed the projects in here to use http only cookies now instead of them sending the gw token on the headers you see i'm doing the gw2 token i'm signing the gwt token and everything but instead of sending it back on a hitter or sending it back as a response i'm not doing that i'm just sending the users data without a password of course and i'm sending that gwt as a cookie and of course if you're not familiar with how http work or http cookies is once the server sends back a cookie the cookie is going to be automatically set on the underlying browser for the particular local or for the particular domain that you know the cookie owns so that's particularly where it's going of course you can secure it here if you are http or https and ssl and because i'm just running this on localhost i'm putting this false but make sure to put it through if you're in production and then put in http only and this is a very very actual crucial approach to do for cookies not just cookies but you have to do http only cookies because http only cookies cannot be accessed by javascript so no javascript code can access the htcp only cookie and the cookie is going to be sent automatically by the browser when particularly making any requests to the underlining the mean that the cookie has so the browser's going to take care of handling the sending the cookie and the server is going to read the cookie as it does for the headers basically just need to add just you know cookie parser and that is it and that's all you need to do so http only cookie cannot be accessed by javascript that means you can actually run no xss or no excessive vulnerability can allow you to access that cookie which means you cannot do like session hijacking you cannot steal the gw token because the cookie cannot be accessed by the javascript and that's actually a very good approach so simply here i'm just doing the cookie in here i'm just returning the cookie and that's what it is so you like you don't need to go through the details of how that particularly works so just you got the cookie in here of course in the other hand in the front end in here particularly i'm not setting the api token on the local storage anymore i'm just going to leave that to the server to set the cookie because the server is going to be you know be able to return the cookie and the browser is going to send the cookie automatically for you so you don't need to do anything just save the user in here whatever made idea they need and the authorization token or the gw token is going to be handled by the server in the browsers themselves pretty easy and if i take a look on the axios interceptors because before we were using the actual interceptors to intercept every single request and add that clock at that from api token from the local storage and add it to the authorization header so to load that now i commented this code because that's no needed the cookie is going to be sent automatically by the browser and when like the response is coming in here when you have like an authorized i'm just removing the user in here because that's all i'm using for authentication and because i can't remove the cookie the cookie needs to be cleared by the server so that's a pretty good approach now if i jump back to the application real quick in here so i tried now to log in with cookies and http only cookies i click enter i'm going to be authenticated and get no luck you know no api token saved all the local storage but i head over to the cookies i'm going to find a new api auth and it has a cookie has a domain it has expiry days and plenty of stuff and plenty of you know details and it's just gonna be working fine so if you head over to the dashboard in here you're gonna be authenticated it's gonna allow you to access you can access the payments in here uh if i go to like the payment route that's gonna work and you're gonna find cookies that are sent like a request cookies in here it's gonna send that every single time the browser knows and everything so that would work fine and of course in here for this particular example if you try to do any xss right i've got the xss in here and i've got my server in here so this is my server i need to you know to be able to see if i can steal anything now if i you know put that in here the actual is you know because it's xss it can be still be called but if you take a look on the token the payload it's no because you have no access to this the local storage is not accessed anymore and you cannot access cookies http only cookies and if they take a look on this the token stolen and it's going to be called as no and exclusive tollen or stolen gwc token is going to be null and they can no longer steer your gw tokens and this is the best approach to secure gwc tokens in the first place also one other thing you need to keep an eye on so when you use cookies right now with axios with fetch so what you want to include is actually you want to include with credentials you can include it per request or better you can include it as a default so you can do access defaults with credentials and you can send that to true for the axios instance of course and this will allow it to send in set cookies and everything so make sure to do that when you change from local storage to you know http only cookies and the other very awful thing i completely disguise about using gwt is actually the ability to invalidate or blacklist a particular gwt in a particular time so for example here you got a gwt right and you got an x expiration time for that gwt like for example this one is from seven days from now and you won't be able like the server won't be able to an or won't be able to delete and block this particular gwt if anything happens for that particular user for security concerns or anything in in that particular time so you won't be able to do that like only this can only happen once the expiration time is ended because dwt's are stateless and you cannot keep them on the database or something so likely there is a particular way and they can make them or they can make them still be stateless kind of stuff you can still not include them or save them on the storeroom on the database but rather you can store them on a radius cache like an in-memory cache or just like even in disks cache because redness is super super fast and super powerful and not going to be storing that much of information you can be doing it on radius in here so for example right here i got this particular example it uses radius and of course so what i do in this one is actually i use radius to store like an object the key for up this object is the user id and those are all the gwts that the user got before and they were blacklisted so any gws is going to be added to this one is going to be blacklisted and the server won't allow it to access that of course you need to add a couple of different stuff but it's actually pretty pretty simple and pretty easy so i really advise you to go to this critical repo to check how that is implemented i'm not going to go into all the details but that should be pretty simple so we got the same thing we cooking structure we got the gwt and i'm using the same thing what one another thing here i'm adding is actually a logout route whenever the user hits the logout button and the request is sent to logout i want to take this particular gwt of the current user and store it on the redis so it's just to make this as blacklisted and nobody else can use uwt because it can no longer be generated and who like if the gwc was stolen before or anything compromised about that gwt you can just make sure that dwc can no longer access that because the user logged out and everything and of course you can have different types of different ways to include in the blacklist in here but just this is this is a super simple example of how to do it so once the luck you know wants to log out in here i'm going to authenticate to make sure there's a gwt i'm going to grab the gwt i'm going to access reddit in here to make sure if there's already a user and of course i'm gonna save that users uh particularly or save that new like token in here by just looking to the user and saving it if there is new user i'm gonna create a new record for it and so on and so forth and and that's basically what it is and of course i'm going to clear out the cookie so i'm going to do response clear the cookie the api auth on the browser so it can be cleared out for this particular user and everything would be working fine in the other hand this is actually the you know the way to add it to the actual redis cache and there is another middleware i created in here and this particular middleware is going to check every single request if it has an invalid or it has a blacklisted gwt or not so if he has a blacklisted gwt it's not going to be allowing it to access the server it's going to return 401 an authorized http you know response otherwise it's just going to allow it to access through what we can do is actually you can you know you can log in here for example like i'm going to grab this particular cookie value in here or what i can do particularly just a little bit better i'm going to go to axios right or sorry i'm going to go to postman and postman here i'm going to close this i'm going to go to log out right and i'm going to try to do that so for example i'm going to be able to log in first i'm going to click i'm going to log in it's going to send the password and everything and here postman what it does it keeps the state right so it keeps the state in here and the actual name of the value is going to be kept in here and it's going to be like you know keeping the actual cookies so whenever you do another request to a the same domain the cookies you saved before are going to be sends throughout that request so for example in here the payments i can do payments and it will be able to access the payment i'm going to get that you know i'm going to get still get the cookie and everything but that's going to be working fine so that's a pretty good approach now let's go in and try because if you remember i'm going to copy this particular token that i used in here i'm going to go to log out right remember i'm going to log out in here i'm going to use the same token i click on this it says goodbye that's pretty good cookies are cleared there's no cookies back if i head over back in here to redis and if i refresh excuse me there's a new token got added and that's what it is now it's actually blacklisted and if you try to go back to postman in here and if you try to head over to the payment api try to send a request you're going to have an unauthorized right because you're logged out and all those tokens and everything are you know removed even though the cookies are removed so that would work absolutely fine so anyway guys thanks for watching really hope you guys enjoyed this particular best practices for gwt and how to secure apis or how to secure react application and browser application and to make it absolutely like a standard secure application and make it absolutely work fine so without further ado guys hope you guys enjoyed and catch you hopefully in the next ones [Music] [Music] you
Info
Channel: CoderOne
Views: 39,031
Rating: undefined out of 5
Keywords: jwt, jsonwebtoken, json web token, JSON web token, JSON Web Token, JWT, JWTs, jwt auth, jwt authentication, jsonwebtoken auth, jsonwebtoken authentication, JWT Authentication, Express Auth, passport.js, Passport JWT, passport strategy JWT, invalidate jwt, blacklist jwt, blacklist auth user, authenticate user, jwt user auth, jwt authentication user, JWT advanced auth, learn jwt, learn jsonwebtoken, secure jwt, cookies, localstorage, local storage, http only, http only cookies
Id: FVmxtmzyrSw
Channel Id: undefined
Length: 23min 33sec (1413 seconds)
Published: Sun May 15 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.