利用字符编码问题绕过mysql_real_escape_string()
的SQL注入
尽管mysql_real_escape_string()
函数可以防止SQL注入,但在某些特定情况下,它可能会被绕过。
考虑以下PHP代码:
<code class="language-php">$login = mysql_real_escape_string(GetFromPost('login')); $password = mysql_real_escape_string(GetFromPost('password')); $sql = "SELECT * FROM table WHERE login='$login' AND password='$password'";</code>
这段代码看似安全,但由于字符集编码的边缘情况,它可能被利用。
攻击方法:
攻击依赖于以下步骤:
mysql_real_escape_string()
: 客户端认为连接使用的是不同的字符集(例如,latin1),因此mysql_real_escape_string()
会在单引号前插入反斜杠,从而产生语法上有效的字符串。工作原理:
关键问题在于服务器期望的字符集与客户端认为的字符集不匹配。虽然mysql_real_escape_string()
根据客户端设置的连接编码进行转义,但在某些情况下,它会将无效的多字节字符视为单个字节,包括使用SET NAMES
而不是mysql_set_charset()
的情况。
后果:
即使禁用了模拟预处理语句,此攻击也可以绕过PDO的模拟预处理语句。
补救措施:
使用非易受攻击的字符集,如utf8mb4或utf8,可以减轻此问题。启用NO_BACKSLASH_ESCAPES SQL模式也可以提供保护。
安全的示例:
始终使用mysql_set_charset()
或PDO的DSN字符集参数正确设置字符集。MySQLi中的真实预处理语句也对这种攻击免疫。
结论:
虽然mysql_real_escape_string()
通常提供强大的保护,但务必注意此类潜在的边缘情况,以确保全面防御SQL注入。
以上是由于字符编码问题,SQL注入可以绕过'mysql_real_escape_string()`?的详细内容。更多信息请关注PHP中文网其他相关文章!