假设我的数据库设置如下,使用utf-8(mysql中的完整4mb版本)
mysql_query("SET CHARACTER SET utf8mb4");
mysql_query("SET NAMES utf8mb4");
我在将字符串放入sql之前使用mysql_real_escape_string来逃避不需要的字符(注意 - 我不是在寻找切换到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还是足够的?
答案 0 :(得分:2)
在我回答之前发布公共服务公告。你还在使用mysql_query。即使你不想去PDO,你最终也必须升级到mysqli
。所有mysql_
函数都已折旧(请参阅上一个链接中的大红色可怕框),并且可能会在PHP 5.6中删除。这很重要,因为在您的案例中建议PDO的主要原因是prepared statements,mysqli
也可以这样做。准备好的语句远比攻击更容易受到注入攻击,但需要更多查询(性能影响小)。
至于UTF8,我建议使用mb_check_encoding来确保字符串在尝试插入之前至少是有效的UTF8。
最后,有this answer,它提供了这些智慧的话语
另一种让自己进入热水的方法 mysql_real_escape_string是您设置数据库连接时 使用错误的方法编码。你应该这样做:
mysql_set_charset('utf8',$ link);
你也可以这样做:
mysql_query(“SET NAMES'utf8'”,$ link);
问题是后者绕过了mysql_ API,但仍然如此 认为你正在使用latin1(或其他东西)与数据库交谈 其他)。现在使用mysql_real_escape_string时,它会假设 错误的字符编码和转义字符串不同于 数据库稍后会解释它们。通过运行SET NAMES查询, 你已经在mysql_客户端API如何处理之间创建了一个裂缝 字符串以及数据库如何解释这些字符串。这可以 用于某些多字节字符串情况下的注入攻击。
答案 1 :(得分:1)
所有输入验证和反SQL注入都受到 soo许多错误概念的影响。事实上,所有这些归结为一件事:
如果您能够确保任何输入数据的SQL语法正确,那么您是安全的,并且您根本不需要阅读或研究有关验证或SQL注入的任何内容。因为所有这些漏洞只有在允许不正确的SQL语法的情况下才有可能。
为了确保您的SQL查询语法正确,您必须确保$input
以正确的方式转义。查看PHP文档:http://php.net/mysql_real_escape_string:
警告安全:默认字符集
字符集必须在服务器级别设置,或者使用 API函数mysql_set_charset()对它有影响 mysql_real_escape_string()。请参阅有关字符集的概念部分 了解更多信息。
因此,必须在您的字符集上正确通知mysql_real_escape_string
才能正常转义。因此,您应该执行以下操作:
mysql_query("SET NAMES utf8mb4");
mysql_set_charset("utf8mb4");