2

when the user want to reset his password , I send to his email a 6 digits code, then I check if the user enter the matched code !

I am generating the code using rand function :

$code = rand ( 100000, 999999 );

is it safe to do that ?

david
  • 3,310
  • 7
  • 36
  • 59
  • Depends on your definition of "safe". If the code is only valid for a couple of hours, it's probably fairly safe. `rand()` in general is not considered to be a good option, so if you can, use `mt_rand()` instead. Even better would be if you used `openssl_random_pseudo_bytes()` to generate a random "code". – Till Helge Feb 24 '15 at 12:43
  • I guess it's pretty safe, since a hacker would have to try all the codes to reset a users password. You could also firsly send a email with a comfirmation link that he would like to reset his pass, and if clicked, then it will send a code he would have to use – Jesper Feb 24 '15 at 12:43
  • 1
    @TillHelge tank you for your response, but what the different between mt_rand() and rand() , and How to generate 6 digit code using openssl_random_pseudo_bytes() – david Feb 24 '15 at 12:55
  • @Djip but does it possible to guess what the code , that will be sent ? – david Feb 24 '15 at 12:57
  • @david brute forcing.. Just check every single possible way 6 digits can stand, and then a hacker would be able to reset peoples password. IF after you've pasted the code, you'll get some input fields to reset it. Not if a random password is sent to the users email. Imagine a hacker getting access to a admin because of easy brute-forcing a 6 digit code. – Jesper Feb 24 '15 at 13:02
  • @david If you want to make this kind of system fairly safe, disable the function for an account, if three wrong codes have been used. Also, the codes should expire after a couple of hours. This makes brute force attacks pretty infeasible. Regarding your questions: Check out [this question](http://stackoverflow.com/questions/7808021/whats-the-disadvantage-of-mt-rand) and [this documentation page](http://php.net/manual/en/function.openssl-random-pseudo-bytes.php). :) – Till Helge Feb 24 '15 at 13:09

1 Answers1

2

No. Let's say you want to reset a privileged user's password. All an attacker has to do is issue a bunch of resets for an unprivileged account (or multiple accounts) that they control to predict the next random value. Which means they can then request a password reset for the privileged user (e.g. "Admin") and then take over the account.

More information:

If you really want unpredictable random numbers for any sort of security feature, feel free to use this library that I wrote and maintain:

https://github.com/resonantcore/lib/blob/master/src/Secure.php

$iRandom = \Resonantcore\Lib\Secure::random(100000, 999999);

Note that this is soon going to be adopted/refactored into this repository in the near future (and the functions offered may even make it into the PHP 7 core): https://github.com/SammyK/php-src-csprng

$iRandom = random_int(100000, 999999);

It's not there yet, though. My code works today.

If you don't trust me, you can also check out Anthony Ferrara's wonderful RandomLib project: https://github.com/ircmaxell/RandomLib

$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new SecurityLib\Strength(SecurityLib\Strength::MEDIUM));

$iRandom = $generator->generateInt(100000, 999999);

Don't use rand() or mt_rand() for any authentication (or authentication bypass) purpose. Ever.

Also, you may want to use something with a larger brute-force space than a 6 digit number. A hex-encoded 32-byte string should be sufficient for stopping both practical and all known theoretical attacks.

Community
  • 1
  • 1
Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206