【问题标题】:Create a Secure PHP Petition创建安全的 PHP 请愿书
【发布时间】:2012-07-23 03:09:18
【问题描述】:

我启动了一个带有在线承诺组件的网站,但它不断被使用 html/javascript 的人入侵/利用,导致签名页面上发生疯狂的事情。我不知道如何从字段中编写非 alpha 脚本以防止这种情况发生。

下面是我用来在数据库中记录表单数据的代码。关于如何实现 preg_replace 函数的任何建议(如果这是最好的)?另外,这是防止漏洞利用的最佳位置,还是有其他更理想的地方?

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {
    $insertSQL = sprintf("INSERT INTO signature (FirstName, LastName, Email, State, Country, `TSDate`, IP) VALUES (%s, %s, %s, %s, %s, %s, %s)",
                   GetSQLValueString(($_POST['FirstName']), "text"),
                   GetSQLValueString(($_POST['LastName']), "text"),
                   GetSQLValueString(($_POST['Email']), "text"),
                   GetSQLValueString(($_POST['State']), "text"),
                   GetSQLValueString($_POST['Country'], "text"),
                   GetSQLValueString($_POST['Date'], "date"),
                   GetSQLValueString($_POST['IP'], "text"));
mysql_select_db($database_petitionscript, $petitionscript);
$Result1 = mysql_query($insertSQL, $petitionscript) or die(mysql_error());
}

【问题讨论】:

    标签: php mysql database-security


    【解决方案1】:

    你应该用 htmlspecialchars 包装你所有的 $_POST 变量

    http://php.net/manual/en/function.htmlspecialchars.php

    另外,如果你使用的是 PHP5,你应该使用 PDO 对象来连接数据库,并且你不应该将 vars 直接放入 MySQL 查询中(这允许 SQL 解析器从用户那里注入 SQL 代码)。您需要使用参数化查询。 How can I prevent SQL injection in PHP?

    (实际上我刚刚意识到您正在使用参数化查询)

    【讨论】:

    • @user1544815 询问如何防止疯狂的 HTML/JavaScript 漏洞利用(通常是 XSS),而不是 SQL 注入预防。
    • @uzyn 据说GetSQLValueString 函数正在阻止SQL注入。
    • @AndrewM 是的,因此我的评论是原始发布者询问的是 XSS 预防,而不是 SQL 注入。
    【解决方案2】:

    使用 htmlentities() 清理所有输出。

    例如,而不是做

    <?php echo $FirstName; ?>
    

    做:

    <?php echo htmlentities($FirstName); ?>
    

    这将阻止您描述的疯狂 HTML/JavaScript 的 XSS 攻击。

    此外,为了防止 SQL 注入,您还应该在保存输入($_POST 数据)之前对其进行清理。

    【讨论】:

    • 谢谢,乌津!认为这里提供的功能足以清理 $_POST 数据? css-tricks.com/snippets/php/sanitize-database-inputs
    • @Sam 您所看到的不是对数据库输入进行太多清理,而是在显示时安全输出(使用htmlentities())。
    • 我相信您正在使用的GetSQLValueString() 已经在为您处理 SQL 清理。
    【解决方案3】:

    您可以使用表单标记。 实施可能需要一点时间,但很简单:

    当 PHP 提供表单时,生成一个随机字符串并将其作为“令牌”保存到数据库中。 在表单上有一个带有该令牌的隐藏字段。

    当您收到用户提交的表单数据时,仅当提供的令牌存在于数据库中时才对其进行处理。 (然后删除令牌)。

    这将有助于防止人们自动化提交表单的过程,因为他们每次都需要重新加载表单并提交令牌(大多数脚本小子不会打扰。)

    您可以通过执行诸如将令牌绑定到用户会话以及只允许每个会话一个令牌等操作来更进一步,但这可能是一个很好的起点。

    实际上,看起来这可以只使用session 而不接触数据库来完成,可能会更容易一些。

    【讨论】:

    • 不过,这无助于防止 XSS。任何人都可以访问他的页面并复制/粘贴 HTML/JS,但问题仍然存在。
    • 但是他们复制的 HTML 里面会有一个硬编码的令牌,它只能工作一次。
    • 不,我的意思是如果他们在名称输入中键入&lt;script src="http://example.com/badThing.js"&gt;&lt;/script&gt;,则令牌不会阻止这种情况。此外,任何浏览器自动化脚本(即 AutoIt 脚本)也会使令牌变得无用,因为它只会模拟用户在字段中输入值。
    • 这可以防止僵尸攻击,而不是 XSS。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 2011-11-01
    • 2011-12-03
    • 2010-09-16
    • 2021-10-05
    相关资源
    最近更新 更多