• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

flyway报错: sql injection violation, dbType mysql, druid-version xxx, syntax error: illegal name...

武飞扬头像
gaoyq28
帮助1

1. 背景

最近在项目中使用driud dynamic flyway自动执行数据库脚本的时候,碰到一些包含“if not exists” 字样的sql语句时,项目启动会报SQL注入错误。

2. 报错信息

SQL State  : null
Error Code : 0
Message    : sql injection violation, dbType mysql, , druid-version 1.2.5, syntax error: illegal name, pos 37, line 1, column 36, token IF : alter table `xxxxxxxx` add column if not exists `xxxxxx` varchar(10) comment 'xxxxxx'
Location   : db/migration/V001__flyway_test_add_column.sql (/xxxxxxx/V001__flyway_test_add_column.sql)
Line       : 1
Statement  : alter table `xxxxxxxx` add column if not exists `xxxxxx` varchar(10) comment 'xxxxxx'

Caused by: java.sql.SQLException: sql injection violation, dbType mysql, , druid-version 1.2.5, syntax error: illegal name, pos 37, line 1, column 36, token IF :  alter table `xxxxxxxx` add column if not exists `xxxxxx` 
	at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:849)
	at com.alibaba.druid.wall.WallFilter.check(WallFilter.java:821)
	at com.alibaba.druid.wall.WallFilter.statement_execute(WallFilter.java:454)
	at com.alibaba.druid.filter.FilterChainImpl.statement_execute(FilterChainImpl.java:3008)
	at com.alibaba.druid.filter.FilterAdapter.statement_execute(FilterAdapter.java:2484)
	at com.alibaba.druid.filter.FilterEventAdapter.statement_execute(FilterEventAdapter.java:188)
	at com.alibaba.druid.filter.FilterChainImpl.statement_execute(FilterChainImpl.java:3008)
	at com.alibaba.druid.proxy.jdbc.StatementProxyImpl.execute(StatementProxyImpl.java:147)
	at com.alibaba.druid.pool.DruidPooledStatement.execute(DruidPooledStatement.java:632)
	at org.flywaydb.core.internal.jdbc.JdbcTemplate.executeStatement(JdbcTemplate.java:244)
	at org.flywaydb.core.internal.sqlscript.ParsedSqlStatement.execute(ParsedSqlStatement.java:111)
	at org.flywaydb.core.internal.sqlscript.DefaultSqlScriptExecutor.executeStatement(DefaultSqlScriptExecutor.java:208)
	... 52 common frames omitted
学新通

该信息大致含义是脚本中的‘IF’关键字存在注入风险。导致driud的防火墙过滤器检查不通过。但奇怪的是,我把引入的多数据源框架dynamic注释掉后,相同的SQL脚本不会报错。所以我怀疑是苞米豆中修改了driud防火墙的策略

<!--注掉这个引用的多数据源包,再启动就不会报错-->
<dependency>
	<groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.2.0</version>
 </dependency>

3. 解决方案

根据报错信息*com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:849)*找到抛出错误的地方,如下所示:
学新通
抛出该异常的正是847行,我们注意到844行有个throwException变量,那如果把这个变量变成false是不是就能解决问题?所以第一个解决方案正是修改变量值
方案一:修改throwException
点击throwException,发现该值默认true,实例化WallFilter时会从系统参数中获取,如下所示:
学新通
因此可以在启动参数或者其他地方put一个该key(ps: 我是在启动参数中增加配置项)
启动参数增加

-Ddruid.wall.throwException=false #对被认为是攻击的SQL不抛出异常
-Ddruid.wall.logViolation=true #该参数是为了打印错误日志

再次启动程序,不再报错,flyway脚本也顺利执行完成!

方案二:修改filters默认值
方案一是已经检查出了攻击SQL,但是没有抛出异常而已。那么我们能不能直接不让防火墙过滤器执行呢?我之前尝试改过很多driud相关的配置项,如druid.filter.wall.enabled=false,但是我发现这些配置在集成了dynamic之后并不起作用。于是断点调试发现在数据源初始化的时候会去加载driud的防火墙配置,并且该配置项默认“监控”和“防火墙”。
学新通学新通
我们注意到只有filters中包含wall才会开启防火墙。所以我们可以把“druid.filters”的值可以改为null或者其他值(只要不包含wall就行)

spring.datasource.dynamic.druid.filters: null 或者 stat

再次启动程序,不再报错,flyway脚本也顺利执行完成!

4. 总结

之所以报错是因为多数据源配置项默认开启了driud的防注入功能,导致 IF 这类的逻辑判断语法检查不通过。可以通过不抛出异常或者关闭filters解决该问题!!

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgghcjk
系列文章
更多 icon
同类精品
更多 icon
继续加载