Druid-排查conditionDoubleConstAllow配置问题(double const condition)
Druid-排查conditionDoubleConstAllow配置问题(double const condition)
报错信息
Caused by: java.sql.SQLException: sql injection violation, dbType postgresql, druid-version 1.2.18, double const condition : SELECT * FROM test where 1=1 AND TRUE AND TRUE
关键词:double const condition
Druid进行SQL检查,发现了重复的常量条件
排查过程
- 下载druid源码 https://github.com/alibaba/druid
- 阅读相关文档 文档
- 代码断点调试排查
编写代码复现问题
@RestController
@Slf4j
public class TestController {@Autowiredprivate JdbcTemplate jdbcTemplate;@GetMapping("test")public String test(){String sql = "SELECT * FROM test WHERE 1=1 AND TRUE AND id = 1 ";jdbcTemplate.execute(sql);return "Test";}}
Druid配置关键信息:wall
spring:datasource:druid:filters: config,wall,stat
运行错误:
java.sql.SQLException: sql injection violation, dbType postgresql, druid-version 1.2.18, part alway true condition not allow : SELECT * FROM test WHERE 1=1 AND TRUE AND id = 1 at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:836)at com.alibaba.druid.wall.WallFilter.check(WallFilter.java:801)at com.alibaba.druid.wall.WallFilter.statement_execute(WallFilter.java:433)at com.alibaba.druid.filter.FilterChainImpl.statement_execute(FilterChainImpl.java:2991)at com.alibaba.druid.proxy.jdbc.StatementProxyImpl.execute(StatementProxyImpl.java:143)at com.alibaba.druid.pool.DruidPooledStatement.execute(DruidPooledStatement.java:635)at org.springframework.jdbc.core.JdbcTemplate$1ExecuteStatementCallback.doInStatement(JdbcTemplate.java:422)at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:381)at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:431)
通过文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE-wallfilter 可以看到相关存在相关配置:conditionDoubleConstAllow , 默认为false,既不允许Where条件中有两个以上的常量。
接下来打开源码,搜索conditionDoubleConstAllow,找到以下线索:
- com.alibaba.druid.wall.WallConfig#conditionDoubleConstAllow
- com.alibaba.druid.spring.boot.autoconfigure.stat.DruidFilterConfiguration#wallConfig
解决方法一:将配置filters: config,wall,stat 中的wall去掉,既不进行一些防注入检查,修改有效,但安全性降低,暂不采用
解决方法二:重点关注wallConfig()方法:
private static final String FILTER_WALL_PREFIX = "spring.datasource.druid.filter.wall";private static final String FILTER_WALL_CONFIG_PREFIX = FILTER_WALL_PREFIX + ".config";@Bean@ConfigurationProperties(FILTER_WALL_CONFIG_PREFIX)@ConditionalOnProperty(prefix = FILTER_WALL_PREFIX, name = "enabled")@ConditionalOnMissingBeanpublic WallConfig wallConfig() {return new WallConfig();}@Bean@ConfigurationProperties(FILTER_WALL_PREFIX)@ConditionalOnProperty(prefix = FILTER_WALL_PREFIX, name = "enabled")@ConditionalOnMissingBeanpublic WallFilter wallFilter(WallConfig wallConfig) {WallFilter filter = new WallFilter();filter.setConfig(wallConfig);return filter;}
发现可以通过配置修改WallConfig#conditionDoubleConstAllow的值,于是进行配置修改:
spring:datasource:druid:filters: config,wall,statfilter:wall:enabled: trueconfig:condition-double-const-allow: true
测试结果:(依旧报错…)
java.sql.SQLException: sql injection violation, dbType postgresql, druid-version 1.2.18, part alway true condition not allow : SELECT * FROM test WHERE 1=1 AND TRUE AND id = 1 at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:836)at com.alibaba.druid.wall.WallFilter.check(WallFilter.java:801)at com.alibaba.druid.wall.WallFilter.statement_execute(WallFilter.java:433)at com.alibaba.druid.filter.FilterChainImpl.statement_execute(FilterChainImpl.java:2991)at com.alibaba.druid.proxy.jdbc.StatementProxyImpl.execute(StatementProxyImpl.java:143)at com.alibaba.druid.pool.DruidPooledStatement.execute(DruidPooledStatement.java:635)at org.springframework.jdbc.core.JdbcTemplate$1ExecuteStatementCallback.doInStatement(JdbcTemplate.java:422)at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:381)at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:431)
进一步断点调试:
发现在com.alibaba.druid.spring.boot.autoconfigure.stat.DruidFilterConfiguration#wallFilter方法中,filter.setConfig(wallConfig)时,注入的wallConfig,其conditionDoubleConstAllow属性已经是true,说明配置生效了。
但还是报上述异常,继续调试分析。
@Bean@ConfigurationProperties(FILTER_WALL_PREFIX)@ConditionalOnProperty(prefix = FILTER_WALL_PREFIX, name = "enabled")@ConditionalOnMissingBeanpublic WallFilter wallFilter(WallConfig wallConfig) {WallFilter filter = new WallFilter();filter.setConfig(wallConfig);return filter;}
继续调试,关注方法com.alibaba.druid.wall.WallFilter#checkInternal
private WallCheckResult checkInternal(String sql) throws SQLException {WallCheckResult checkResult = provider.check(sql);List<Violation> violations = checkResult.getViolations();if (violations.size() > 0) {Violation firstViolation = violations.get(0);if (isLogViolation()) {LOG.error("sql injection violation, dbType "+ getDbType()+ ", druid-version "+ VERSION.getVersionNumber()+ ", "+ firstViolation.getMessage() + " : " + sql);}if (throwException) {if (violations.get(0) instanceof SyntaxErrorViolation) {SyntaxErrorViolation violation = (SyntaxErrorViolation) violations.get(0);throw new SQLException("sql injection violation, dbType "+ getDbType() + ", "+ ", druid-version "+ VERSION.getVersionNumber()+ ", "+ firstViolation.getMessage() + " : " + sql,violation.getException());} else {throw new SQLException("sql injection violation, dbType "+ getDbType()+ ", druid-version "+ VERSION.getVersionNumber()+ ", "+ firstViolation.getMessage()+ " : " + sql);}}}return checkResult;}
com.alibaba.druid.sql.ast.SQLObjectImpl#accept 方法
public final void accept(SQLASTVisitor visitor) {if (visitor == null) {throw new IllegalArgumentException();}visitor.preVisit(this);accept0(visitor);visitor.postVisit(this);}
com.alibaba.druid.wall.spi.WallVisitorUtils#getValue_and方法
public static Object getConditionValue(WallVisitor visitor, SQLExpr x, boolean alwayTrueCheck) {final WallConditionContext old = wallConditionContextLocal.get();try {wallConditionContextLocal.set(new WallConditionContext());final Object value = getValue(visitor, x);final WallConditionContext current = wallConditionContextLocal.get();WallContext context = WallContext.current();if (context != null) {if (current.hasPartAlwayTrue() || Boolean.TRUE == value) {if (!isFirst(x)) {context.incrementWarnings();}}}if (current.hasPartAlwayTrue()&& !visitor.getConfig().isConditionAndAlwayTrueAllow()) {addViolation(visitor, ErrorCode.ALWAYS_TRUE, "part alway true condition not allow", x);}if (current.hasPartAlwayFalse()&& !visitor.getConfig().isConditionAndAlwayFalseAllow()) {addViolation(visitor, ErrorCode.ALWAYS_FALSE, "part alway false condition not allow", x);}if (current.hasConstArithmetic()&& !visitor.getConfig().isConstArithmeticAllow()) {addViolation(visitor, ErrorCode.CONST_ARITHMETIC, "const arithmetic not allow", x);}if (current.hasXor() && !visitor.getConfig().isConditionOpXorAllow()) {addViolation(visitor, ErrorCode.XOR, "xor not allow", x);}if (current.hasBitwise() && !visitor.getConfig().isConditionOpBitwseAllow()) {addViolation(visitor, ErrorCode.BITWISE, "bitwise operator not allow", x);}return value;} finally {wallConditionContextLocal.set(old);}}
发现到以下代码时,执行了addViolation
if (current.hasPartAlwayTrue()&& !visitor.getConfig().isConditionAndAlwayTrueAllow()) {addViolation(visitor, ErrorCode.ALWAYS_TRUE, "part alway true condition not allow", x);}
于是再次修改配置:将condition-and-alway-true-allow也改为true
spring:datasource:druid:filters: config,wall,statfilter:wall:enabled: trueconfig:condition-and-alway-true-allow: truecondition-double-const-allow: true
再次测试:执行成功!!!
Druid-排查conditionDoubleConstAllow配置问题(double const condition)相关推荐
- c++ 中const的使用
在c++中.const是这么一个东西:假设你希望可以有一些东西是别人不能改动的,这个时候const就起作用了. const 在使用情况例如以下: a.修饰常量 const int a; int con ...
- 《认清C++语言》---谈谈const
const类型修饰符可以: 1) 用来说明符号常量和常数组(必须同时进行初始化,以后不能再更新) C++中,用关键字const修饰的标识符称为符号常量,或称为const变量. 常量在使用前必须先定义 ...
- 指针和Const限定符
指针和Const限定符 1.指向const对象的指针 如果指针指向的是const对象,则不允许使用指针来改变其所指的const值.C++要求指向const对象的指针具有const特性. const d ...
- 有关c++中const用法
今天看了一下<<c++ primer>>对于const有一个新发现 double a; const double b = 12; 这种表示比 ...
- 【小白学习C++ 教程】八、在C++指针传递引用和Const关键字
@Author:Runsen 以前,当我们将参数传递给函数时,我们一般使用普通变量,这称为pass-by-value方法.但是因为传递给函数的变量有可以出现超出了范围的问题,这样我们实际上无法修改参数 ...
- C/C++中Static和Const的作用
C/C++中Static和Const的作用 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/53118850 一.c ...
- 类的转换函数调用的优先级与是否用const修饰的关系
P415 C++ Primer Plus (第六版)(待解决~~知道原理的同学请留言,多谢~~) #include <iostream> using namespace std; clas ...
- 指针、引用以及const限定符、constexpr限定符
文章目录 复合类型 引用 概念与使用 引用的定义 注意 指针 概念 声明方式 取地址符 指针值 空指针 利用指针访问对象 赋值和指针 void* 指针 指向指针的指针 指向指针的引用 初始化所有指针 ...
- C++primer第二章2.4节对于const限定符相关内容进行详解
const限定符 const对象一旦创建后其数值就不会被再次改变,因此const对象必须初始化. const对象只在文件中有效 在不同的文件中使用不同的const来定义不同的常量,那么每个文件定义的变 ...
最新文章
- ELK 为什么这么流行?|GIAC 访谈
- PTA团体程序设计天梯赛篇(一)----模拟专题
- 【Transformer】HRFormer:High-Resolution Transformer for Dense Prediction
- 1秒获取Power BI Pro帐号
- Python学习入门5:Python到底应该怎么学?
- R语言-merge和rbind
- 转电感和磁珠两兄弟的差别
- python计算sinx在0-2π_定积分[0,2π]|sinx|
- 【Mac实用技巧】Mac如何修复YouTube视频黑屏现象?
- 快手火山抖音视频(包含其他视频)跨平台操作搬运,下载,消重,全自动操作解放双手...
- 数据链路层协议(1)
- 实验一 stm32F407VETx点亮流水灯
- Python3 遇到\\u开头的编码
- python 求x的 n次方
- 移动互联网创业方向的思考(绕过腾讯和华为等大公司的战场,打造新型的餐饮平台)
- 明德扬手把手教你设计VGA显示颜色
- 自动化测试脚本-帐号注册到激活
- 应用写作[0045]
- 2023 年 Pycharm 最新安装教程,亲测可用
- 1177_SICP学习笔记_嵌套映射
热门文章
- [附源码]JSP+ssm计算机毕业设计高校教材管理平台的设计与实现4boq6【源码、数据库、LW、部署】
- hist函数,plot函数,linspace
- OpenCV 检测二维码并定位
- 但愿人长久(有福利)
- 三极管在ad中的原理图库_三极管工作原理介绍,NPN和PNP型三极管的原理图与各个引脚介绍...
- C语言 FILE文件指针
- JS === 简易放大镜
- FPGA程序固化流程
- matlab 存mat文件,matlab中mat文件简单存/取
- 1.所谓计算机热启动是指(),计算机应基础与应用复习题.doc