php - 求mysql_real_escape_string()防注入详解
黄舟
黄舟 2017-04-11 09:16:43
0
2
803

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.并考虑到连接的当前字符集啥意思呢? 改变当前连接的字符集?

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

répondre à tous(2)
小葫芦

这个说的就是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 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集

洪涛

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

重要:

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

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal