How to add extra layer of jwt security when the token is stolen

Viewed 449

I am using jwt. I have some admin routes. I save the token in localStorage. In the payload of my token i have also admin property which is true or false. I wonder what if the 'admin' token from some user is stolen, and the old 'non-admin' token in the localStorage from the malicious user is replaced with the 'admin' token, then he will have access to the admin routes.

To prevent this on some way:

  • I will refresh the token on 10 minutes for example ( but the malicious user can do a lot of bad thinkgs in that 10 minutes - delete users from DB, delete configurations etc...). Is there any other way to prevent and this 10 minutes 'possible attack'

  • Save the token in httpOnly and secure cookie. Is 100% sure that if i store my token in this kind of cookie, and nobody can edit it ? so when the 'admin' token is stolen the malicous user can't just copy paste the new token, like he could in localStorage ?

1 Answers

Don't save the token in LocalStorage since it is accessible to js, which means any XSS attack will have an access to the token.

Use 2 kind of tokens,

  1. Short term access token (10 mins), it will be attached to each api request, it must contain something that is none "guess"ible some kind of hash, with it you will identify the user on the server side, it will be saved in memory.
  2. Long term refresh token (12 hours or more), it will be saved in httpOnly + secure cookie. It has one purpose, with it your app can generated a new access token (when it expires). It must contain none "guess"ible hash to identify a user.

This will make your system much robust. If someone get somehow the accessToken, it will be expired in 10 mins, without it your api will refuse requests. It is much harder to steal httpOnly + secure cookie, if someone managed to steal it, you can "revoke" the hash inside the token, so, it will become useless.

By revoking, it is simple as generate new hash in the db for the specific user/ entire db.

I always recommend to read this https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/

The entire idea on accessToken + refreshToken is explain there.

Some my code example, Axios Interceptor Response Token Refresh API called but getting Token is expired regardless in refreshToken API & lator all APIs

Related