I have multiple clients connecting to a Node.js TCP socket server from an app. I would like to know a secure way of managing their session.
Username + password is passed over the socket to the server. The server confirms this is correct.
I believe that I now need to generate a unique token to send back to the client.
Now if the user closes the app, then opens it again, this token can be passed to the server and thus the server will confirm the user is authenticated again.
Potentially though, this token could be used by somebody else to gain access to this persons account. Is there a way to prevent this?
Is there a more secure way (whilst still maintaining the ability for the user to authenticate without logging in again)?
How would you handle connections from other devices using the same login. Do they get a different token or the same token?
Many thanks.
It comes down to your definition of secure enough. What you're doing now, which is essentially session tracking, and it is generally secure enough for a lot of general purpose usages - however there is typically an extra component added in which is a session should only be considered valid for a particular ip. If the users' IP changes, you should make them login again and issue them a new token. That way if some bad guy hijacks their session id it won't do them any good.
Now of course this is only valid if your bad guy can't appear to come from the same IP address as your client. If you are concerned about bad guys who are behind the same NAT as your client, and thus can appear to come from the same IP, then you'll have to bump up your security a bit more and maybe consider a system similar to what SSH uses, but that's a bit more complex.
As for connections from multiple devices, it's up to you - you can either keep track of some single token and just hand back that token when the user logs in from a different IP (while at the same time now allowing both IPs to access the site using that same token), or you can just issue a fresh token every time someone authenticates. Personally I tend to find issuing fresh tokens easier, much less tracking and hassle... but it comes down to your application and how you want to organize things, I could dream up good use cases for both methods.
Also, as for doing the password exchange.. You should at least do some hashing there, ie, server sends client some random_string
, client then uses some hash
function (such as md5
or sha
) to compute hash(random_string + hash(username + password))
and sends it back. The server then verifies that this matches by checking hash(random_string + password_hash)
is equal to whatever the user sent it. This makes it so the user's plain text password never has to be stored anywhere - on the server you just store password_hash = hash(username+password)
when the password changes.
Maybe something like this:
FIRST LOGIN:
username + pwd (hashed) ---> check user/hashed pwd
receive token <--- send token
NEXT LOGIN:
request login ---> receive request
receive random string <--- send random string
hash string with token as salt ---> compare hashed string
You should allow only one attempt with that random string and if possible check the IP from the original login.
This is not perfect because you could still intercept the token at login, but then you would also have the username and pwd.
This question basically comes down to session hijacking using stolen cookies. So the question is how you can secure the cookie as good as possible.
Use https instead of http and force your users to use https. This way, the cookie is not transmitted as clear text and can not be stolen using eavesdropping.
Set the secure
attribute on cookies (see Wikipedia) to bind the cookie to https and avoid it from being transferred via http.
Use some kind of message authentication digest, such as HMAC, to make sure that the cookie has not been tampered.
Optionally you can embed the client's IP address into the cookie and only accept it if it is being sent from the specific IP. Unfortunately this may cause problems with proxy servers or dial-up connections where IP addresses are newly assigned from time to time.
Last but not least allow one token only to be used once at a given point in time. If the user logs on using the same token on a second machine, either disallow the connection or end the first machine's session.
Hope this helps ...
PS: I am very sorry, I skipped the TCP part. Of course most of what I wrote only applies to http, not TCP. Anyway, some things might help anyway, such as #3, #4 and #5.