Is using microtime() to generate password-reset to

2019-01-26 11:42发布

问题:

In PHP I've noticed some frameworks make use of the microtime() function to generate password reset tokens as in:

  $token = md5(microtime());

Is this a security issue? If the attacker is able to synchronize the clocks with the server to a degree of accuracy they could brute force the token. 1sec synchronization will only require 1,000,000 tries and this is not too crazy of an issue.

How likely is this attack to succeed? Should one be generating tokens with /dev/urandom or openssl_pseudo_bytes() instead? Is microtime() bad practice?

回答1:

Yes it is a security issue! Generating tokens with time is a very bad practice. Burp Suite makes it trivial for an attacker to brute force tokens that are predictable, and tokens based on time are very predictable. Burp allows someone to easily gather tokens and perform statistical analysis on them to determine entropy. Using this info you can easily predict future tokens.

Remember, the attacker only needs to get it right once. Getting it wrong millions of times makes no difference.

Here is a useful (and recent) StackOverflow post about token generation that may be helpful to you: REST Web Service authentication token implementation



回答2:

Tokens should always be created at random, not microtime. Now to give some extra securty (because, let's face it once again: computers cannot do anything but calculate stuff), you'll want to see php's example: http://php.net/manual/de/function.srand.php Also see http://php.net/manual/de/function.chr.php to easily create a "completely" random string. Here's how I do it

mt_srand((double) microtime() * 1000000);
    function random_string ($length = 16)
    {
        $string = "";
        for ($n = 0; $n < count($length); $n++) $string .= chr(rand(32, 126));
        return $string;
    }



回答3:

Yes, it is (I think).
A hacker might able to guess the password in 1 to 2 hours. (If the server use a limit how much resets can be taken the hacker can avert it by using a Botnet or with having a lot of time and lots of trials.

If I were you I would add a static salt. The salt should be loaded from a config (or an other secure place). The salt should not be set by the server own or whoever. It should be generated by a real-random API (google should help you but I guess random.org offers one).
If you are not able to use that API a pseudo salt should help, too as long as the hecker don't know when the server has been set up (or the server admin might delete it sometimes, but not automatic!)

Example:

$salt = null;
include('protectedDir/salt.php'); // Here should stand "$salt = ''"
if ($salt == null){
// Using real random api
file_put_contents('protectedDir/salt.php', '<?php \$salt = \'$salt\'; ?>)";
}

$resetKey = sha1(microtime() . $salt);

// May contain bugs. Untested. It is only a example and should not be implemented by copying and pasting.

If the hack has access to the php file ('protectedDir/salt.php') "source code" he should be able to see database configs, too. And it would be an bigger problem.