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,找到以下线索:

  1. com.alibaba.druid.wall.WallConfig#conditionDoubleConstAllow
  2. 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)相关推荐

  1. c++ 中const的使用

    在c++中.const是这么一个东西:假设你希望可以有一些东西是别人不能改动的,这个时候const就起作用了. const 在使用情况例如以下: a.修饰常量 const int a; int con ...

  2. 《认清C++语言》---谈谈const

    const类型修饰符可以: 1)  用来说明符号常量和常数组(必须同时进行初始化,以后不能再更新) C++中,用关键字const修饰的标识符称为符号常量,或称为const变量. 常量在使用前必须先定义 ...

  3. 指针和Const限定符

    指针和Const限定符 1.指向const对象的指针 如果指针指向的是const对象,则不允许使用指针来改变其所指的const值.C++要求指向const对象的指针具有const特性. const d ...

  4. 有关c++中const用法

    今天看了一下<<c++ primer>>对于const有一个新发现 double a; const double b = 12;                   这种表示比 ...

  5. 【小白学习C++ 教程】八、在C++指针传递引用和Const关键字

    @Author:Runsen 以前,当我们将参数传递给函数时,我们一般使用普通变量,这称为pass-by-value方法.但是因为传递给函数的变量有可以出现超出了范围的问题,这样我们实际上无法修改参数 ...

  6. C/C++中Static和Const的作用

    C/C++中Static和Const的作用     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/53118850 一.c ...

  7. 类的转换函数调用的优先级与是否用const修饰的关系

    P415 C++ Primer Plus (第六版)(待解决~~知道原理的同学请留言,多谢~~) #include <iostream> using namespace std; clas ...

  8. 指针、引用以及const限定符、constexpr限定符

    文章目录 复合类型 引用 概念与使用 引用的定义 注意 指针 概念 声明方式 取地址符 指针值 空指针 利用指针访问对象 赋值和指针 void* 指针 指向指针的指针 指向指针的引用 初始化所有指针 ...

  9. C++primer第二章2.4节对于const限定符相关内容进行详解

    const限定符 const对象一旦创建后其数值就不会被再次改变,因此const对象必须初始化. const对象只在文件中有效 在不同的文件中使用不同的const来定义不同的常量,那么每个文件定义的变 ...

最新文章

  1. ELK 为什么这么流行?|GIAC 访谈
  2. PTA团体程序设计天梯赛篇(一)----模拟专题
  3. 【Transformer】HRFormer:High-Resolution Transformer for Dense Prediction
  4. 1秒获取Power BI Pro帐号
  5. Python学习入门5:Python到底应该怎么学?
  6. R语言-merge和rbind
  7. 转电感和磁珠两兄弟的差别
  8. python计算sinx在0-2π_定积分[0,2π]|sinx|
  9. 【Mac实用技巧】Mac如何修复YouTube视频黑屏现象?
  10. 快手火山抖音视频(包含其他视频)跨平台操作搬运,下载,消重,全自动操作解放双手...
  11. 数据链路层协议(1)
  12. 实验一 stm32F407VETx点亮流水灯
  13. Python3 遇到\\u开头的编码
  14. python 求x的 n次方
  15. 移动互联网创业方向的思考(绕过腾讯和华为等大公司的战场,打造新型的餐饮平台)
  16. 明德扬手把手教你设计VGA显示颜色
  17. 自动化测试脚本-帐号注册到激活
  18. 应用写作[0045]
  19. 2023 年 Pycharm 最新安装教程,亲测可用
  20. 1177_SICP学习笔记_嵌套映射

热门文章

  1. [附源码]JSP+ssm计算机毕业设计高校教材管理平台的设计与实现4boq6【源码、数据库、LW、部署】
  2. hist函数,plot函数,linspace
  3. OpenCV 检测二维码并定位
  4. 但愿人长久(有福利)
  5. 三极管在ad中的原理图库_三极管工作原理介绍,NPN和PNP型三极管的原理图与各个引脚介绍...
  6. C语言 FILE文件指针
  7. JS === 简易放大镜
  8. FPGA程序固化流程
  9. matlab 存mat文件,matlab中mat文件简单存/取
  10. 1.所谓计算机热启动是指(),计算机应基础与应用复习题.doc