- 普通 - 未处理
在通常的网站sql注入漏洞中,根据用户提交的数据,来拼接成sql字符串,是最最主要的漏洞之源。从经验看恐怕99%都是这个原因。常用的预防方法有几个。
一是对用户提交的数据,做类型化处理,对于数字型、浮点型等数据,进行intval、floatval的处理。
二是对于字符串类型的数据,根据不同的数据库进行escape_string编码。
三是通过正则表达式之类,对数据进行过滤处理,这种方式个性化很强,不好做到通用化,而且过滤规则不当,仍会有漏网之鱼。
一般来说,用户提交的数据,或者生成insert/update数据,或者是用在sql的查询语句中,WHERE后面的查询条件上。TP2.x在生成SQL语句的时候,有了很好的处理,即采用第一、二种方式,对这些数据进行了parseValue处理,也即是进行escape_string编码。
但是TP2.x也有一些限制,比如Model类常用的where函数,如果传递的参数是字符串,就没有做编码处理,就会有漏洞产生。所以在使用的时候,必须对where函数调用,传递array数组参数,才会使用到TP2.x的安全过滤功能,SQL语句才会比较安全。
在看Model.class.php的时候,发现Model类的getBy****函数、find函数、select函数、save函数、delete函数等多个地方,对$options['where']的处理,居然仍然采用字符串拼接的方式,是很明显的sql注入的漏洞。而且这几个函数中,$options['where']的处理,很容易改成采用比较安全的array数组方式。
另外Model类中,其他几个函数order, limit, having, group等,这几个函数也是采用直接字符串拼接的方式,组成sql语句。也许是考虑到灵活性,比如有sql函数调用之类,不好进行escape_string编码处理。还有这几个函数的参数采用用户提交数据的可能性也小些。但是如果一旦有这种情况,比如Rbac例子中的table排序,就是用户输入的内容作为order函数的参数,这时就必须对_order进行小心仔细过滤才行,否则必然是漏洞。
还有,建议Model.class.php,最好有一个public function escape_string($str),将类成员中$Db的escape_string函数暴露出来。这样在只能使用字符串拼接sql的时候,可以手动对用户数据进行处理。
