views:

207

answers:

5

I have a user account 'member center' that shows all of a customer's subscriptions and memberships that they have with my company. This is at https://secure.example1.com/membercenter/.

I have another site which is the actual member site. This is at http://www.example2.com/. ( each site on a different domain, though it is the same dedicated server.

I want to provide easy login to the membership site, without including the user's username and password in the link.

So what I've come up with is this:

When the user clicks the 'Login' link for their membership, I create an md5 hash of their userid + unix timestamp, and add that into a database table along with their userid and the timestamp.

I then redirect to http://www.example2.com/login?hash=(the hash).

The login script on example2 takes the hash and looks it up in that same table. If the hash is present, I retrieve their username and password from the customer database using the userid stored with the hash, and pass it into the site's pre-existing login function, and they get logged in.

When this hash login script runs, it first deletes any rows older than 5 minutes, then checks for the hash value passed. If it finds the hash, it logs the user in, and then deletes the hash that was used from the table. This means that there will never be any hashes in the table older than 5 minutes. The only time there would (should) be any hashes left over in the table is if the user somehow doesnt make it from secure.example1.com to www.example2.com after clicking the link ( say, internet goes down at just the right second, dns problems resolving example2.com, etc ). The 5 minute expiration means they can sit there and reload the redirected URL until they get in, or until 5 minutes have gone by.

When the user is redirected, they do see the hash value.

Every time the login link is clicked from secure.example2.com, a new hash value is calculated and stored.

My question is... am I missing something obvious? How would you break or hack this? Did I just create a gaping security hole in my site(s)?

Thanks SO Hive Mind!

EDIT: This is in addition to the normal model of coming to www.example2.com and logging in with a form using your username / password.

EDIT2: Response to tobyhede re: sniffing the hash. The attacker would have to also stop the user from reaching the login script on www.example2.com as the hash is deleted once used. If they were able to stop that, they would then also have to use the hash within five minutes or it would be automatically deleted.

EDIT3: Re: Attacker generating their own hashes: A hacker would have to insert those hashes into the database AND include a valid userid ( no users know their userid ). How would they do that? Since the hash is used only once and then deleted immediately, I'm not convinced any of the below attacks would work.

+3  A: 

All someone needs to do is intercept the URL with the hash and they have access to your system. You really should pass the hash over SSL using HTTP POST.

Toby Hede
A: 

If the attacker knows that the user is about to log in, the attacker can generate the hash (or a series of hashes with slightly different timestamps) and log in before the user does so. A slightly better solution is to replace the hash with a randomly generated token. Then the attacker will have to intercept the user's login request to site example2.

As long as you are using HTTP instead of HTTPS on site example2, no scheme will be secure. For example, say, you found the perfect login scheme for site example2 that is secure. However, after the login, the requests from the user will be sending the session information either in the URL or in the request headers (e.g., cookies). These requests can be intercepted and the attacker can steal the session information. In the worst case for the attacker, you'll be linking sessions to their source IP and the attacker will need to fake the source IP.

Alexander
+2  A: 

While you can't get this sort of scheme fully watertight there are number of things that could improve it:

  • Use a random seed instead of the unix timestamp when generating the key
  • Check that the referrer in the request for the second page is the the first page
  • Check that the source of the two requests is the same

A crytographic proof-of-knowledge scheme may be applicable to this situation, for the most secure approach to the problem. My brain's a bit too mushy after meetings this morning to say anything intelligent about their applicability though :)

Bell
A: 

Are the user id that the id you use in the hash and the id which the user uses to log in to the site different? That's crucial part when attacking your system with generating the hashes. Another thing to consider is that are the ids you're using easy to guess, like numbers or words?

You have to come up with a solution that contains something which is not easily guessed by the attacker. Basically you want to have a secret in your hash which is almost impossible for the attacker to guess. That's why using salt (random bits) in your hash is the way go.

I suppose you're aware of the attacks against the MD5 and SHA-1 hashes? In MD5 there's actually possibility of hash collisions (http://merlot.usc.edu/csac-s06/papers/Wang05a.pdf) where as SHA-1 is supposedly still secure, but there are also rainbow table attacks against both of the hashes.

Generating a hash with salt, user id and time stamp sounds feasible for your solution. I also suggest that you delete the hash after use.

Bleadof