架构和环境
- spring-cloud版本:Dalston.SR1
- spring-boot版本:1.5.3.RELEASE;
- ORM:spring-data-jpa
- 数据库连接池:Druid
问题描述
系统被检测出多处大量接口有SQL注入风险,并且指明了存在多种注入的方式
原因
框架架构初期约定的JPA与数据库交互没有被开发人员恪守,存在大量直接拼接的SQL执行语句,既没有预编译,也没有做危险SQL关键词的统一过滤
解决方案
- 方案一:采用预编译方式运行SQL,如今基本所有数据库都支持预编译,所以直接使用数据库连接包中的预编译类即可实现,不过所有拼接SQL的代码都需要更改,工作量非常巨大,此篇不再赘述,百度java SQL预编译即可
- 方案二:在网关拦截处做处理,拦截获取的请求的所有参数,判断参数是否有SQL注入风险的关键词,有危险关键词就一律报错不予执行,这样侵入性太强,大量参数传入可能会给系统造成一定负担,而且有些关键词存在SQL注入风险但是还是需要使用的
- 方案三:这个方案是后来才发现的,因为系统使用的数据库连接池是Druid,Druid自带防止SQL注入的配置,在第一个方案被否决,第二个方案发布测试后很多接口被测试和开发怼,不得已的情况下发现了这个最佳的解决方案
实现代码
开门见山,最佳方案三的配置
添加配置文件中Druid
配置filters= wall
表示防止SQL注入
1 | spring: |
当然有的项目不是使用Druid做数据库连接池,其他的连接池有些同样自带防SQL注入的配置,可以检索一下
方案二的实现代码
SqlInjectionFilter类继承ZuulFilter重写run方法(此类还带有预防XSS攻击的代码,如果配置了Druid配置,可以删除此处预防sql注入相关代码,改为预防XSS攻击的类)
1 |
|
SqlInjectionConfig类读取配置文件中需要跳过检查的接口数组
1 | import org.springframework.boot.context.properties.ConfigurationProperties; |
yml配置文件,如果想要关闭SQL注入检测将enable
改为false
即可,如果想要某个接口跳过检测,添加到skipUrls
数组即可
1 | custom: |