Live data from Hacker News

How to build (and how not to build) a secure “remember me” feature

troyhunt.com

11–20 of 65 posts

Re: How to build (and how not to build) a secure “remember me” feature

#11

Regarding how long to keep the "remember me" cookie for, this is one of the overlooked reasons why native apps are eating the web's breakfast. When was the last time you have to re-authenticate on a native mobile app? Maybe it happens on some finance/banking apps, but I don't recall seeing it on apps like Facebook or Kindle for example. Web developers could, for example, add longer times if the user agent is mobile.…

> When was the last time you have to re-authenticate on a native mobile app?

All the time. The Facebook android app is horrible.

Re: How to build (and how not to build) a secure “remember me” feature

#12
post #5

How does the "reference implementation" of ASP.NET actually work? Is the cookie's value mapped to some in-memory entry in the application server, is it stored in a database, etc? It seems that the article doesn't say.

> Is the cookie's value mapped to some in-memory entry in the application server, is it stored in a database, etc?

Neither. At login the server signs the new session cookie with a secret application key. Later, when a client requests a page and sends over the session cookie, the server verifies the signature. If it matches, the data in the session cookie -- which usually includes the username, whether they're logged in, and for how long -- can be trusted.

This is nice because it makes scaling a stateful site easier. Server-side session stores often become the bottleneck. Also, from a REST standpoint, updating a session database during a GET request (eg to freshen the session) is problematic.

ASP.net was the first time I remember seeing the signed session cookie trick, but most web frameworks have it now:

django -- https://docs.djangoproject.com/en/dev/topics/http/sessions/#...

rails -- http://guides.rubyonrails.org/security.html#session-storage

flask -- http://flask.pocoo.org/docs/api/#sessions

node -- https://github.com/mozilla/node-client-sessions

mojolicious -- http://toroid.org/ams/etc/mojolicious-session-cookies

Re: How to build (and how not to build) a secure “remember me” feature

#14
post #3
post #2

> A more pragmatic mitigation is to still separate the auth cookie from a dedicated “remember me” cookie and use the latter to re-authenticate the user but impose some restrictions. What are the benefits of using a separate cookie for the "remember me" feature, provided that you impose the same restrictions (e.g. requiring the password again before accessing sensitive areas of the website) and same security measures…

How do you tell if the user's session has expired so you know to ask them to re-authenticate before doing anything sensitive?

AFAIK the re-authentication thing has nothing to do with expiring sessions. The whole point is to ask users to re-authenticate even though their sessions are still alive and well. Enter your password again to change your privacy settings, etc.

Re: How to build (and how not to build) a secure “remember me” feature

#15
post #6

I tend to like doing: sha256(sha256($password) . $ip) This encrypts the password and makes the cookie only usable by the IP it was set for. Then to verify the cookie, since I already store sha256 of the password, it's trivial to do, without having to store an additional token for persistence. Of course you can replace sha256 with your fav hashing function.

I have two ISPs at home. What happens when the next day my router decides to use the other IP address?

Re: How to build (and how not to build) a secure “remember me” feature

#16
post #2

> A more pragmatic mitigation is to still separate the auth cookie from a dedicated “remember me” cookie and use the latter to re-authenticate the user but impose some restrictions. What are the benefits of using a separate cookie for the "remember me" feature, provided that you impose the same restrictions (e.g. requiring the password again before accessing sensitive areas of the website) and same security measures…

One significant benefit is being able to enforce a one-time use policy the remember-me cookie. If you only utilize it when the user is not logged in, then you use it to authenticate, set a regular session cookie, and generate a new remember-me cookie. If an old remember-me cookie is ever used that means someone probably sniffed the cookie, and you can invalidate all sessions at that point and even force a password reset if you are particularly paranoid. You can't do this with the regular session cookie because a user might have multiple tabs open. For remember-me the same effect is only a race condition if the user opens two tabs simultaneously.

Re: How to build (and how not to build) a secure “remember me” feature

#18
post #8

Good article, but one thing is explained in a weird way: Don't bother with cookie expiration. That's the wrong approach, because the cookie is controlled by the user . Always do a server-side check whether or not the auth token in the cookie is allowed to continue the session. So you could simply set the expiration date for a cookie until 2030 but make sure that the auth token from that cookie cannot be used after $E…

Good point, but your explanation is also a bit confusing. If I understand correctly, your point is not so much "don't bother with cookie expiration" as "don't trust cookies to expire when you tell them to". In other words, the server should double-check cookie expiration dates because you don't want somebody fudging your 7-day cookie and using it to log in next year. Am I right?

Re: How to build (and how not to build) a secure “remember me” feature

#19
post #2

> A more pragmatic mitigation is to still separate the auth cookie from a dedicated “remember me” cookie and use the latter to re-authenticate the user but impose some restrictions. What are the benefits of using a separate cookie for the "remember me" feature, provided that you impose the same restrictions (e.g. requiring the password again before accessing sensitive areas of the website) and same security measures…

The justification is earlier in the article [1].

It slightly lowers the attack cross-section. If you implement the separate login cookie scheme described in the linked article[2] you also get a limited ability to detect hijacked sessions and limit the length of time an attacker has access to the account.

[1] "One argument against long expiration of auth cookies is that they’re effectively keeping the user authenticated and at risk of attacks such as CSRF or clickjacking. Of course the application needs to exhibit other risks in order for an attacker to capitalise on the long lasting cookie but the whole defence in depth argument comes up again."

[2] http://jaspan.com/improved_persistent_login_cookie_best_prac...

Re: How to build (and how not to build) a secure “remember me” feature

#20
post #2

> A more pragmatic mitigation is to still separate the auth cookie from a dedicated “remember me” cookie and use the latter to re-authenticate the user but impose some restrictions. What are the benefits of using a separate cookie for the "remember me" feature, provided that you impose the same restrictions (e.g. requiring the password again before accessing sensitive areas of the website) and same security measures…

One significant benefit is being able to enforce a one-time use policy the remember-me cookie. If you only utilize it when the user is not logged in, then you use it to authenticate, set a regular session cookie, and generate a new remember-me cookie. If an old remember-me cookie is ever used that means someone probably sniffed the cookie, and you can invalidate all sessions at that point and even force a password re…

> You can't do this with the regular session cookie because a user might have multiple tabs open.

Why not? It's considered standard practice to refresh regular session identifiers every X minutes, and this rarely causes race conditions unless your app is AJAX-heavy.

My apps regenerate the session identifier every time it detects that it has been more than 5 minutes since the last regeneration. So if a user who has been away for a few hours returns to the site, his session identifier will be immediately regenerated and the old one will become useless. If race conditions become a serious issue, I can allow the old session identifier to continue to work for the next 30 seconds or so. It also shouldn't be too difficult to add a feature that throws tantrums if someone continues to use the old one much later than that.

Post reply on HN