views:

329

answers:

6

Hi all,

I'm considering to implement the classic 'remember-me' checkbox on my webapp to allow the authenticated user to be 'remembered' once he returns to visit my website.

Gmail, Facebook and others have this kind of feature but I'm not too sure how secure it can be.

A Java Framework like Spring Security uses an 'Hash-Based Token Approach'. The token that gets generated (using username,password,expirationTime and a privateKey) is stored in the Client's Cookies 'token=567whatever567'. The token is then reused to re-authenticate the user the next time he comes back.

I'm concerned of the fact that even if the login process happened under a https connection, on every subsequent http request the cookie will be sent unencrypted on the net.

Basically everybody can read the token and reuse it to authenticate.

I'm trying to have a look at how Gmail or Facebook are implementing this functionality. I can see some Cookie like 'presence=DJ267619445G09H0L15228675.....' in FB, others in Gmail.
I'm not too sure if they use some other trick to protect against someone that tries to impersonate some other user.

I'll try to impersonate myself using something like cURL to see if they're only using a specific token to remember the user.
If they are it looks to me like a big security issue. Maybe not facebook(I don't care of it) but with Gmail if you don't set 'Use always https' an http connection will be used and it will send your unencrypted tokens over internet.
What do you think?

I've also noticed that Facebook username/password fields are exposed under http (not https). In this regard I'm also wondering : Are all the websites exposing username/password field over http unsecure 'by nature'. Once the request is sent over http there's no 'redirect to https' that can fix the 'credentials visible to the world' problem.

Thanks

+1  A: 

The only way to make totally secure site is to enable https everywhere. You are right, cookies can be sniffed and later used to impersonate.

Andrey
+1  A: 

There are a couple ways of preventing session hijacking, such as storing the IP address of the client that opened the session. Additional data must be stored server-side to verify sessions, even without an automatic login feature. It's better to use a nonce for the token (or at least base it on non-secret data) rather than the hashed username & password, as an attacker could conceivably mount an attack to find the authentication information given the hashed value.

If you look at the source for the Facebook, Gmail and probably other sites' login forms, the login form action uses HTTPS, which then redirects to a non-secure page once login succeeds.

outis
IP is only a mildly successful solution that disregards large ISP's or companies that use distributed proxies.
Robert Paulson
+1  A: 

1/ When the user check "remember me" : you store a hash of every informations about his computer : IP, browser, OS, language etc... and you write this hash in his cookies with his ID 2/ when the user is back, you compute his new hash. You compare this value with the value in the received cookie, and the value in the database (for the given id). if they are all equals, you can authenticate the user.

Is it clear ?

Https couldn't do anything if you have an XSS attack (best way to steal cookie)

remi bourgarel
Someone can still know os, language, whatever.. and the token is still transmitted over the network without being encrypted so that everybody can see it. Including the IP as part as the generated token also doesn't fit well we the remember-me concept, I think. If I login at home I still want to be able to be remembered when I connect from my office and the IP is different.
al nik
@al the token is transmited over the network without beeing transmited ok but it's a hash so even if you see it you won't able to know how we create it. And you can save multiple hash for the same user.
remi bourgarel
+4  A: 

It's not such a problem to implement a remember-me. What you need to do is to keep the session alive for long (and set the cookie to last long). Even Gmail will log you out after certain period (I think it's two weeks or a month). However, you need to realize that keeping the same session open longer increases the possibility to hijack into it. As a countermeasure, you need to increase the strength of your session identifier. Session identifier is the one that is in the cookie (or in the URI as commonly seen in some software as "file.php?PHPSESSID=1234...").

The key is to maintain a strong session identifier. For example, in Gmail, you have a cookie GX with a value similar to

DQAAAJoAAAA8mnjaAwgkS7y8Ws5MYCl-PAQLp9ZpMXpGKR47z4L9mlBH-4qEyApAtFbnLkzv1pPqxua1hOWMGiKYpBZr-h7Icyb-NUUg2ZW_nUFIymvw9KjmjSECYTowbCsDerkAxCzSDa83b5YC1mykPv1a9ji4znt6Fsna-AKgNTntvmUxeJ92ctsSlg9iGySEmXnisVyyJiQvI8jzbZqSpE_N2RKZ

The reason why Session Hijacking is pretty much impossible is, because the session identifier is so strong, and because the site utilizes HTTPS everywhere. No one can guess or otherwise get your session identifier (thus can't hijack into your session). On a quick look, the session identifier above seems to have somewhat ~1250-bits of strength, 1*10^376 different possibilities. No one can guess that.

Obviously there will be always potential ways to still hijack into the session. For example, XSS vulnerabilities open the door way to get your cookies and therefore your session identifier, but this isn't your sessions fault in any way, and has nothing to do with a "remember-me".

I'm concerned of the fact that even if the login process happened under a https connection, on every subsequent http request the cookie will be sent unencrypted on the net.

If you set the cookie secure flag to true while in HTTPS, the cookie will never be sent when accessing the site via HTTP. It is a must to do for HTTPS-only sites.

In general, people seem to only use HTTPS for the log-in page, which is wrong. If one really cares, he should use HTTPS all over the page. Otherwise, it's impossible to prevent all Session Hijacking attempts.

Why do many still use HTTPS just for the log-in part? Probably because they don't realize what's in the stakes, or because it's too CPU heavy to use HTTPS everywhere. However, it's still better to use HTTPS for the log-in than not to use it anywhere - because it encrypts the credentials (thus only the session identifier can be stolen later on, not the actual credentials during log-on).

Maybe not facebook(I don't care of it) but with Gmail if you don't set 'Use always https' an http connection will be used and it will send your unencrypted tokens over internet. What do you think?

I think the value should default to HTTPS in all cases if possible. The only real reason as to why not use HTTPS is money (=performance/hardware).

Kai Sellgren
Any identifier sent in plain text, no matter how long, isn't secure if I can just steal it via man-in-the-middle with a hostile router and use it in my own requests. A stolen token doesn't need to be decrypted to be used in a replay attack. It might make guessing an authentication token hard / impossible, but that's not what was being asked.
Robert Paulson
As I said, if one doesn't use HTTPS, it's impossible to prevent all Session Hijacking attempts.
Kai Sellgren
So, I'm now logged-in here in SO. If I click 'Ask a question' I'll post my new question over plain Http. Basically everybody can intercept the request's Cookies and reuse them to send new questions as 'al nik'... is this correct?
al nik
Someone could even change my profile (as http is used everywhere). It seems that SO is not using any 'Secure cookie'. Is this correct? The only way to prevent any attack is to set a Secure Cookie to be transmitted only over https, and use https for all the operations that are visible ony to authenticated users.
al nik
This might slow down the website but it's the only way to prevent a Cookie from getting stolen
al nik
al nik, you are right. As long as you don't use HTTPS everywhere, you may end up in trouble. This is especially true on WiFi.
Kai Sellgren
+2  A: 

Agree with most comments made above. If you are concerned about security, you should -

a) Use https throughout. Even gmail recently switched to using https by default - see http://gmailblog.blogspot.com/2010/01/default-https-access-for-gmail.html

b) Set the secure flag in your session cookie to prevent the browser from sending it over a http connection.

c) Fix XSS in your application. If you have xss issues, your implementation of 'remember me' is always going to be unsecure. See OWASP XSS Prevention cheat sheet.

Including IP address in the session identifier is NOT going to help. Doing this will make the 'remember me functionality' pretty much useless, and it does not add much security. I know for sure google doesn't put IP addresses in its session identifier.

sri
+2  A: 

It's generally called a replay attack. The attacker replays a request using the same credentials (e.g. cookie) that it stole from you, and is able to impersonate you. The XSS attack is just a variation of this, but is preventable (e.g. using HTTPOnly).

The only way to mitigate most replay attacks is https everywhere. That should keep away most of the prying eyes.

There are lots of prevention techniques too.

There are also hardware devices that do a better job than you can hack out in software, slowing down your server in the process, and you'll probably get it wrong. Specialized hardware can do a much better job of tracking requests in realtime and determining that the same token is being used by many different IP's all at the same time, and faster than a single human operator ought to be able to request.

In ASP.NET 2.0+, when using Forms Authentication, you can specify requireSSL='true' to indicate that browsers should only send the authentication cookie when an https connection is made. See this msdn article for more information on securing forms authentication.


The only reason not to allow remember me is if you're a banking or similar application. If you're not, just follow a few simple rules:

  1. If you have remember me, put an expiry on the cookie at most 30 days in the future and don't slide the value. Forcing the user to login once a month isn't so bad.
  2. Any sensitive operations require a password. When updating billing, credit cards, or account details always re-request the users password. The most likely form of abuse is typically via the same computer that the person is using, but it also ensures that even a stolen authentication cookie on it's own can't do too much harm. You can see my balance, but you can't transfer anything.
Robert Paulson
very helpful, thanks!
al nik