假设我的数据库设置如下以使用 utf-8(mysql 中的完整 4mb 版本)
mysql_query("SET CHARACTER SET utf8mb4");
mysql_query("SET NAMES utf8mb4");
我正在使用 mysql_real_escape_string 在将字符串放入 sql 之前转义不需要的字符(注意 - 我不是在寻找切换到 PDO 的建议,我想确定 mysql_real_escape_string 是否对超长的 utf8 等是安全的)。
$input = mysql_real_escape_string($_POST['field']);
$sql = "SELECT * FROM `table` WHERE `header`='$input'";
在执行我的操作之前,是否需要对 $_POST['field'] 进行任何验证(例如,检查字符串是否为有效的 UTF-8 且是否过长且不包含无效序列等) mysql_real_escape_string 还是足够了?
最佳答案
我回答之前的公共(public)服务公告。您仍在使用 mysql_query .最终,您至少必须升级到 mysqli
,即使您不想使用 PDO。所有 mysql_
函数都已弃用(请参阅上一个链接中的红色大方框)并且可能会在 PHP 5.6 中删除。这很重要,因为在您的案例中建议 PDO 的主要原因是 prepared statements , mysqli
也可以做到。准备好的语句比转义更不容易受到注入(inject)攻击,但需要执行更多查询(性能影响小)。
至于UTF8,我推荐的是使用mb_check_encoding在尝试插入之前确保字符串至少是有效的 UTF8。
最后,有 this answer , 它提供了这些智慧的话
Another way to get yourself into hot water using mysql_real_escape_string is when you set the database connection encoding using the wrong method. You should do this:
mysql_set_charset('utf8', $link);
You can also do this though:
mysql_query("SET NAMES 'utf8'", $link);
The problem is that the latter bypasses the mysql_ API, which still thinks you're talking to the database using latin1 (or something else). When using mysql_real_escape_string now, it will assume the wrong character encoding and escape strings differently than the database will interpret them later. By running the SET NAMES query, you have created a rift between how the mysql_ client API is treating strings and how the database will interpret these strings. This can be used for injection attacks in certain multibyte string situations.
关于php - mysql_real_escape_string 是否容易受到无效的 UTF-8 攻击,例如超长的 UTF-8 或格式错误的 UTF-8 序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21091580/