6 ms·
You don't need to verify the session on the server all the time. Session verification very quickly becomes a bottleneck to app performance, since you're doing a
by mark242 10y ago
You don't need to verify the session on the server all the time. Session verification very quickly becomes a bottleneck to app performance, since you're doing a separate database/cache lookup for each rest endpoint request. It's far easier, and provides much better performance, to just cryptographically sign a cookie that says "I'm this user".
This is where the short/long-term cookie comes into play, and is actually a neat idea to take care of the "how do I periodically check that the user hasn't logged out/changed their password/invalidated their sessions/etc" problem that the cryptographically-signed cookie brings up.
- bradleyjg 10y agoThat sounds like a time-space trade-off to me. I'd think cryptographic signature verification would be more expensive computationally than a cache lookup and compare, but not require much space. Also, and maybe this is the key part, it would be more distributable since you don't need shared state.
- mark242 10y agoYes; and CPU is cheap as hell. Round trips to a cache are expensive.
- cpeterso 10y agoAlso, CPU tasks like authenticating a message are cheap to scale horizontally. A cache is a centralized bottleneck.
- carterehsmith 10y agoThat depends on where your cache is. If your cache is on a separate box and you have to make a network round trip, yeah it is expensive. But if your cache is in-process, the access is cheap.
- tptacek 10y agoCryptographic signature verification can be expensive, but the previous commenter (and, to be fair, pretty much the whole software industry) is abusing the term "signature". Really, what we're talking about is cryptographically authenticated messages. Verifying an authenticator is extremely fast.
- dpark 10y agoCan you clarify what the difference is here? How do you verify an authenticator without verifying a signature?
- tptacek 10y agoPedantically, a "signature" is the product of a public key signature algorithm. It's what you use when you have multiple and/or anonymous verifiers. An authenticator is the product of an authentication algorithm, which can be as simple as a keyed SHA-3 hash (a hash over the data to be authenticated and a key known only to the verifier). Session tokens virtually never use signatures. The only party that needs to verify them is the serverside of the application that generates them; they're opaque to clients.
- dpark 10y agoSo you're assuming the session tokens are authenticated with a shared key. I guess that makes sense from a perf standpoint. It seems iffy from an isolation standpoint, though. I wouldn't think you would want every server holding effectively global auth keys. Edit: I guess this is actually a good case for the 2CH described here. The long-session cookie could be cryptographically signed, while the short-session cookie could be authenticated with a shared key that gets rotated frequently so that a leak of the key cannot cause a long-term compromise.
- tptacek 10y agoI don't know what you mean by "isolation", but virtually every mainstream system that stores secrets in tokens uses MAC constructions, not signatures. Signatures are much more complicated and dangerous. Don't ever use public-key crypto unless you absolutely need it.
- ejcx 10y agoSigning something is great but it comes with some possibly unintended consequences. If you want a stateless cookie, you won't be able to revoke it down the road. Which means if the cookie is long lived, someone who gets their hands on the signed cookie can impersonate a user for a long time. If you cryptographically sign a cookie and it isn't stateless, you haven't really improved anything because you still have to look into up. Cryptographically signing a cookie is great, especially for distributed applications, but it does have some properties that might not be desirable.
- oldrny 10y agoStill learning about this, but couldn't you: 1. Sign a cookie. 2. Store revocations in a database (remove after session expiry time). 3. Use a distributed bloom filter to avoid db hits for every request. ?
- ejcx 10y agoYes you could, but you still end up with this dependence on a lookup when you store revocations. Once you do that you lose the stateless benefit of cryptographically signing the object, and at that point you could just store the whole object and give the user a lookup id to the object without the complexity of cryptographically signing anything.
- dpark 10y ago> at that point you could just store the whole object and give the user a lookup id to the object without the complexity of cryptographically signing anything. Only if the collision of lookup IDs (accidental or malicious) is effectively impossible. If it's possible to generate a collision, then you've thrown away your security. This would also effectively give every server the ability to issue auth tokens (and mutate them in the DB), which is not a great choice if you care about security. But if you're handing out unsigned lookup IDs, you probably don't.
- StavrosK 10y ago
- riskable 10y agoA simpler solution is to simply keep the connection open until the session is complete. That way you can use the long-lived session token (in the cookie) each time the user visits your site/app and then just keep a WebSocket open while the user is connected. This has many advantages beyond the short/love-lived cookie stuff.
- ploxiln 10y agoYou can re-verify on the backend however often you like. Make the signed cookie include user-id and date (and maybe a session id). Accept it without backend-check while it's less than X minutes old. Buf if it's older than that, check the backend to see if the user has invalidated sessions since it was generated. In the typical all-good case, generate a new signed cookie and put it in the response. No need for service workers or anything. A web company I worked for a couple years ago implemented something almost exactly like this while I was there.