2

I'm implementing custom authentication & session management system in Node.js & PostgreSQL. My goal is to implement sessions that expire after 2 weeks (if not refreshed/renewed).

OWASP and other resources suggest to store unhashed session IDs both in database and cookie. However, if those session IDs are leaked from the database, then they can be used to successfully authenticate before they expire.

I wonder if hashing sessions would add some additional security against such situations. The implementation I'm thinking about would work like this:

  1. User authenticates.
  2. A session is saved to database with id (UUID v4) and token_hash (SHA256 hash of cryptographically secure random string).
  3. Both id and original unhashed token are saved to response session cookie(s).

Then on subsequent requests:

  1. Server reads id and token from request session cookies.
  2. If there's a session found with id, then the token is verified against token_hash. If it succeeds, then the user is authenticated.

(I'm thinking about using both session id and token/token_hash because I think it will be faster to first find the session simply using id, and only then verify token against token_hash. Otherwise, the token would need to be hashed on every request to find the session, which, I assume, would be slower, even if some fast hashing function like BLAKE3 would be used.)

17
  • I think this is actually a duplicate of security.stackexchange.com/questions/138389/…, which is in turn a duplicate of security.stackexchange.com/questions/136122/… . Accepted answer is "Yes", second answer is "No, if you implement some advanced logic that makes it not necessary".
    – Alex
    Sep 27, 2021 at 6:55
  • @Alex, these questions are indeed close, but my question is about specific implementation not mentioned in them. Sep 27, 2021 at 12:55
  • 1
    @multithr3at3d there can be many reasons, e.g. 1) greater control over implementation 2) needs not supported by existing solutions 3) actually creating/maintaining those 3rd party solutions 4) learning 5) curiosity Oct 3, 2021 at 3:02
  • 1
    I think you don't realize that hashing sessions have a performance cost that is paid on every request that uses the session token. A hashed password pays the cost only during login.
    – ThoriumBR
    Oct 29, 2021 at 13:55
  • 3
    DB leaks are frequently read-only (lots of SQLi is limited this way, as are exposed backups or clone functions, etc.). If I gain R/O access to the SE DB and it's using hashed session tokens (or JWTs or similar), I can read everything that has been written - even if it's not visible to most users anymore - but that's it. Bad but hardly catastrophic for the users; most content on SE is public anyhow, especially to privileged users. If I gain R/O access to the DB and it's got unhashed session tokens in it, I can hijack your session and post content under your name.
    – CBHacking
    Feb 25 at 11:53

1 Answer 1

0

I think it will time consuming since you will validate id and token on each request. In my opinion, what you could do is implement stateless JWT authorization. Implement custom claims w.r.t to user ID in JWT token and set expiration time while generating the JWT token. It will minimize compute time of auth validation.

1
  • 1
    In terms of compute time, JWTs are almost strictly worse than server-stored random session tokens, even if the random tokens are hashed. JWT signature validation requires a minimum of two rounds of hashing (HMAC), or much much worse if asymmetric signatures are used. What JWTs avoid is the time to hit the DB or other storage.
    – CBHacking
    Feb 25 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.