views:

878

answers:

7

Hi,

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.

+1  A: 

Store a cookie that is an obscure ID into your local server database. Do a server-side DB lookup based on the ID provided in the cookie. Be sure to make the ID sufficiently complex that it cannot be easily guessed. Map the ID to the IP Address of the user. If their IP changes, then force them to log in again, and create a new ID.

On second read, it sounds like you want a high level of security with your hands tied. The user must have the choice to remain logged in and thus increase his/her risk. You can implement all the security in the world from the application's and server's point of view, but if the user forgets their laptop on a table in Tim Horton's (Canadian Starbucks), then none of it will do you any good.

Leave the choice up to the user as to whether or not they remain logged in, and give them a warning about their information being at risk.

Kieveli
Hi Kieveli,that doesn't sound very convinient for the user. There are a lot of environments where IP addresses change very often, and the user don't want to log in over and over again, that's why he/she choosed 'remember me'.
Cookies are only accessible by a specific domain. Think about it: if somebody can steal the cookie, it means that the thief has access to the computer, if he does, he can open the browser and go to the site anyway. But yes, some attacks can be performed. I would recommend you do it the way above.
Loki
Loki -- that is incorrect. Cookies are sent in plaintext over the internet; sniffing them is fairly trivial, especially if you are using wireless.
SquareCog
+1  A: 

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.

Chris
+2  A: 

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.

SquareCog
+1  A: 

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.

SquareCog
A: 

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

Page.Request.UserHostName
mjmcinto
+2  A: 

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:

  1. Steal the victim's cookies
  2. Spoof the correct IP address
  3. Spoof the correct User Agent

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.

+1  A: 

session identifier

islam khalil saber