随机数的严重错误

时间:2014-10-07 21:27:42

标签: php apache

我终于可以创建一种方法来重现我所拥有的错误。当2个或更多用户在同一秒内调用页面时,modsecurity会向两个用户生成相同的随机数序列(使用来自php的rand()函数)。

以下是该错误的演示:

http://quemfazsite.com.br/em_criacao/modelo9/teste.php

打开此页面,将加载2个iframe,每个iframe应该彼此独立生成随机数,但两个帧都生成相同的随机数序列!非常简单的源代码如下所示。如果您没有看到相同的序列,我会要求您重新加载页面几次,直到您获得相同的序列顺序。

编辑:此错误仅在modsecurity激活时发生。如果您评论" LoadModule"加载modsecurity的行不会发生错误!

<?php

if (isset($_GET["test"])) {

        $output= "";

        for ($i=0;$i<10;$i++) {

                $output.= rand(0,99999999) . "<br />";

        }

        echo $output;

        exit();

}

?>
<iframe src="PUT_THE_SAME_NAME_OF_THIS_FILE_HERE.php?test&953487"></iframe>
<iframe src="PUT_THE_SAME_NAME_OF_THIS_FILE_HERE.php?test&234322"></iframe>

1 个答案:

答案 0 :(得分:2)

rand并非旨在生成随机数。其目的是生成在给定端点之间均匀分布的pseudorandom numbers。如果你对你生成的数字进行直方图,你会发现它们确实是均匀分布的。

生成这些数字的算法完全是确定性的。如果您提供相同的种子(通常基于当前时间,如您的示例),您将获得完全相同的数字序列。这是一个功能,而不是一个错误:它允许您利用分布的统计属性,同时通过重用种子来重现结果。

如果您需要随机数不可预测,则应使用cryptographic RNG

如果您只是想要有力地避免这样的冲突(由时间衍生的种子冲突引起),那么您将不得不检查某种跨会话存储以确保唯一性(例如文件或数据库)。如果您的应用程序要求数字始终是唯一的,那么您应该这样做。