如何制作一个“Spinner”来提高php表单的安全性?

时间:2010-07-13 04:12:52

标签: php security spinner

这篇关于php表单安全性的文章:

http://nedbatchelder.com/text/stopbots.html

......提到一个“旋转器”:

  

微调器是用于的隐藏字段   一些事情:它汇集在一起   阻止的值的数量   篡改和重播,并习惯于   模糊的字段名称。微调器是一个   MD5哈希:

* The timestamp,
* The client's IP address,
* The entry id of the blog entry being commented on, and
* A secret.
     

表单上的字段名称都是   随机。他们是哈希   真实的字段名称,微调器和a   秘密。微调器得到一个固定的字段   名称,但所有其他字段   表格,包括提交   按钮,使用散列字段名称。

有没有人有一个代码示例,说明如何在包含表单和关联的php表单提交脚本的php页面上实现这一点?

我不想使用AJAX,只需PHP。

2 个答案:

答案 0 :(得分:0)

您可以实施以下内容:

  On Page Submit:
  <?php
    $spinnerKey = 'spin';
    $spinner = $_POST[$spinnerKey];
    $values = array();

    foreach ($_POST as $key=>$value)
    {
      if ($key !== $spinnerKey)
      {
        $values[deHash($key, $spinner)] = $value;
      }
    }
?>

A 'deHash' example:
<?php

    # You have to define deHash based on your hash but it 
    # would look something like this:
    var $_rainbowTable = array();
    var $_expectedKeys = array();

    function deHash($hashedkey, $spinner)
    {
        $rt = $this->getRainbowTable($spinner);

        return isset($rt[$hashedKey])
          ? $rt[$hashedKey])
          : NULL;
    }

    function getRainbowTable($spinner)
    { 
        if (count($this->_rainbowTable) > 0)
            return $this->_rainbowTable;

        foreach ($this->_expectedKeys as $key)
        {
            $this->_rainbowTable[hash($key, $spinner)] == $key;
        }

        return $this->_rainbowTable;
    }
  ?>

最终虽然我没有看到这是如何阻止机器人提交你的页面 - 它只是阻止人们的“电子邮件/用户/通行证”记住浏览器插件的工作。

答案 1 :(得分:0)

如果在页面加载时创建具有随机值的会话,该怎么办? 例如 $_SESSION['name_for_email'] = 'something_random';

然后输入字段

<input type="text" 
name="<?php echo htmlspecialchars( $_SESSION['name_for_email'], ENT_QUOTES, "UTF-8");?>"
>

似乎更好地使用ajax。访问者点击发送,将所有数据传递到外部php,在外部php调用$_SESSION['name_for_email']中,因此可以知道电子邮件字段名称。

如果没有ajax,则发布和页面重新加载,但在页面顶部创建了新的$_SESSION['name_for_email']。因此,处理输入表单的PHP代码必须在定义$_SESSION['name_for_email']

之前

如果输入字段很多,那么必须使用多个会话。可能更好一些简化版本。

$_SESSION['name_for_email'] = 'something_random';

<input type="text" 
name="field1<?php echo htmlspecialchars( $_SESSION['name_for_email'], ENT_QUOTES, "UTF-8");?>"
>

只需要记住,field1用于发送电子邮件,field2用于名称,等等。

但......再想一想。主要问题是机器人要么没有$_SESSION['name_for_email'],要么对于机器人来说,价值不正确。好吧,机器人&#34;看到&#34;电子邮件,&#34;类型&#34;电子邮件。

如果使用$_SESSION['name_for_email']定义一些隐藏字段,并且在处理输入之前检查$_SESSION['name_for_email']是否与隐藏输入字段中的相同,我想这将是相同的效果。因为,如果机器人知道正确的随机值,那么输入字段名也是正确的。