場景
1)使用了Oracle隨機排序 order by dbms_random.value;
2)springboot集成druid連接池批量更新異常
異常關鍵詞:
oracle Cause: java.sql.SQLException: sql injection violation, deny object : dbms_random
異常詳細:
Error querying database. Cause: java.sql.SQLException: sql injection violation, deny object : dbms_random : select * from ( select * from ( select t.professional_id,t.professional_name,question.* from ASK_QUES_BANK question left join ASK_PROFESSIONAL t on question.professional = t.professional_id where question.professional = ? and question.question_type = ? and question.state = 0 and t.state = 0 ) order by dbms_random.value ) m where rownum <= ? at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:800) at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:251) at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:568) at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:929) at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122) at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:568) at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:929) at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122) at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:568) at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:342) at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:349) at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:87) at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88) at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59) at sun.reflect.GeneratedMethodAccessor394.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49) at com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor.intercept(PaginationInterceptor.java:158) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) at com.sun.proxy.$Proxy196.prepare(Unknown Source) at sun.reflect.GeneratedMethodAccessor394.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) at com.sun.proxy.$Proxy196.prepare(Unknown Source) at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85) at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62) at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:326) at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:136) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) ... 61 more
分析;
Druid的防火牆配置(WallConfig)中變量multiStatementAllow默認為false;
解決方案:更改druid 配置並解決問題
設置Druid的防火牆配置(WallConfig)中變量multiStatementAllow=true,新建DruidDataSource配置類
配置類代碼:
@Configuration public class DataSourceConfig { @Autowired WallFilter wallFilter; @Bean //聲明其為Bean實例 @Primary //在同樣的DataSource中,首先使用被標注的DataSource @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource(){ DruidDataSource datasource = new DruidDataSource(); // filter List<Filter> filters = new ArrayList<>(); filters.add(wallFilter); datasource.setProxyFilters(filters); return datasource; } @Bean(name = "wallFilter") @DependsOn("wallConfig") public WallFilter wallFilter(WallConfig wallConfig){ WallFilter wallFilter = new WallFilter(); wallFilter.setConfig(wallConfig); return wallFilter; } @Bean(name = "wallConfig") public WallConfig wallConfig(){ WallConfig wallConfig = new WallConfig(); wallConfig.setFunctionCheck(false); //wallConfig.setMultiStatementAllow(true);//允許一次執行多條語句 //wallConfig.setNoneBaseStatementAllow(true);//允許一次執行多條語句 return wallConfig; } }