3

I have read recently that sessions work as follows:

  1. Your credentials are checked.
  2. A token is generated and stored on server side, eg UUID, and this token is given to the client where it is stored for the duration of the session.
  3. When the user logs out, their session token is revoked, and no longer valid.

My concern is that with people more and more relying on their browsers remembering their credentials and having sessions that never expire, or expire after a long period of time, this means that somebody might be able to just copy your token and bypass authentication altogether, since usernames and passwords are no longer needed: just the tokens.

Am I misunderstanding something, or is this a real issue and if it is a real issue, what are some means I can avoid this issue in building authentication systems?

Dmitry
  • 351
  • 1
  • 7
  • 2
    UUIDs are *not* a good token: they are not unpredictable enough. Instead, you need a large random number (128bits or more), preferably of crypto quality (I believe that on windows you should use: [CryptGenRandom()](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx)). – Jacco May 26 '16 at 20:34
  • @Jacco you're right, but when I said UUID, I meant a unique identifier with at least 128 bits under which, it would take at least 2^30 brute force guesses to have exactly 50% chance of guessing an active UUID in a system with 32,000,000 active UUIDs. That said, 128 bits accomplishes this so much of what I wrote is redundant. – Dmitry May 26 '16 at 22:34
  • 1
    @Jacco depends on the implementation. Java UUIDS are secure random – Neil McGuigan May 27 '16 at 02:36
  • @Jacco - I would interpret UUID without further context to be exactly 128 bits: https://en.wikipedia.org/wiki/Universally_unique_identifier – TTT May 27 '16 at 14:05
  • @TTT 128 bits is nice. But if it is unevenly distributed, its not nearly as good as crypto quality random 128bits. Apparently, the Java UUIDs are truly random, where the windows ones are not (they are meant to be unique; being unpredictable is not a requirement for that). – Jacco May 27 '16 at 20:18
  • @Jacco - got it. You can use this in c#: http://stackoverflow.com/questions/1668353/how-can-i-generate-a-cryptographically-secure-pseudorandom-number-in-c – TTT May 27 '16 at 21:10

1 Answers1

4

First off, I'm not sure I completely follow this statement:

My concern is that with people more and more relying on their browsers remembering their credentials and having sessions that never expire, or expire after a long period of time, this means that somebody might be able to just copy your token and bypass authentication altogether...

The browser remembering credentials is entirely independent from the website sessions lasting a long time. In fact, having your browser remember your credentials is a convenience so that you don't need to click on the "remember me" option on a website, so one could argue that allowing browsers to store credentials makes you more likely to logout and make your session shorter rather than longer. That being said, I do understand where you're headed with the question, so let's assume you aren't storing credentials in the browser, and instead are clicking on the "remember me" option so you have a session that lasts for a long time (maybe months). How insecure is the "remember me" option?

The remember me option is insecure in either of the following scenarios:

  • You are on a shared computer where someone else has access to the same user you use, or someone else has admin access to the computer you use. In this case another user of the computer can look at your authentication cookies and copy your token as you suggested.
  • The site is using http instead of https. In this case someone sniffing the network can capture your session token in transit.

Some things you can do to help prevent from token snatching are:

  1. Use https.
  2. Use a short-lived authentication token in combination with a long-lived refresh token.

If implemented properly the refresh token accomplishes a couple of things. Since the refresh is only passed periodically instead of with every request, it is less likely to be compromised in the first place. When the refresh occurs, all existing authentication tokens that were created with that refresh token are automatically expired, so if the refresh is ever compromised, and two users try to use it simultaneously, there would be a continuous fight over the auth token and multiple refreshes would occur before expiration. The server could easily detect this and expire the refresh token too. Then the user would have to login again and only the real user would be able to do that. More info about this can be found here.

TTT
  • 9,122
  • 4
  • 19
  • 31
  • Great answer. I'll need a bit of time to understand it. Your long paragraphs are a bit challenging. – Dmitry May 26 '16 at 20:22
  • From what I understood, you are saying that it is indeed a security issue to use remember-me option with no refreshing, but only if either somebody has either physical or remote access to your computer. You are also saying that you can make it more secure by refreshing the token and invalidating old ones, making it obvious to you if somebody else may be using your session(in which case you can simply change the password and invalidate old sessions and you are good since the attacker likely won't be able to change your password using session token alone). – Dmitry May 26 '16 at 20:31
  • 2
    I wouldn't say it's definitely a security issue to have remember-me without refresh tokens, just that if you (the website owner) are worried about it, you can use https and/or refresh tokens to help prevent/detect token snatching. Note the refresh token is implemented by the server and is seamless to the end-user. The end user may not notice their session was hijacked, since the refresh mechanism happens automatically behind the scenes. The website owner could detect it if they care to. – TTT May 26 '16 at 20:40
  • @TTT Your answer made it more clear for me, thank you. But just one more question. I was reading about how to store a `refresh_token` and I've read someone saying that you can store it in `localStorage` without any problems because the attacker needs to get the token from outside your network. So reading Spotify's `store` it has a `session` object where they store the `accessToken` with 1 hour of expiration, but they never store the refresh token on the client side. If I have a Javascript app, would it be a problem to store it in `localStorage`? – FacundoGFlores Apr 19 '17 at 13:04