防止非现场表格帖子?

时间:2011-10-13 01:09:13

标签: php forms security

我正在寻找最安全的方法,不允许我的网页表单(使用PHP和MySQL)从场外发布。我做了一些搜索,发现大多数人建议在表单中设置一个隐藏字段,并使用md5()哈希值设置一个会话变量,并在表单提交时检查它。但这似乎不太安全,因为md5()哈希值可以在隐藏值的表单源中看到。

我的想法是不允许提交网站表单。数据库调用对资源的影响要大一些,但看起来更安全,因为代码哈希永远不会发送到客户端。

请查看它,看看您是否可以在此安全措施中挖出任何漏洞,以防止非现场表格帖子。

// First time form loads
if (!$_POST) {

    session_start();

    $code_options = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9');
    for ($i=1; $i<=20; $i++) {
        $code .= array_rand(array_flip($code_options), 1);
    }

    // Insert new record
    $con = connect_to_db(); // connects to db
    $sql = "INSERT INTO security_table (form_code) values('$code')";
    $result = run_query($sql, $con); // runs the query

    $_SESSION['formcode'] = $code;
    $_SESSION['formid'] = mysql_insert_id();

}

// If form was posted to    
if ($_POST) {

    session_start();

    $con = connect_to_db();
    $form_code = mysql_real_escape_string($_SESSION['formcode']);
    $form_id = mysql_real_escape_string($_SESSION['formid']);

    $sql = "SELECT form_code FROM security_table WHERE form_code = '$form_code' AND form_id = '$form_id '";
    $result = run_query($sql, $con);

    if (mysql_num_rows($result) > 0) {

        // Process the form

        // If form processes successfully
        $_SESSION['formcode'] = "";
        $_SESSION['formid'] = "";

    }else{

        // Error

    }

}

3 个答案:

答案 0 :(得分:2)

您可以通过Web服务器配置控制对站点的访问,而不是在应用程序中执行此操作。如果您可以这样做,可以很好地分离关注点 - 服务器处理请求,应用程序只处理逻辑。

假设您正在使用Apache,并且您对apache http.conf或本地.htaccess具有读/写访问权限,则可以添加如下规则:

<Limit GET POST>
  order deny,allow
  deny from all
  allow from 199.166.210.
  allow from .golden.net
  allow from proxy.aol.com
  allow from fish.wiretap.net
</Limit>

所以,拒绝所有人,除了您选择允许的少数IP或网络地址。

See the Apache docs了解细节。

答案 1 :(得分:1)

But that doesn't seem very secure because the md5() hash value can be seen in the source of the form in the hidden value.

没关系。如果加密得足够好,那么令牌对任何人都是希腊的,因此除非你知道php脚本中的关键机制,否则无法重新创建。由于你在每篇帖子后重新生成令牌,看看它看起来像什么都不会帮助任何坏人。

您保护表单的方式基本上是“如果您有会议,那就很好”。因此,如果垃圾邮件计算机访问过您的网页一次,则安全层已通过。您拥有客户端令牌的原因是垃圾邮件发送者必须提供只能以您的实际形式获得的内容。

有很多关于stackoverflow的安全表单的讨论,例如,请查看Good Form Security - no CAPTCHA

答案 2 :(得分:0)

这是一篇很好的文章,解释了保护表单的不同方法。我用这些方法效果很好。 http://www.campaignmonitor.com/blog/post/3817/stopping-spambots-with-two-simple-captcha-alternatives