MySQL条件等号的异常
敬原作者(应该是原作者,如有错误,请指正)
来自Wupco’s Blog
##根源
MySQL WHERE语句中,等号=
通常作为判断条件,然而这个等号却是弱类型
的判断,如果忽略了这一点,很容易造成安全问题,以下是原作者整理的匪夷所思的相等
。
##字符型和数字型
MySQL的等号同PHP一样,对等号两端不同的数据类型都有强制类型转换,如下:
1 | mysql> use mysql |
但却没有PHP的弱类型判断(此处本人不明白,为什么以下语句能说明这句话,望大神指点)
1 | mysql> select user name from user where 0.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999=1; |
这个的应用范围很局限,但是又不得忽视,所以开发者在字段的数据类型的选择以及SQL语句的构造方面,要多多注意,防止等号两边类型不相同导致的漏洞。
1 | mysql> select user name from user where '1d'=1; |
##尾空格
MySQL等号对字符尾部的空格做忽视的处理,所以我们可以构造一个'abc'='abc [space]
的效果,绕过某些特定串整体检查的WAF
,不过相对来说,这个也比较鸡肋,因为很少有用的字符串直接对比来过滤某些敏感串的,直接用trim
函数来避免。
1 | mysql> select user from user where user='root '; |
##UNICODE字符集相似字符
Unicode字符集所有字符:[点我](http://unicode-table.com/cn/ "点我")
其中有些相似字符,比如下面这个与a
相似。
这会造成什么后果呢?
1 | mysql> select user from user where 'a'='à'; |
看到了吧,MySQL的等号认为这些相似字符也是相等的,这样的话,我们就可以完全绕过对敏感串的过滤,前提是在UTF8
编码下。
##新型万能密码username='admin'=''
这是有2个等号,然后计算顺序从左到右
。
先计算username='admin'
,
如果没有这个记录,则返回false
,
然后计算false=''
,
结果就成了true
了,
所以这个就相当于where 1
,
达到了万能密码的效果。
1 | mysql> select user from user where user='admin'; |