Split token for PHP login - timing attack

262 Views Asked by At

I am creating a PHP login system. User will receive email with a onetime link to the website where the one-time link is gonna be checked and token provided as a cookie/session. My question is how to split the token and/or onetime link to prevent timing attacks.

My sessions table:

- uid (AI PK)
- datecreated (when welcome email sent with one-time link)
- datevalidated (once one-time link is confirmed and token loaded to the user as cookie/session)
- email (email to which the welcome email has to be sent)
- onetimelink (https://example.com/login/$onetimelink - sent via email)
- token (token which authenticates users for up to a week)

Tokens will be generated with the following code and saved to the db:

$onetimelink = bin2hex(random_bytes(15));
$token = bin2hex(random_bytes(15));
1

There are 1 best solutions below

5
On

Here's how I would do this.

When generating the email

  1. Create a hard-to-guess random text string token using a technique like this one. PHP random string generator. 20 characters at five bits/character give you 100 bits of randomness in the token. That should be more than enough.

  2. Use php password_hash() to handle that token as if it were a password.

  3. Store the output from password_hash() in your SQL table. DO NOT store the actual token in your table.

  4. Put the token in the URL of your email. (&token=zSBXsEkhNX6S8h5fjFbB for example)

When verifying the token when the user presents the URL from the email

  1. Read the hashed token from your SQL table.

  2. Use password_verify() (which is designed to be safe from timing and other cybercreep attacks) to validate the token that came in on the URL. If password_verify() fails reject the request with a very generic message like "sorry, link invalid", not "your token was wrong."

  3. When the token is verified, UPDATE or DELETE the row in the table so the hashed token is no longer present.

When maintaining your table

DELETE or UPDATE rows containing stale (too-old) hashed tokens. Don't leave the hashes for stale tokens floating around in your system.

If you do things this way you use tried-and-true cryptographic modules. That's safer than creating your own. Unless you're Bruce Schneier or Whit Diffie, that work is best left to experts.

This kind of token is called a