How to do stateless (session-less) & cookie-less authentication?

How to do stateless (session-less) & cookie-less authentication?

I’ve seen multiple ways to do this during my stints during application assessments. One of the popular ways is the playing tennis way that you mentioned – sending the username and password in every request to authenticate the user. This, in my opinion, is unsafe, especially if the application isn’t single page. It is also not scalable, especially if you want to add authorization to your app in addition to authentication in the future (although I guess you could build something based on logins too)

One popular, although not completely stateless mechanism (assuming you have JavaScript execution) is to embed the session cookie in the JavaScript. The security guy in me is screaming at this, but it could actually work – every request has a X-Authentication-Token header or something like that, and you map that to a database, file-store in memory, etc. on the backend to validate the user. This token can have a timeout of whatever time you specified, and if it times out, the user has to log in again. It’s fairly scalable – if you store it in a database, its one SQL statement executed, and with the correct indexes, it should take very little time to execute, even with multiple simultaneous users. Load testing here would definitely help though. If I read the question correctly, this would be your encrypted token mechanism – although, I would strongly suggest that you use a cryptographically random token of say 32 characters, versus using a combination of username + password + whatever else – this way, it stays unpredictable, but you can still associate it with the user ID or some such thing.

Whichever you do end up using, ensure it is sent to you safely. HTTPS protects you across the wire, but it doesn’t protect you if you leak the session token via the URL (or worse, credentials via the URL). I would recommend using a header, or if that’s not feasible, sending the token via a POST request every time (this would mean a hidden form field on the user’s browser.) The latter approach of using a POST request should use CSRF defenses, just in case, though I suspect using the token itself might be some sort of a CSRF defense.

Last, but not the least, make sure you have some mechanism in the backend to purge expired tokens. This has been the bane of many applications in the past – a rapidly growing database of authentication tokens which never seems to go away. If you need to support multiple user logins, make sure you either limit the number, or have a shorter time limit on each token. As I said before, load testing may be the answer to this.

There are some other security concerns that I can think of, but they are too broad to be addressed at this stage – if you keep all the use (and abuse) cases in mind, you should probably be able to do a fairly good implementation of this system.