in Web 2.0 applications many users usually want to stay logged in ('remember me' flag) and on the other hand their cookie can give access to very private data. Is there a way to prevent that somebody who steals the cookie - directly from the computer or via sniffing - can use the cookie to get access to the user's data? Always HTTPS is not an option.
Thanks, Bernd
[Edit] Connect the IP address to the cookie is not an option either.
Put a lid on the cookie jar.
Jokes aside, the best option has already been stated - make the cookie an obscure ID and tie it to an IP address lookup on the server side. Since you edited to say you cannot tie it to an IP address, that leaves the obscure ID part. Your options are limited with cookies - the minute you place something on the client, it becomes a risk.
Bernd -- the trouble with anything done over standard HTTP is that it's plaintext; anyone can fake anything. IP Spoofing is a bit more challenging to do than just plain cookie stealing, so tying to the IP tends to be what people do. Like you said, that does not work very well with highly dynamic environments.
The only mostly secure way I can think of is to use HTTPS to place and verify a "permanent" cookie, and then place (in the same HTTPS session) a short-lived session cookie. The rest of the communication can be done over regular HTTP, using the session cookie to authenticate.
That way, fewer resources are used in supporting encryption (just the handshake), the permanent cookie is not exposed -- it's only transmitted under encryption -- and stealing the session cookie opens up to only limited risk, since that cookie will quickly expire.
All that being said -- don't let users click "remember me" on a site that contains truly sensitive data! That's why Banks don't do it..
Hope this helps.
Bernd - you say connecting the IP address to the cookie is not an option, I'm assuming that's b/c the user could be connected via DHCP, and thus could come in under a different IP each time. Have you considered tying the cookie to the DNS host name? You could encrypt the cookie using a private key, and store it on the user's box. Then whenever they come in, check the cookie, un-encrypt it, and then check the user's current DNS Host name against the one in the cookie. If it matches, you allow them in. If not, you don't allow the auto-login.
FYI - in ASP.Net, to get the DNS host name of the user's box, just look at
About storing complex cookie ids and associated IPs in a database -- you don't really have to do that. If you have a secret key K, it is enough to encrypt the user's ip with your K, and place the result {IP}K as a cookie. As long as your key is secure (and the crypto hasn't been broken -- but if that happens, we have bigger problems), this is safe.
KISS -- just use sessions so that you're using an ID that is already automatically created by the server-side scripting language of your choice. That's hard enough to guess. Then, if it's stolen, store the IP address and user-agent of the visitor in the session (making sure never to output that) and only consider the session valid only if the already stored IP address and user agent match that which is found for the remote client.
In this scenario, the attacker would have to do the following three things:
It also helps to make sure that the attacker doesn't already know all of the things he/she would have to do in order to correctly take over a victim's session. IE: They may assume just the cookie is needed and then fail... and have to figure out everything else through a very long trial and error. In this way, you gain security through obscurity and through difficulty, depending on the skill of the attacker and his/her existing knowledge of the system.
Perhaps using a Session ID and token (a hash based on the IP, a salt, and the Session ID), that is regenerated every request (use a fast hashing algorithm) would be a good approach? I store session data in a database (currently), and this means I have a two query overhead every request. It works like this:
In this way, firstly cookies are bound to whatever I base the token on (in this case, remote address), and if that is stolen and client data spoofed, the cookie is only useful for one request anyway - by the time the cookie is intercepted, it is useless.
The only perceivable weakness I can see is if the attacker managed to grab a cookie, spoof, and use it, before the real person could do another request. There are a few ways to solve this that I need to think about. The overhead is two queries and generating a token hash twice (once for verification, once for replacement).