登录

php - 求mysql_real_escape_string()防注入详解

mysql_real_escape_string()被视为替代addslashes()和mysql_escape_string()的好方法,可以解决宽字节和注入问题,不过官方对其的描述却说的不清不楚:

mysql_real_escape_string — 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集

这句真没懂,考虑到连接的当前字符集啥意思,请高手详细讲讲,谢谢!

参考:
http://php.net/manual/zh/function.mysql-real-escape-string.php
http://www.cnblogs.com/suihui/archive/2012/09/20/2694751.html
http://www.neatstudio.com/show-963-1.shtml

补充问题: @演演演演
1.加的\并不会传入mysql中,那么如果注入了' or 1=1;-- s ,这里的注入内容最终还不是传到mysql去了执行了吗?
参照:https://segmentfault.com/q/1010000005994443

2.并考虑到连接的当前字符集啥意思呢? 改变当前连接的字符集?

# PHP
黄舟黄舟2198 天前483 次浏览

全部回复(2) 我要回复

  • 高洛峰

    高洛峰2017-04-11 09:18:43

    这个说的就是mysql gbk双字节注入

    比如用户登录 假设你的sql语句:
    $sql = "select * from user where user_name='$username' and password='$password'";

    1 如果存在注入点 并且也没有转义。传递参数username=' or 1=1;-- s 那么此时的sql语句就是

    $sql = "select * from user where user_name='' or 1=1;-- s ' and password='$password'";

    因为--是注释符 所以后面不用判断成功绕过

    2 如果存在注入点 并且使用了特殊字符转义。那么此时的sql语句就是

    $sql = "select * from user where user_name='\' or 1=1;-- s ' and password='$password'";

    无法绕过

    3 这个时候问题来了,牛逼的黑客发现了gbk编码时存在宽字节注入。这个时候传递username=%df%27 or 1=1;--

    这个时候执行的sql语句变成了:

    $sql = "select * from user where user_name='運' or 1=1;-- s ' and password='$password'"; 成功绕过

    如何解决这个问题

    mysql_real_escape_string — 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集

    回复
    0
  • PHP中文网

    PHP中文网2017-04-11 09:18:43

    mysql_real_escape_string方法对SQL语句的转义机制,随着当前数据库连接的字符集的改变而改变。相同的SQL语句,不同的字符集下,转义后的结果不一定相同。

    重要:

    mysql_real_escape_string方法属于mysql扩展,该扩展自PHP版本5.5.0之后已被标记为过时,并在PHP版本7之后被移除。请使用mysqli或者PDO扩展进行数据库操作。数据库字符集请尽量使用utf8或者utf8mb4(更好)。

    回复
    0
  • 取消回复发送