如下controller即可触发SQL注入:
为什么?
我们看看代码。我从github下载的最新源码:https://github.com/liu21st/thinkphp
/ThinkPHP/Library/Think/Db/Driver.class.php 531行:
这就是处理where条件的函数,我们看到如下片段:
当匹配/BETWEEN/i和$val[0]时,则将strtoupper($val[0])直接插入了SQL语句。
这个匹配:preg_match('/BETWEEN/i',$val[0]),明显是有问题的。因为这个匹配没加^$也就是首尾限定,所以只要我们的$val[0]中含有between时,这个匹配就可以成立,就产生了一个SQL注入。
为了防止I函数对我们输入的过滤影响,我们看看I函数:
较前些版本有些改进:
1.加了类型强制转换$type,但在默认情况下$type是空的,强制类型转换是不存在的。
2.将is_array($data) && array_walk_recursive($data,'think_filter');放在最后一行。我们看看think_filter这个过滤函数:
这个实际上就是对我之前那个漏洞的一个解决方案,将一些关键词后面加空格。但我们看到,这个正则是存在“^$”首尾限定符的。所以只有传入参数完全“等于”BETWEEN的时候才会被加上空格,而且这里加上空格也不会影响漏洞的产生,因为漏洞位置的正则没有加^$首尾限定符。
还有一个说明:之前thinkphp出了个“错误”的补丁,这个补丁已经被官方去掉了,所以不用考虑那个补丁造成的一些干扰。