4

I'm starting to develop the user's registration on my project. The users would confirm their registering by a link sent by email.

I thought I could use the email inserted on the form, plus a random salt, and hash this concatened string, so that becomes each string token unique. The link would be something like this:

http://www.example.com/register/7ddf32e17a6ac5ce04a8ecbf782ca509

I think it's good and easy to build, but I'm not sure if it's secure enough.

I'm developing this project using CakePHP 2.7 and SQL Server 2014.

Keoma Borges
  • 683
  • 2
  • 12
  • 27
  • 1
    See https://github.com/cakephp/cakephp/pull/8297 - this will also soon be available in 2.x. If you use the Tools plugin, you can use the [Tokens](http://www.dereuromark.de/2010/06/25/tools-plugin-part1-codekey/) there, as they got it already built in. – mark Feb 21 '16 at 18:41

3 Answers3

9

It really depends on how you generate the MD5. Just ensure your data is random. I don't use MD5 for generating these types of hashes, and instead will do something like:

$email_token = openssl_random_pseudo_bytes(16);
$token = bin2hex($email_token);

Personally, I would opt for something like this using random_bytes if using PHP7.

$email_token = bin2hex(random_bytes($length));

For PHP5 there's a polyfill available: https://github.com/paragonie/random_compat

BugHunterUK
  • 8,346
  • 16
  • 65
  • 121
  • It's a really good idea, but is this not computationally expensive? Every time I create a token, I'm going to have to verify, in database, if that token has not been created. – Keoma Borges Feb 21 '16 at 16:22
  • Generating the token when inserting the user into the database is going to come at a little more cost than MD5, but you won't really notice the difference unless you're talking serious traffic/usage. As for checking the key when the user validates their email, this isn't going to cost any more resources than checking an MD5. You're just checking to see if they match. – BugHunterUK Feb 21 '16 at 16:28
  • I see. I think that's the solution I was looking for beacuse it agrees with the other answers. Thank you so much. – Keoma Borges Feb 21 '16 at 16:36
2

You should think about what a potential attacker could do if he is able to generate tokens that do not belong to him and then decide if the MD5 hash is good enough.

If I got it correctly you just want to verify a users email and only create an account if the user really owns the email address. Would it be bad for you or the owner of the address if an attacker creates 1000 accounts with faked emails?

As always, security depends on the situation, IMO.

If you want to play it safe, don't let your token depend on user data. Generate a completely random token and save it beside the pending registration in your database.

siegi
  • 5,646
  • 2
  • 30
  • 42
  • That's the salt idea. The salt would be a random string which I'd concatenate with the user's email and hash it. – Keoma Borges Feb 21 '16 at 15:40
  • Yes, but if an attacker gets to know your salt, he can generate valid tokens for any email. If you generate a complete random token for every registration, this is not possible. – siegi Feb 21 '16 at 15:42
  • I see. You're right. I'll not use user's data to create the tokens. – Keoma Borges Feb 21 '16 at 16:24
1

Use a completely random value for the user which you generate at the time of registration, run it through 'sha1' or 'sha2', store it in the db, and use that in the email. Then you just check if that value is in the database. If you wanted to additionally associate the hash with another data point (such as their email) all the better.

random_user_name
  • 25,694
  • 7
  • 76
  • 115
  • If the initial value is completely random there is no point in hashing it; it does not add any security. Of course, it all depends on the random function, but that's an entirely different problem. – JvO Feb 21 '16 at 22:23
  • 2
    Use the unhashed version in the email. The hashing the stored versions can prevent any data leak from enabling the values to be used by an attacker. – SilverlightFox Feb 23 '16 at 11:12