MySql+Mybatis+Druid:sql injection violation, multi-statement not allow
2016-01-28 14:01
1106 查看
做一个批量update的操作 ,sqlmap如下:
<update id="updateBatch" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update device_bd_token
<set>
access_token=#{item.accessToken}
</set>
where device_id = #{item.deviceId}
</foreach>
</update>
结果报错:
Caused by: java.sql.SQLException: sql injection violation, multi-statement not allow : update device_bd_token
SET access_token=?
where device_id = ?
;
update device_bd_token
SET access_token=?
where device_id = ?
at com.alibaba.druid.wall.WallFilter.check(WallFilter.java:714)
at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:240)
at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)
at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:928)
at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122)
at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)
at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:342)
at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:318)
刚开始以为是连接数据库的url上没有加上支持批量的参数,然后就改了下:
jdbc.url=jdbc:mysql://192.168.11.107:3306/alarm_db?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
结果还是同样的错误!但是在命令行直接执行又是没问题的,这就很奇怪了!
仔细看日志,好像是Druid的WallFilter.check()抛出来的,那就是说是Druid在做预编译的时候,给抛出的异常,还没有到mysql的服务器。
最终的解决办法是这样的:
<bean id="dataSourceOne" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="proxyFilters">
<list>
<ref bean="stat-filter" />
<ref bean="wall-filter"/>
</list>
</property>
</bean>
配置一个multiStatementAllow参数就可以了。
看下源码的处理:
也就是说,只要把config的multiStatementAllow设置为true就可以避免出现这样的错误了!
Druid配置的时候还有一个大坑就是,不要同时配置filters和proxyFilters,filter都是内置的,想通过proxyFilters来定制的话,就不要配置filters。
DruidDataSource继承了DruidAbstractDataSource,
可以看出来,既可以配置filters,也可以配置proxyFilters,不同的是,filters是字符串别名,proxyFilters是类。
我们继续看一下这些字符串的值应该是啥样的:
原来在这里:
这就是druid内置的所有的filter了,去掉前缀druid.filters就是别名了。
<update id="updateBatch" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update device_bd_token
<set>
access_token=#{item.accessToken}
</set>
where device_id = #{item.deviceId}
</foreach>
</update>
结果报错:
Caused by: java.sql.SQLException: sql injection violation, multi-statement not allow : update device_bd_token
SET access_token=?
where device_id = ?
;
update device_bd_token
SET access_token=?
where device_id = ?
at com.alibaba.druid.wall.WallFilter.check(WallFilter.java:714)
at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:240)
at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)
at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:928)
at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122)
at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)
at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:342)
at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:318)
刚开始以为是连接数据库的url上没有加上支持批量的参数,然后就改了下:
jdbc.url=jdbc:mysql://192.168.11.107:3306/alarm_db?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
结果还是同样的错误!但是在命令行直接执行又是没问题的,这就很奇怪了!
仔细看日志,好像是Druid的WallFilter.check()抛出来的,那就是说是Druid在做预编译的时候,给抛出的异常,还没有到mysql的服务器。
最终的解决办法是这样的:
<bean id="dataSourceOne" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="proxyFilters">
<list>
<ref bean="stat-filter" />
<ref bean="wall-filter"/>
</list>
</property>
</bean>
<bean id="wall-filter" class="com.alibaba.druid.wall.WallFilter"> <property name="config" ref="wall-config" /> </bean> <bean id="wall-config" class="com.alibaba.druid.wall.WallConfig"> <property name="multiStatementAllow" value="true" /> </bean>
配置一个multiStatementAllow参数就可以了。
看下源码的处理:
也就是说,只要把config的multiStatementAllow设置为true就可以避免出现这样的错误了!
Druid配置的时候还有一个大坑就是,不要同时配置filters和proxyFilters,filter都是内置的,想通过proxyFilters来定制的话,就不要配置filters。
DruidDataSource继承了DruidAbstractDataSource,
可以看出来,既可以配置filters,也可以配置proxyFilters,不同的是,filters是字符串别名,proxyFilters是类。
我们继续看一下这些字符串的值应该是啥样的:
原来在这里:
这就是druid内置的所有的filter了,去掉前缀druid.filters就是别名了。
相关文章推荐
- media query 单位
- Ueditor后端配置项没有正常加载,上传插件不能正常使用!
- 3、vuejs数据绑定
- 脚本检测 media query 分界点
- UIMenuController 在UIView 上的 显示
- valuestack,stackContext,ActionContext.之间的关系
- IOS开发:UIAlertView使用
- 303. Range Sum Query - Immutable [Leetcode]
- Android 之采用execSQL和rawQuery方法完成数据的添删改查操作
- pcduino v2安装opencv2.4.8
- java中continue是什么意思?
- UIAlertView笔记
- Android源码中的Builder模式实现
- iOS开发之UILabel动态高度设置方法
- Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences
- iOS学习之路-简易”IT之家“(UITableView)
- confluence5.6安装
- Java Request 获取域名
- SVN问题:Server sent unexpected return value (403 Forbidden) in response to OPTIONS
- quick + nimble 单元测试