【发布时间】:2013-04-23 15:45:48
【问题描述】:
我知道我已经asked了一个关于消毒和逃逸的问题,但我有一个问题没有得到回答。
好的,就这样吧。如果我有一个 PHP 脚本并且我 GET 用户输入和 SELECT 它来自一个 mySQL 数据库,如果我没有通过使用来逃避 < 和 > 是否有任何安全风险? htmlspecialchars、htmlentities 或 strip_tags,因此允许从数据库中选择/搜索 HTML 标签?因为输入已经通过使用trim()、mysql_real_escape_string 和addcslashes (\%_) 进行了清理。
使用htmlspecialchars 的问题在于它转义了与号(&),这是用户输入应该允许的(我猜htmlentities 也是如此?)。通过使用strip_tags,类似“John”的内容会导致 PHP 脚本为 John 选择并显示结果,这是不应该的。
这是我的 PHP 代码,用于在从数据库中选择之前清理输入:
if(isset($_GET['query'])) {
if(strlen(trim($_GET['query'])) >= 3) {
$search = mysql_real_escape_string(addcslashes(trim($_GET['search']), '\%_'));
$sql = "SELECT name, age, address WHERE name LIKE '%".$search."%'";
[...]
}
}
这是我显示“x 匹配 y 结果”的输出。
echo htmlspecialchars(strip_tags($_GET['search']), ENT_QUOTES, 'UTF-8')." matched y results.";
【问题讨论】:
-
应该为您的目标环境进行清理/转义。 html 不能“影响” sql,因此将其保留在数据库中是安全的。事实上,最好不要转义,直到您检索它并尝试在浏览器上下文中显示它。如果您实际上是在寻找某些东西,这可以避免您不必转义,并消除双重转义的可能性,例如
&amp;amp; -
好的,谢谢。所以,我所做的似乎足够正确,是吗?
-
没有。你是不推荐使用的 mysql_*() 函数。切换到 mysqli 或 PDO。并删除 addcslashes() 调用。这是不必要的,只是为数据库中的数据添加了另一层毫无意义的转义。 mysql_real_escape_string 是您在查询中安全使用表单数据唯一需要的。
-
我知道我正在使用已弃用的
mysql_*()函数。正如我对@jball037 所说,我之前曾多次被建议过。但我只是想知道我上面提到的是否会削减它。顺便说一句,addcslashes用于保护我的 PHP 脚本不显示数据库中的所有内容,因为mysql_real_escape_string(据我所知)不会转义通配符,例如%和_.我之所以在其中添加 ``,是因为搜索“John's”会在数据库中搜索“John's”,这不是这里的意图。 -
您希望您的用户在搜索框中输入
John\'s?那永远飞不起来。您让他们输入他们想要的任何内容,然后使用适当的转义将这些数据安全地放入查询中。请记住:mysql 在文本中实际上并没有 SAVE 反斜杠。它们作为查询解析阶段的一部分被删除。如果你有INSERT ... VALUES ('John\'s'),那么John's是实际保存在数据库中的,而不是John\'s。