@Jeremy - 一些 PHP 细节
当涉及数据库查询时,请始终尝试使用准备好的参数化查询。这mysqli
and PDO
图书馆支持这一点。这比使用 mysql_real_escape_string 等转义函数安全得多。
是的,mysql_real_escape_string 实际上只是一个字符串转义函数。它不是灵丹妙药。它所做的就是转义危险字符,以便它们可以安全地在单个查询字符串中使用。但是,如果您不事先清理您的输入,那么您将很容易受到某些攻击媒介的攻击。
想象一下以下 SQL:
$result = "SELECT fields FROM table WHERE id = ".mysql_real_escape_string($_POST['id']);
您应该能够看到这很容易被利用。
想象一下id
参数包含常见的攻击向量:
1 OR 1=1
它们的编码中没有危险的字符,因此它将直接通过转义过滤器。离开我们:
SELECT fields FROM table WHERE id = 1 OR 1=1
这是一个可爱的 SQL 注入向量。
虽然这些功能很有用,但必须小心使用。您需要确保所有网络输入都在某种程度上得到验证。在这种情况下,我们发现我们可以被利用,因为我们没有检查我们用作数字的变量实际上是数字。在 PHP 中,您应该广泛使用一组函数来检查输入是否为整数、浮点数、字母数字等。但是当涉及 SQL 时,请最注意准备好的语句的值。如果上面的代码是一个准备好的语句,那么它就是安全的,因为数据库函数会知道1 OR 1=1
不是有效的文字。
至于htmlspecialchars()。这本身就是一个雷区。
PHP 中存在一个真正的问题,因为它有一系列不同的 html 相关转义函数,并且没有明确说明哪些函数具体做什么。
首先,如果您位于 HTML 标记内,那么您就有麻烦了。看着
echo '<img src= "' . htmlspecialchars($_GET['imagesrc']) . '" />';
我们已经在 HTML 标签内,所以我们不需要 来做任何危险的事情。我们的攻击向量可能是javascript:alert(document.cookie)
现在生成的 HTML 看起来像
<img src= "javascript:alert(document.cookie)" />
攻击直接通过。
情况变得更糟。为什么?因为 htmlspecialchars 只编码双引号而不是单引号。所以如果我们有
echo "<img src= '" . htmlspecialchars($_GET['imagesrc']) . ". />";
我们邪恶的攻击者现在可以注入全新的参数
pic.png' onclick='location.href=xxx' onmouseover='...
gives us
<img src='pic.png' onclick='location.href=xxx' onmouseover='...' />
在这些情况下,没有什么灵丹妙药,您只需自己清理输入即可。如果你尝试过滤掉坏字符,你肯定会失败。采用白名单方法,只允许好的字符通过。看着那(这XSS 备忘单 http://ha.ckers.org/xss.html有关向量如何多样化的示例
即使您在 HTML 标记之外使用 htmlspecialchars($string),您仍然容易受到多字节字符集攻击向量的攻击。
最有效的方法是使用 mb_convert_encoding 和 htmlentities 的组合,如下所示。
$str = mb_convert_encoding($str, ‘UTF-8′, ‘UTF-8′);
$str = htmlentities($str, ENT_QUOTES, ‘UTF-8′);
即使这样,IE6 仍然容易受到攻击,因为它处理 UTF 的方式。但是,您可以回退到更有限的编码,例如 ISO-8859-1,直到 IE6 使用率下降。