使用 ORM(Object/Relation Mapping)框架对 SQL 注入是有积极意义的。我们知道对抗 SQL 注入的最佳方式就是使用“预编译绑定变量”。在实际解决 SQL 注入时,还有一个难点就 是应用复杂后,代码数量庞大,难以把可能存在 SQL 注入的地方不遗漏地找出来,而 ORM 框 架为我们发现问题提供了一个便捷的途径。
以 ORM 框架 ibatis 举例,它是基于 sqlmap 的,生成的 SQL 语句都结构化地写在 XML 文 件中。ibatis 支持动态 SQL,可以在 SQL 语句中插入动态变量:$value$,如果用户能够控制这 个变量,则会存在一个 SQL 注入的漏洞。
<select id="User.getUser" parameterClass="cn.ibatis.test.User" resultClass="cn.ibatis.
test.User">
select TABLE_NAME,TABLESPACE_NAME from user_tables where table_name like '%'||#table_
name#||'%'
order by $orderByColumn$ $orderByType$
</select>
而静态变量 #value# 则是安全的,因此在使用 ibatis 时,只需要搜索所有的 sqlmap 文件 中是否包含动态变量即可。当业务需要使用动态 SQL 时,可以作为特例处理,比如在上层的 代码逻辑中针对该变量进行严格的控制,以保证不会发生注入问题。
而在 Django 中,做法则更简单,Django 提供的 Database API,默认已经将所有输入进行 了 SQL 转义,比如:
foo.get_list(bar__exact="' OR 1=1")
其最终效果类似于:
SELECT * FROM foos WHERE bar = '\' OR 1=1'
使用 Web 框架提供的功能,在代码风格上更加统一,也更利于代码审计。