我阅读了很多关于常见sql注入的事情,所以对如何修复它们感兴趣。在我刚刚使用之前
addslashes()
(非常)认为它适合。然后我发现mysql(i)_real_escape_string()
比addslashes()
更有用和更可靠。从那以后我使用mysqli_real_escape_string()
,但最近我遇到了一些我还没有真正理解的东西。
我有一些关于将数据发送到mysql和字符集的问题。
因此,我再一次搜索,并且许多用户说SET NAMES UTF8
是使一切正确的方式。
但后来我读到使用该查询会使mysqli_real_escape_string()
无效。
所以我毕竟有点困惑。
转义sql语句的正确方法是什么?
使用SET NAMES UTF8
有哪些可能的漏洞利用?
mysqli_set_charset()
是否是在指定的字符集中进行连接通信的正确方法?
使用mysqli_sey_charset()
是mysql的内部变量在这个过程中被改变了吗?
由于
答案 0 :(得分:2)
您可以使用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();
?>
答案 1 :(得分:0)
由于向后兼容性问题,仅支持传递手动构造的查询。现代应用程序绝不应该这样做,而是使用预处理语句。
话虽如此,如果您已经开始使用手动构造的查询,正确的方法是使用mysql_real_escape_string(),并将编码设置为UTF-8。
您可以在OWASP网站上找到更多详细信息:https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
答案 2 :(得分:0)
只要您明确设置连接对象的字符集,就应该没问题:
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。
答案 3 :(得分:0)
只是纠正了问题和答案中的许多错误信息。
转义sql语句的正确方法是什么?
使用SET NAMES UTF8有什么可能的漏洞?
无
mysqli_set_charset()是否是在指定字符集中进行连接通信的正确方法?
不确定。
它必须与HTML页面上使用的实际字符集一起提供。