PHP:mysql_real_escape_string是否足以清理用户input?

mysql_real_escape_string是否足以在大多数情况下清除用户input?

::编辑::

我主要想防止SQL注入,但我最终想知道,如果我应用mysql_real_escape_string后我可以信任用户数据,或者如果我应该采取额外的措施来清理数据之前,我将它传递给应用程序和数据库。

我看到清理HTML字符的地方很重要,但我不认为需要信任用户input。

Ť

在所有的情况下, mysql_real_escape_string是不够的,但它绝对是非常好的朋友。 更好的解决scheme是使用Prepared Statements

 //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()与Prepared Statements

引用:

mysql_real_escape_string()倾向于影响addslashes()的相同types的问题。

Chris Shiflett (安全专家)

您的问题的答案是不。mysql_real_escape_string()不适合所有用户input和mysql_real_escape_string()不会停止所有的SQL注入。 addslashes()是另一个在php中使用的常用函数,它也有同样的问题。

弱点代码:

 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是另一个stream行的php库。

如果你使用mysql_real_escape_string,应该只能用于sql注入,而没有别的。 漏洞高度依赖于数据的使用方式。 应该在function的基础上对function进行安全措施。 是的,XSS是一个非常严重的问题 。 不过滤HTML是严重的错误,一个黑客将用于pw3n你。 请阅读xss常见问题 。

对数据库来说,是的。 你会想要充分考虑为输出转义/编码数据。

您还应该考虑根据您期望的内容来validationinput。

你有没有考虑使用准备好的陈述 PHP提供了多种与数据库交互的方式。 其中大部分都比mysql_ *函数更好。

PDO , MDB2和MySQL的改进应该让你开始。

什么情况?

对于SQL查询,这是很好的。 (Prepared语句更好 – 我为此投了PDO – 但函数转义就好)。对于HTML等,它不是工作的工具 – 尝试一个通用的htmlspecialchars专用或更精确的工具,如HTML净化器 。

要解决编辑问题 :您可以添加的唯一的其他层是数据的自动生成,例如,确认如果要将整数放入数据库中,并且您期望得到一个正整数,则在尝试放入一个负整数。 就数据完整性而言, mysql_real_escape_string是最好的转义语句(尽pipe准备好的语句是一个更清晰的系统,可以避免完全转义)。

mysql_real_escape_string()仅用于防止SQL注入攻击。 它不会帮助您防止跨站点脚本攻击。 为此,您应该在输出最初从用户input中收集的数据之前使用htmlspecialchars()

有两种方法,一种是使用准备好的语句(正如其他答案中提到的那样),但这会减慢你的应用程序,因为你现在必须向数据库发送两个请求,而不是一个。 如果你能忍受降低的performance,那就去做吧。 准备好的语句使您的代码更漂亮,更容易处理。

如果您select使用mysql_real_escape_string,那么请确保您转义所有不受信任的string。 (mysql_real_escape_string)转义string是SQL注入安全 。 如果你不逃避所有的string,那么你是不安全的。 你应该真的结合mysql_real_escape_string和inputvalidation; 检查你希望保持一个数字的variables真的是一个数字,并在预期的范围内。 请记住,永远不要相信用户。

有不同types的“清洁”。

mysql_real_escape_string对于数据库数据来说已经足够了,但是如果它是HTML的话,它仍然可以在浏览器上进行评估。

要从用户input中删除HTML,可以使用strip_tags 。

我build议你看看使用PDO,而不是一般的MySQL的东西,因为它支持开箱即用的准备语句,以及那些处理无效数据的转义。

你可以尝试两个,如在

 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))); } 

最好的办法是使用Prepared Statements

我想我会补充说,PHP 5.2 +具有inputfilterfunction,可以以各种方式消毒用户input。

这里是手动input以及Matt Butcher的博客文章 ,他们为什么说他们很棒。