The scope is server-side session management with session payloads being sent to the client in a cookie.
I'm researching session management for web applications. I've been looking at a couple places, and from my understanding is we shouldn't use a secret as a session identifier(index). Because it can lead to timing attacks.
Let's say for the sake of performance sessions on the server-side are stored in cache/memory. And the index
is reset(e.g: starts back at 1) every time the server restarts or they are all purged.
session_payload = index || HMAC(server_key, index)
But doing it like that would leave room for replay attacks, right? An attacker could generate a bunch of session payloads and store them for later to hijack sessions. Something is needed to make each session payload unique to prevent that, right?
So what about:
payload = index || nonce
session_payload = payload || HMAC(server_key, payload)
If my understanding is correct, the nonce
just needs to be unique to make the session payload unique. Should it be just the output of a CSPRNG, RNG or the current time(milliseconds?, nanoseconds?)? What are the caveats of each?
So if the above is done right, it should be able to avoid:
- Timing attacks.
- Volume attacks.
- Replay attacks.*
- Tampering.
Right? And is there any other attacks I should be aware of? Please exclude session fixation, that can be mitigated via session payload regeneration on privilege escalation.
- What I define by a replay attack, is adversaries could store pre-computed session payloads and hijack sessions later, hence the use of the nonce.