2

I'm using the following authentication scheme for my current MERN project. I'd like to know if it's secure, particularly the renewal approach (more details after the description).

  1. User signs in over HTTPS. (Passwords are stored hashed and salted with BCrypt alongside the BCrypt-generated salt.) Server verifies the credentials and creates a JWT token. The token is signed with a 512-byte key that was generated via crypto random and is stored in the server's environment variables. It contains only one claim (other than the standard iss, exp, and nbf claims), which is the user ID, an integer. It expires in 1 hour. The token is sent to the client using the Bearer scheme in the Authorization header on the response.

  2. Whenever the client receives a JWT in the Authorization header of any authenticated response, it replaces its current token with the one given and stores it in session storage. Every authenticated request then includes that token with the Bearer scheme in the request's Authorization header. The server verifies that the token is valid, signed correctly, not expired, etc. If any validation here fails, it returns a 401 Not Authorized response.

  3. When the server receives a valid authenticated request with a token that expires within the next 10 minutes, a new token is generated with the expiration pushed back by another hour, then signed and sent in the response's Authorization header for the client to use.

  4. If a token is revoked for any reason, including sign-out, it's dropped into a MongoDB database containing all revoked tokens. Whenever the server is validating a token, if it exists in this database, it's rejected with a 401 same as if it were just expired.

My concern is that this renewal scheme means authentication timeouts can be anywhere from 10 minutes to 1 hour from the last request. The fact that it's not a single consistent time makes me wonder if this method isn't good and may be introducing a vulnerability that I don't know about.

Is this scheme robust? If not, what kinds of things do I need to consider that it doesn't cover?

IceMetalPunk
  • 121
  • 2
  • 1
    Welcome to security.se! Did you already read [Why shouldn't we roll our own](https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own)? – browly Oct 30 '19 at 15:41
  • 1
    @browly Well... I have now :) But consider this project a learning experience for me, not something that will be out in the world storing peoples' bank details. I'm more wondering *what* the flaws in this protocol would be than if it's as secure as it could be. – IceMetalPunk Oct 30 '19 at 15:51
  • 2
    @browly I wouldn't consider this "rolling your own" unless there is a standardized scheme on how to use JWT/JWS for authentication that I am not aware of. To me, this seems more like "How do I use JWT/JWS correctly?" –  Oct 30 '19 at 15:53
  • If it helps analysis, the JWTs are being signed using the library's default of HS256. – IceMetalPunk Oct 30 '19 at 15:55
  • 1
    Sounds good! I would suggest editing the question to clarify that this is for educational purposes, and won't be used in production. – browly Oct 30 '19 at 16:04
  • @browly I've edited the title :) – IceMetalPunk Oct 30 '19 at 16:07
  • How about keeping the track of valid token in the mongoDb instead of expired one? – avicoder Oct 30 '19 at 16:14
  • @dossi That could be done easily, I think; is there a benefit to doing that instead of tracking revoked tokens? I suppose if I do that, I wouldn't have to periodically clear the token collection to trim expired ones so it doesn't grow very large... and if my server is the one granting the tokens, it shouldn't be a problem to validate against that DB, right? – IceMetalPunk Oct 30 '19 at 16:48
  • 1
    In security overall - Whitelisting approach is always welcome than maintaining the blacklist! Also, by implementing it in this way you can also give the user a functionality to select and revoke the token from multiple devices. – avicoder Oct 30 '19 at 16:54

0 Answers0