Druid-排查conditionDoubleConstAllow配置问题(double const condition)

news2024/11/24 20:50:50

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 {

    @Autowired
    private 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")
    @ConditionalOnMissingBean
    public WallConfig wallConfig() {
        return new WallConfig();
    }
    
    @Bean
    @ConfigurationProperties(FILTER_WALL_PREFIX)
    @ConditionalOnProperty(prefix = FILTER_WALL_PREFIX, name = "enabled")
    @ConditionalOnMissingBean
    public WallFilter wallFilter(WallConfig wallConfig) {
        WallFilter filter = new WallFilter();
        filter.setConfig(wallConfig);
        return filter;
    }

发现可以通过配置修改WallConfig#conditionDoubleConstAllow的值,于是进行配置修改:

spring:
  datasource:
    druid:
      filters: config,wall,stat
      filter:
        wall:
          enabled: true
          config:
            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")
    @ConditionalOnMissingBean
    public 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,stat
      filter:
        wall:
          enabled: true
          config:
            condition-and-alway-true-allow: true
            condition-double-const-allow: true

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

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

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

相关文章

02-线性结构2 一元多项式的乘法与加法运算

一个小时敲&#xff0c;五分钟改错。比一年前进步还是很大的。 但是如果测试点没有提示的话&#xff0c;改到哪年就不一定了( ◔︎ ‸◔︎) 思路 多项式加法&#xff0c;极其类似Merge &#xff08;测试点2&#xff1a;系数加完要是0的话就不用添入结果多项式里了~&#xff…

业务安全分析第19期 | 今年暑假,博物馆的门票为什么抢不到?

目录 “黄牛”&#xff1a;加价代预约、加价售票、兜售野导游套餐 “黄牛”倒票带来的危害 “黄牛”为什么能够抢到票 博物馆与“黄牛”的门票攻防 “黄牛”使用的作弊软件有什么特征 技术上防范“黄牛”的作弊软件抢票 遏制“黄牛”倒票给博物馆带来的收益 随着暑期参观…

电影《碟中谍7:致命清算(上)》观后感

上周看了电影《碟中谍7&#xff1a;致命清算&#xff08;上&#xff09;》&#xff0c;从电影名称就知道&#xff0c;这部电影会有下部&#xff0c;讲述科学进步之后&#xff0c;有AI引发的技术变革&#xff0c;出现了一种AI变体叫做智体的东西&#xff0c;它有自主意思&#x…

【代码随想录 | Leetcode | 第八天】哈希表 | 有效的字母异位词 | 两个数组的交集 | 两数之和

前言 欢迎来到小K的Leetcode|代码随想录|专题化专栏&#xff0c;今天将为大家带来哈希法~有效的字母异位词 | 两个数组的交集 | 两数之和的分享✨ 目录 前言242. 有效的字母异位词349. 两个数组的交集1. 两数之和总结 242. 有效的字母异位词 ✨题目链接点这里 给定两个字符串…

【Vue/element】 el-table实现表格动态新增/插入/删除 表格行,可编辑单元格

el-table实现表格动态新增/插入/删除 表格行&#xff0c;可编辑单元格 效果如下&#xff1a; 点击“新增一行”可以在表格最后新增一行&#xff0c;单元格内容可编辑 点击绿色按钮&#xff0c;可在指定行的后面插入一行 点击红色-按钮&#xff0c;可以删除指定行 原理&#…

【Spring 】执行流程解析:了解Bean的作用域及生命周期

哈喽&#xff0c;哈喽&#xff0c;大家好~ 我是你们的老朋友&#xff1a;保护小周ღ 今天给大家带来的是 Spring 项目的执行流程解析 和 Bean 对象的6 种作用域以及生命周期&#xff0c;本文将为大家讲解&#xff0c;一起来看看叭~ 本期收录于博主的专栏&#xff1a;JavaEE_保…

那些你必须知道的4个matlab小技巧(附最新安装包)

文末福利&#xff1a;MATLAB R2022b软件安装包 MATLAB 简介 01 一、MATLAB简介 数学类科技应用软件包括数值计算&#xff08;Number Crunching&#xff09;型软件和数学分析&#xff08;Math Analysis&#xff09;型软件 数值计算型软件 它们对大批数据具有较强的管理、计…

数据仓库建设-数仓分层

数据仓库能够帮助企业做出更好的决策&#xff0c;提高业务效率和效益&#xff1b;在数据仓库建设时&#xff0c;绕不开的话题就是数仓分层。 一、数据分层的好处 1. 降低数据开发成本 通用的业务逻辑加工好&#xff0c;后续的开发任务可以基于模型快速使用&#xff0c;数据需…

分布式定时任务组件:XXL-JOB

一、GitHub源码地址 https://github.com/xuxueli/xxl-job 二、部署文档 参考&#xff1a;https://blog.csdn.net/qq798867485/article/details/131415408 三、初始化数据库SQL 1、xxl_job_user XxlJob-用户管理 2、xxl_job_group XxlJob-执行器管理 3、xxl…

vue3+vite+pinia+vue-router+ol项目创建及配置

一、vite (一)、定义 vite官网 (二)、操作步骤 注意&#xff1a;两种方式创建目录结构一致 方式一&#xff1a;vite创建脚手架命令&#xff1a; 命令行&#xff1a;npm create vitelatest 然后选择 方式二&#xff1a;命令行直接声明带上vue 二、pinia (一)、定义 定义&#xf…

TortoiseGit 入门指南12:创建标签

前面的文章不止一次的提到过 标签 &#xff08;Tag&#xff09;&#xff0c;我们在《TortoiseGit 入门指南08&#xff1a;浏览引用以及在引用间切换》一文中知道&#xff0c;标签 是一种 引用&#xff1b;还知道每个提交都对应着一个 SHA-1 值&#xff0c;而引用就是 SHA-1 的一…

常见面试题之HashMap

1. 二叉树 1.1 二叉树概述 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只有左子节点&#xff0c;有的节…

jmeter压测过程中,ServerAgent响应异常:Cannot send data to network connection

ServerAgent异常信息&#xff1a; Cannot send data to network connection&#xff08;无法将数据发送到网络连接&#xff09; 原因&#xff1a; linux 防火墙 拦截了当前端口 解决方案&#xff1a; Linux 执行以下命令 /sbin/iptables -I INPUT -p tcp --dport 4445 -j ACC…

高压功率放大器应用场合是什么

高压功率放大器是一种能够将低电压信号转换为高电压输出信号的设备。它通常由前置放大器和功率放大级组成&#xff0c;广泛应用于雷达、医疗、半导体测试和工业自动化等领域。下面安泰电子将介绍高压功率放大器的几个主要应用场合。 一、雷达系统 雷达系统需要产生高频、高功率…

【IDEA大项目依赖分析卡死-解决方案】Processing build files for dependencies analysis...

最近一直在研究一个大型项目&#xff0c;在IDEA里面启动调试的时候&#xff0c;IDEA经常会进行Processing build files for dependencies analysis…&#xff08;处理构建文件进行依赖分析&#xff09;&#xff0c;并且在这个步骤耗时太久甚至直接卡死。经过一些排查找到了解决…

arping命令 ip地址冲突检测 根据ip查mac地址

arping命令介绍 arping 命令主要用来获取ip对应的mac地址&#xff0c;更新本地arp缓存表。平时主要用来探测ip地址是否冲突即同一个网络里&#xff0c;同一个ip不同mac地址的情况。ip地址冲突将导致网络故障。 arping常用命令参数 arping [参数] ip -U 强制更新邻近主机的a…

Android系统开发-入门篇

参见&#xff1a;[视频教程] 写给应用开发的 Android Framework 教程——玩转 AOSP 篇之 Android 系统开发工具推荐 - 掘金 前置条件&#xff1a; android系统源码位于 linux 服务器&#xff0c;ssh 地址假如为&#xff1a;test172.1.10.2本机为windows 1、本机&#xff1a; 下…

leetcode 101.对称二叉树

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;对称二叉树 思路&#xff1a; 这道题和 leetcode 100.相同的树 类似&#xff0c;是上一道的变形题。✨leetcode 100.相同的树 代码链接&#xff1a;【往期文章】leetcode 100.相同的树。这道题把根的左子树和右子树看作两…

ROS:动态参数

目录 一、前言二、概念三、作用四、实际用例4.1需求4.2客户端4.2.1流程4.2.2新建功能包4.2.3添加.cfg文件4.2.4配置 CMakeLists.txt4.2.5编译 4.3服务端(C)4.3.1流程4.3.2vscode配置4.3.3服务器代码实现4.3.4编译配置文件4.3.5执行 4.4服务端(Python)4.4.1流程4.4.2vscode配置4…

Spring核心问题解答

1.谈谈对Spring的理解 Spring是Java EE编程领域的一个轻量级开源框架&#xff0c;该框架由一个叫Rod Johnson的程序员在 2002 年最早提出并随后创建&#xff0c;是为了解决企业级编程开发中的复杂性&#xff0c;实现敏捷开发的应用型框架 。 Spring是一个开源容器框架&#x…