-1

Thinking about statelessness I wonder how I can overcome the issue of saving the user's password on the client side in a secure but also comfy way.

I assume the client always sends credentials to the server and that uses CPU power to verify the authenticity and also make sure the user has the authorization to do whatever is requested.

That way I hope to achieve a setup where no server needs to query the database for some session info upon each request and instead wastes some CPU cycles. Of course I could add a cache to the server, but with many concurrent users what do I keep in cache and what can I get rid off? Each server would need to have a user in it's cache or look it up from the db. Now if sequential requests always hit other servers they unnecessarily hit the db or put something in their cache.

On the other hand they need to do this anyway to ensure authenticity (I mean they need to check creds) or authorization. But for the sake of the argument, let's assume they do not.

Now: How could I store the password on the client so that after an initial authentication message an arbitrary server that replies with "Credentials okay" I can reuse them, but not send them plaintext upon every request. (I mean plaintext here. Of course I need to send the password or some token upon every request, that's the essence of being stateless. If I introduce a token on the other hand, I am not really stateless anymore, am I? And if I store the salted/encrypted password from the server - given that he returns it upon initial handshake, this is also bad, I assume.)

Let's assume the client is:

a) a Webbrowser b) an arbitrary application

Any ideas?

  • 2
    Why not leverage OAuth 2.0 services from Microsoft, Facebook, Google, etc..? Rolling your own security should not be lightly undertaken. – Erik Eidt Jan 27 '17 at 18:03
  • and instead wastes some CPU cycles -- This is probably the last thing you should be worried about. – Robert Harvey Jan 27 '17 at 18:05
  • Because of two reasons: 1) I am interested in learning new stuff and this is not yet about a real world application 2) I prefer not to use anything by said companies (let that just be a statement, no offense meant) – Sorona Jan 27 '17 at 18:05
  • In every stateless application, there has to be some form of handshake as part of every request to indicate that this client is still legitimately logged in, and that he's not being impersonated, etc. – Robert Harvey Jan 27 '17 at 18:06
3

You can't.

You tell that don't want to resend the password in every request, but at the same time, you want to remain stateless. You can't have both.

What you can do, however, is to generate a key on successful authentication. This key will then be stored client side, and sent at every request in order to be checked by the server. This also means that when the server needs to perform the check, there would be a roundtrip to the database, unless the same server already did the check previously and cached the response.

This approach is not very different from sending the plain password every time. The only difference here is that you don't actually store the plain password for a long time. Note that security wise, the difference is not that big: if an attacker gained access to the browser (for instance by installing a malicious plugin), then the attacker would be able to intercept the password anyway at the moment the user enters it and submits the form.

But, wait, doesn't this mean that you're not stateless any longer?

Actually, no. What happens is that every request requires a key to be provided in the HTTP request, and when not, the server responds with HTTP 401. When the key is provided, the server performs an ordinary authentication. This is exactly as if you were requesting the user credentials themselves.

What happens is that the keys could (and should) have expiration policy. For instance, if the last request from the user happened fifty days ago, it may be very suitable to invalidate the key and request a new one. Or if the user's last request was twenty seconds ago from Oregon, and now happens to be from New Delhi, asking to confirm the password could probably be an appropriate step. But this doesn't mean that the API is not stateless any longer: in the same way, the user may suddenly change the password, and the API call which worked a few seconds ago will result in HTTP 401 if repeated with the same credentials.

That way I hope to achieve a setup where no server needs to query the database for some session info upon each request and instead wastes some CPU cycles.

Or you simply use a distributed cache, for instance Redis.

but with many concurrent users what do I keep in cache and what can I get rid off?

I think “cache expiration” is the term you are looking for.

  • Where exactly did I say that I don't want to send the password in each request? OF COURSE I DO! I just don't want the user to having to enter it for each request! (Non-native speaker here, maybe some sentence made the impression of what you just stated, if so, please point me to it, so I can get rid of that nasty little bastard) – Sorona Jan 27 '17 at 18:07
  • @Sorona: Have I misunderstood the “I can reuse them, but not send them plaintext upon every request.” part of your question? – Arseni Mourzenko Jan 27 '17 at 18:08
  • Also, what if an attacker intercepts later, if only the token is on the client? Then all would boil down to the algorithm on the server-side to find out the real password. That session would be corrupt though and could be hijacked. – Sorona Jan 27 '17 at 18:09
  • Yes, the "plaintext" is important here. – Sorona Jan 27 '17 at 18:09
  • @Sorona: what about HTTPS (that you should use anyway, otherwise you'll be sending the password in plain text the first time)? – Arseni Mourzenko Jan 27 '17 at 18:10

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.