Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Secure AND Stateless JWT Implementation

Background

I am attempting to implement token authentication with my web application using JSON Web tokens.

There are two things I am trying to maintain with whatever strategy I end up using: statelessness and security. However, from reading answers on this site and blog posts around the internet, there appears to be some folks who are convinced that these two properties are mutually exclusive.

There are some practical nuances that come into play when trying to maintain statelessness. I can think of the following list:

  • Invalidating compromised tokens on a per-user basis before their expiration date.
  • Allowing a user to log out of all of their "sessions" on all machines at once and having it take immediate effect.
  • Allowing a user to log out of the current "session" on their current machine and having it take immediate effect.
  • Making permission/role changes on a user record take immediate effect.

Current Strategy

If you utilize an "issued time" claim inside the JWT in conjunction with a "last modified" column in the database table representing user records, then I believe all of the points above can be handled gracefully.

When a web token comes in for authentication, you could query the database for the user record and:

if (token.issued_at < user.last_modified) then token_valid = false;

If you find out someone has compromised a user's account, then the user can change their password and the last_modified column can be updated, thus invalidating any previously issued tokens. This also takes care of the problem with permission/role changes not taking immediate effect.

Additionally, if the user requests an immediate log out of all devices then, you guessed it: update the last_modified column.

The final problem that this leaves is per-device log out. However, I believe this doesn't even require a trip to the server, let alone a trip to the database. Couldn't the sign out action just trigger some client-side event listener to delete the secure cookie holding the JWT?


Problems

First of all, are there any security flaws that you see in the approach above? How about a usability issue that I am missing?

Once that question is resolved, I'm really not fond of having to query the database each time someone makes an API request to a secure end point, but this is the only strategy that I can think of. Does anyone have any better ideas?

like image 634
Luke Avatar asked Oct 18 '22 05:10

Luke


1 Answers

You have made a very good analysis of how some common needs break the stateleness of JWT. I can only propose some improvements on your current strategy

Current strategy

The drawback I see is that always is required a query to the database. And trivial modifications on user data could change last_modified and invalidate tokens.

An alternative is to maintain a token blacklist. Usually is assigned an ID to each token, but I think you can use the last_modified. As operations revocation of tokens probably are rare, you could keep a light blacklist (even cached in memory) with just userId, and last_modified.

You only need to set an entry after updating critical data on user (password, permissions, etc) and currentTime - maxExpiryTime < last_login_date. The entry can be discarded when currentTime - maxExpiryTime > last_modified (no more non-expired tokens sent).

Could not sign out the action just trigger some client-side event listener to delete the cookie secure holding the JWT?

If you are in the same browser with several open tabs, you can use the localStorage events to sync info between tabs to build a logout mechanism (or login / user changed). If you mean different browsers or devices, then a you would need to send some way of event from server to client. But it means maintain an active channel, for example a WebSocket, or sending a push message to a native mobile app

Are there any security flaws that you 'see in the above approach?

If you are using a cookie, note you need to set an additional protection against CSRF attacks. Also if you do not need to access cookie from client side, mark it as HttpOnly

How about a usability issue that i am missing?

You need to deal also with rotating tokens when the are close to expire.

like image 88
pedrofb Avatar answered Oct 21 '22 06:10

pedrofb