views:

83

answers:

2

I have a Mothership domain, and if you log into it, a token is created in the database for your login with user Id, created datetime, expiry datetime and user agent. The expiry is set to an hour after the token was made (created when the user logins).

To be able to login from Mothership to Scoutship, I append a query string like so

<a href="http://www.spaceship.com?user=ahs6588ads6d8das"&gt;go to spaceship</a>

Then on the scoutship, it looks up the database like so:

$query = "SELECT user_id FROM user_tokens
                    WHERE token = $tokenFromUrl
                        AND user_agent = $thisUserAgent
                        AND expires > NOW()
            LIMIT 1";

If it finds a match, it logins the user, and then sends location headers to remove the query string.

Obviously, if someone accessed that URL, it will log them in as whoever it is (provided they came within the hour of login of the old site, and have the same user agent string). This to me doesn't sound as secure as it should.

Is there a way to beef up this security? Should I have a column in the db like has_auto_logged_in and set it to TRUE for the first lookup, and deny all incoming requests after that?

Many thanks

UPDATE

Here is what I came up with

  • Every request creates a new nonce with a 15 minute expiry date and saves user agent
  • Adds the nonce hash to outgoing URLs in the query string
  • New site will ensure hash matches a nonce, and is within the 15 min expiry and has the same user agent. It will then delete that nonce.
  • Sends location headers to remove the query string.

So, is the only way one could defeat this is if person A is on the site and person B (hacker)

  • Have the exact same user agent string (or forge it)
  • Observe the hash and visit it in their own browser, but within 15 minutes and before person A makes any new request

Is there much more you could do besides this? You could probably put am AJAX script that gets a new hash and updates the links, but is that more trouble than it's worth?

+6  A: 

Try a nonce. I even reserve a table for stuff like this

When the user is going to be redirected, create a random hash based on the time, user id, etc. Send that over the URL. When the URL redirects and it tries to log the user in on the other side, it checks if the nonce is in the database. If it is, it logs the user in and deletes the nonce. If it isn't, it denies the user.

You can even add an expiration.

Chacha102
(http://en.wikipedia.org/wiki/Cryptographic_nonce)
Amber
good one. could this be used for every page call (performance hit)?
henchman
I'd put a cache. Like, generate it on the first call, then check for an existing one for this user, and regenerate every 5 minutes, hours, however long. I wouldn't be too worried though, if you design it right, a simple insert isn't going to do much
Chacha102
You could even make a middle page, where you direct the link to `redirect.php?site=scoutship`, where it would make the nonce, and redirect.
Chacha102
Thanks for your answer Chacha102. I've made an update to my question, let me know if you foresee any problems. Cheers.
alex
A: 

Thats the way security works in many implementations. You can see these when having a SID-parameter in url or cookie. The only way to make these more secure is to use a larger id.

henchman