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

  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

再次测试:执行成功!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/2737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

正则表达式概念以及语法的使用

目录 1.概念 2. 为什么使用正则表达式&#xff1f; 3. 语法 1.普通字符 非打印字符 2. 特殊字符 3. 限定符 4. 定位符 5. 运算优先级 3.匹配规则 1. 基本模式匹配 2. 字符簇 3. 确定重复出现 1.概念 正则表达式(Regular Expression)是一种文本模式&#xff0c;包…

【Docker】docker-compose基本使用

【Docker】docker-compose基本使用 文章目录 【Docker】docker-compose基本使用1. docker 项目部署弊端2. docker-compose 简介3. 实践4. 模板命令4.1 build 指令4.2 command 指令4.3 container_name 指令4.4 depends_on 指令4.5 env_file 指令4.6 environment 指令4.7 image 指…

基于Redisson的Redis分布式锁

Redisson分布式锁_redissonclient_甩锅虾的博客-CSDN博客 *** 分布式锁*/ public interface DistributedLock {/*** 尝试获取锁* param lockName* param seconds* return*/Boolean tryAcquire(String lockName, long seconds, TimeUnit unit);/*** 释放锁* param lockKey*/v…

如何使用自动化构造随机路由模型

为什么要仿真随机路由&#xff1f; 路由器测试中&#xff0c;为了最大程度还原现网路由情况&#xff0c;评估路由器在现网环境下稳定工作各项指标&#xff0c;需要对导入路由进行离散仿真&#xff0c;目前路由仿真可分为导入路由与生成路由两种方式&#xff0c;导入路由需要现…

vue如何使用webscorket实现多人协同在线表格填写

要使用WebSocket在Vue中实现多人协同在线表格填写&#xff0c;你可以按照以下步骤进行操作&#xff1a;1. 安装WebSocket库&#xff1a;首先&#xff0c;在Vue项目中安装WebSocket库。你可以使用 socket.io-client 库来处理WebSocket通信。使用npm或yarn安装它&#xff1a;npm …

学习遇上的一点补救

从开始学习java到现在逐步确定好发展路线。是时候停一下步伐了。 之前不停的往前走&#xff0c;从学校的课程、书本开始&#xff0c;没有借助网课、视频&#xff0c;依靠自己一步一个脚印。从Java实用程序、Javaweb、JavaEE然后选择MySQL数据库、然后觉得有必要对前端了解&…

think-on-graph: 基于知识图谱的大模型推理

概述 本文的研究背景是大规模语言模型在复杂推理任务中存在困难并展示了较低的性能&#xff0c;特别是在需要知识的追溯能力、及时性和准确性的场景中。 过去的方法主要面临两个问题&#xff1a;推理不负责任容易生成虚构或带有有害文本&#xff0c;以及模型在预训练阶段无法…

【深入浅出C#】章节 5: 高级面向对象编程:泛型编程和集合类型

高级面向对象编程是在基础面向对象编程的基础上进一步深入和拓展的一种编程范式。它强调封装、继承和多态的概念&#xff0c;并引入了泛型编程和集合类型等高级特性。高级面向对象编程提供了更灵活、可扩展和可复用的代码结构&#xff0c;能够帮助开发者构建更复杂、更高效的应…

基于IPC-CFX的点对点通信C#

IPC-CFX有两种主要的通信方式&#xff0c;可以通过RabbitMQ发布和订阅&#xff0c;也可以通过request和response进行点对点的通信&#xff0c;本文主要讲的是点对点的通信方式。 在vscode里建立新的dotnet项目&#xff0c;可以通过终端输入dotnet new console来建立&#xff0c…

【拿来就能用】C#指定打印机打印的类

之前写过一个“C#WinForm程序中选择打印机打印”的文章&#xff0c;但在使用过程中&#xff0c;尤其是生成Word文档时&#xff0c;会感觉系统响应较慢。如果不需要留存打印文档的电子版&#xff0c;可以使用下面的类直接打印。相比之前的方法&#xff0c;这种方法更简单&#x…

MySQL常用语句大全

语句 DDL MySQL的DDL&#xff08;数据定义语言&#xff09;是一组用于创建、修改和删除数据库、表、索引、视图、存储过程和触发器等数据库对象的语句。下面是一些常用的MySQL DDL语句和它们的详细说明&#xff1a; alter 在MySQL中&#xff0c;DDL&#xff08;数据定义语言…

LCD—STM32液晶显示(2.使用FSMC模拟8080时序)

目录 使用STM32的FSMC模拟8080接口时序 FSMC简介 FSMC NOR/PSRAM中的模式B时序图 用FSMC模拟8080时序 重点&#xff1a;HADDR内部地址与FSMC地址信号线的转换&#xff08;实现地址对齐&#xff09; 使用STM32的FSMC模拟8080接口时序 ILI9341的8080通讯接口时序可以由STM32使…

北邮国院物联网 Microprocessor 微处理器笔记

Introduction-随便聊 嵌入式系统是什么&#xff1f;专用的计算机系统。为专门功能可能对计算机架构&#xff0c;外设等做出一些取舍。 通常的限制&#xff1a;Cost&#xff08;比如大量部署传感器节点&#xff09;&#xff0c;Size and weight limits&#xff08;特定应用场景…

配置Hadoop_0

配置Hadoop_0 1配置Hadoop100模板虚拟机1.1配置Hadoop100模板虚拟机硬件1.2配置Hadoop100模板虚拟机软件1.3配置Hadoop100模板虚拟机IP地址1.4配置Hadoop100模板虚拟机主机名称/主机名称映射1.5配置Hadoop100模板虚拟机远程操作工具 1配置Hadoop100模板虚拟机 Hadoop100 内存…

TRT4-trt-integrate - 1 YOLOV5导出、编译、推理

模型导出 修改Image的Input动态维度 首先可以看到这个模型导出的时候Input有三个维度都是动态&#xff0c;而我们之前说过只需要一个batch维度是动态&#xff0c;所以要在export的export onnx 进行修改&#xff0c;将 torch.onnx.export(model, im, f, verboseFalse, opset_ver…

华为云子网路由表作用及价值

子网路由表 子网路由表作用云专线、VPN的配置与子网路由表强关联&#xff0c;本质是在相应的子网路由表中添加了一条路由Nat路由表问题地址变更问题snat和dnat 子网路由表作用 子网内部作为一个二层网络&#xff0c;通过mac地址互通&#xff0c;不通过路由互通。跨子网&#x…

实时网络更改检测

未经授权的配置更改可能会对业务连续性造成严重破坏&#xff0c;这就是为什么使用实时更改检测来检测和跟踪更改是网络管理员的一项关键任务。尽管可以手动跟踪更改&#xff0c;但此方法往往非常耗时&#xff0c;并且通常会导致人为错误&#xff0c;例如在跟踪时错过关键网络设…

企业需要一个数字体验平台(DXP)吗?

数字体验平台是一个软件框架&#xff0c;通过与不同的业务系统喝解决方案集成&#xff0c;帮助企业和机构建立、管理和优化跨渠道的数字体验。帮助企业实现跨网站、电子邮件、移动应用、社交平台、电子商务站点、物联网设备、数字标牌、POS系统等传播内容&#xff0c;除了为其中…

文心一言 VS 讯飞星火 VS chatgpt (58)-- 算法导论6.4 2题

文心一言 VS 讯飞星火 VS chatgpt &#xff08;58&#xff09;-- 算法导论6.4 2题 二、试分析在使用下列循环不变量时&#xff0c;HEAPSORT 的正确性&#xff1a;在算法的第 2~5行 for 循环每次迭代开始时&#xff0c;子数组 A[1…i]是一个包含了数组A[1…n]中第i小元素的最大…

IntelliJ IDEA 2023.1 更新内容总结

IntelliJ IDEA 2023.1 更新内容总结 * 主要更新内容 * UI 大改版 * 性能改进项 * 其它更新内容IntelliJ IDEA 2023.1 更新内容总结 主要更新内容 IntelliJ IDEA 2023.1 针对新的用户界面进行了大量重构,这些改进都是基于收到的宝贵反馈而实现的。官方还实施了性能增强措施, …