转义sql语句的正确方法是什么?
我读了很多关于常见SQL注入的东西,所以对如何解决它们感兴趣。在我刚刚使用 addslashes()
之前,我认为它很合适。然后我发现mysql(i)_real_escape_string()
比addslashes()
更有用和可信。从那时起我使用mysqli_real_escape_string()
,但最近我陷入了一些我还没有真正理解的东西。 我有一些关于发送数据到MySQL和字符集的问题。 因此,我再次搜索,许多用户表示SET NAMES UTF8
是让所有事情顺利进行的方法。 但后来我读到,使用该查询使得mysqli_real_escape_string()
无法正常工作。转义sql语句的正确方法是什么?
所以毕竟我有点困惑。
转义sql语句的正确方法是什么?
使用SET NAMES UTF8
有什么可能的漏洞利用?
是mysqli_set_charset()
使连接在指定字符集中通信的正确方法是什么?
使用mysqli_sey_charset()
是mysql的内部变量cchanged在这个过程中吗?
感谢
只是为了纠正问题和答案中的大量错误信息。
- 不是“声明”,而是字符串文字。转义“SQL语句”是一种直接注入方式。只有字符串必须转义,而其他查询部分需要截然不同的格式和转义,对他们来说不会有丝毫好处。
- 所有转义/编码混乱只连接到一些边际编码,如GBK。使用UTF-8,您甚至可以使用addslashes()
- 由于5.3只要设置了DSN,PDO就可以设置客户端编码。
转义sql语句的正确方法是什么?
什么是使用SET NAMES UTF8可能的漏洞?
无
是mysqli_set_charset()的正确途径,以指定的charset的连接进行通信?
当然。
必须使用HTML页面上使用的实际字符集。
您可以使用mysqli prepared statements避免SQL注入 - 而不需要担心字符集编码。
来自链路的一个例子:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$city = "Amersfoort";
/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {
/* bind parameters for markers */
$stmt->bind_param("s", $city);
/* execute query */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($district);
/* fetch value */
$stmt->fetch();
printf("%s is in district %s\n", $city, $district);
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
?>
传递手动构造查询仅由于向后兼容性问题的支持。现代应用程序绝不应该这样做,而是使用预处理语句。尽管如此,如果您使用手动构建的查询已经死了,正确的方法是使用mysql_real_escape_string()并将编码设置为UTF-8。
你可以找到在OWASP网站的详细信息:https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
只要你明确地设置字符集连接对象的,你应该罚款:
mysql_set_charset('utf8', $db); // for mysql
$db->set_charset('utf8'); // for mysqli
同样的问题与字符集适用于PDO预处理语句,因此PDO是推荐的方式,但在这种情况下它不会使您安全。
使用mysqli_real_escape_string()
和定义的字符集没有任何问题。请注意,您使用UTF-8作为连接对象以及HTML页面,这样可以避免很多问题。
我发现这个主题的最好解释是从PHP作者ircmacell,一次为mysql_real_escape_string(),一次为PDO。
请编辑您的文章,并在'mysqli_real_escape_string()'处理之前和之后包含SQL示例。 – 2012-08-08 11:42:25