SQL注入真正产生危害的环节是编译过程,在这个过程中,会将sql中的关键字、执行逻辑翻译成数据库可以明白的待执行语句。
预编译可以防止sql注入的原因
- 进行预编译之后,sql语句已经被数据库分析,编译和优化了,并且允许数据库以参数化的形式进行查询,所以即使有敏感字符数据库也会当做属性值来处理而不是sql。
- sql语句是带着占位符被编译的,因此这条sql语句的操作类型基本被限定了。
- 预编译对sql进行了词法分析,语法分析,语义分析,等于是给这个sql语句进行了一次行为限制,比如只允许向前跑或者向上跳。等执行的时候,带上参数就行,比如向前15米或者向上50公分。
mybatis框架使用者,需要注意哪些注入风险?
注入风险主要来自sql拼接,在mybatis中,传入参数可以用两种字符,#和$。其中#是预编译,&是SQL拼接。
尽量避免使用&字符,尤其是在like、in、order by操作指令中,程序员一般会这么使用:
LIKE查询
SELECT * FROM goods WHERE name like '%${name}%'
替换方案为:
SELECT * FROM goods WHERE name like concat(‘%’,#{name}, ‘%’)
IN查询
SELECT * FROM goods WHERE id in ($ids);
替换方案为:
SELECT * FROM goods WHERE id in
<foreach collection="ids" item="item" open="("separatosr="," close=")">
# {id}
</foreach>
ORDER排序
SELECT * FROM goods ORDER BY $orderType;
替换方案为:
orderType定义为枚举类
SELECT * FROM goods ORDER BY $orderType;