在大多数情况下,mysql_real_escape_string
是否足以清理用户输入的内容?
::编辑::
我主要考虑防止SQL注入,但最终想知道是否可以信任应用程序和数据库中传递的用户数据,在使用 mysql_real_escape_string 后是否需要采取额外措施来清理数据。
我知道清理 HTML 字符很重要,但我认为它不是信任用户输入所必需的。
T
mysql_real_escape_string
并不能在所有情况下都足够安全,但它绝对是非常好的朋友。更好的解决方案是使用预处理语句。
//example from http://php.net/manual/en/pdo.prepared-statements.php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
另外,不要忘记 HTMLPurifier 可以用于丢弃任何无效/可疑字符。
...........
编辑: 根据下面的评论,我需要发布这个链接(我之前应该做过抱歉混淆)
mysql_real_escape_string() versus Prepared Statements
引用:
mysql_real_escape_string()容易出现与addslashes()类似的问题。
Chris Shiflett(安全专家)
mysql_query("select * from user where id=".mysql_real_escape_string($_GET[id]));
POC漏洞利用代码:
http://localhost/sql_test.php?id=1 or sleep(500)
这个补丁是在id周围使用引号:
mysql_query("select * from user where id='".mysql_real_escape_string($_GET[id])."'");
最佳方法是使用参数化查询,这是许多人指出的。Pdo 很好用, adodb 是 php 的另一个流行库。
如果你确实要使用 mysql_real_escape_string ,那么它只应该用于防止 SQL 注入等问题,而不应该用于其他用途。漏洞高度依赖于数据的使用方式。应该根据函数来应用安全措施。是的,XSS 是一个非常严重的问题。不过滤 HTML 是一个严重的错误,黑客会利用它来攻击你。请阅读 xss faq。
mysql_real_escape_string()
不适用于为 SQL 转义 字符串。编辑:是的,预处理语句更好。 - jasonbarmysql_real_escape_and_quote_string()
。再次强调,这并不是函数本身的问题,而是由于错误的使用导致的问题。我仍然希望看到一个 mysql_real_escape_string()
无法解决的例子。 - jasonbar什么情况?
对于SQL查询,这很好。 (准备好的语句更好 - 我投 PDO - 但函数可以很好地转义。) 对于HTML等内容,它不是工作的工具 - 尝试一个通用的 htmlspecialchars
或一个更精确的工具,如 HTML Purifier。
针对编辑进行回应: 您可以添加的唯一其他层是数据验证,例如确认如果您将整数放入数据库,并且您期望获得正整数,则在尝试输入负整数时向用户返回错误。就数据完整性而言,mysql_real_escape_string
是最好的转义工具(尽管准备好的语句是一种更干净的系统,可以完全避免转义)。
<?php echo $_GET['name']; ?>
。 - Matchumysql_real_escape_string()
函数仅仅能够预防 SQL 注入攻击,但它无法帮助你预防跨站脚本攻击。针对这种情况,建议在输出用户输入的数据之前,使用 htmlspecialchars()
函数进行处理。
你可以尝试两种方式,就像这样
function clean_input($instr) {
// Note that PHP performs addslashes() on GET/POST data.
// Avoid double escaping by checking the setting before doing this.
if(get_magic_quotes_gpc()) {
$str = stripslashes($instr);
}
return mysql_real_escape_string(strip_tags(trim($instr)));
}
有两种方法,一种是使用预处理语句(如其他答案中提到的),但这会使您的应用程序变慢,因为现在您需要向数据库发送两个请求,而不是一个。如果您可以接受性能下降,那就去用吧;预处理语句使您的代码更漂亮,更容易处理。
如果您选择使用mysql_real_escape_string,请确保转义所有不可信任的字符串。(mysql_real_escape_string)转义后的字符串是SQL注入安全的。如果您没有转义所有的字符串,则不安全。您应该真正将mysql_real_escape_string与输入验证结合使用;检查您期望保存数字的变量是否真的是数字,并且在预期范围内。记住,永远不要相信用户。
有不同类型的“清理”。
mysql_real_escape_string 对于数据库数据已足够,但如果是HTML,则仍将由浏览器在显示时进行评估。
要从用户输入中删除HTML,可以使用strip_tags。
我建议您考虑使用PDO而不是常规的MySQL内容,因为它支持预处理语句,这些语句可以直接处理无效数据的转义。
我想提醒一下,PHP 5.2+ 版本已经拥有输入过滤函数,可以以各种方式对用户输入进行消毒处理。
这里是手册入口,以及Matt Butcher的博客文章,详细介绍了它们的优点。
mysql_real_escape_string
仅旨在防止SQL注入攻击。对于其他漏洞,您需要其他工具。 - Gumbo