alibaba / druid

阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品,为监控而生的数据库连接池
https://github.com/alibaba/druid/wiki
Apache License 2.0
27.9k stars 8.57k forks source link

druid 1.2.21升级到1.2.22 报错:sql injection violation, dbType postgresql, druid-version 1.2.22, select alway true condition not allow #5882

Open litao11046 opened 4 months ago

litao11046 commented 4 months ago

在springboot项目中,使用druid-spring-boot-3-starter组件,将该组件版本从1.2.21升级到1.2.22时,出现报错:sql injection violation, dbType postgresql, druid-version 1.2.22, select alway true condition not allow 配置为:

spring.datasource.druid.filter.wall.config.conditionAndAlwayTrueAllow=truedruid-spring-boot-3-starter

环境信息: dbtype: postgresql jdk: 21

lizongbo commented 4 months ago

以前这个配置没有生效,1.2.22修复了bug,如果认为有误伤,发出具体的sql语句来。

litao11046 commented 4 months ago

sql如下:select sds1_0.id,sds1_0.buildIn,sds1_0.config,sds1_0.dsVersion,sds1_0.failDateTime,sds1_0.failLog,sds1_0.insertDateTime,sds1_0.jpa,sds1_0.jpaAutoUpdateTableSchema,sds1_0.jpaManagedClassNames,sds1_0.jpaPackagesToScan,sds1_0.jpaProperties,sds1_0.lastModDateTime,sds1_0.main,sds1_0.name,sds1_0.notes,sds1_0.status,sds1_0.tenant,sds1_0.type,sds1_0.useConnectionPool from tao_datasource sds1_0 where 1=1 order by sds1_0.insertDateTime offset ? rows fetch first ? rows only] [select sds1_0.id,sds1_0.buildIn,sds1_0.config,sds1_0.dsVersion,sds1_0.failDateTime,sds1_0.failLog,sds1_0.insertDateTime,sds1_0.jpa,sds1_0.jpaAutoUpdateTableSchema,sds1_0.jpaManagedClassNames,sds1_0.jpaPackagesToScan,sds1_0.jpaProperties,sds1_0.lastModDateTime,sds1_0.main,sds1_0.name,sds1_0.notes,sds1_0.status,sds1_0.tenant,sds1_0.type,sds1_0.useConnectionPool from tao_datasource sds1_0 where 1=1 order by sds1_0.insertDateTime offset ? rows fetch first ? rows only

ice2shell commented 3 months ago

这个我想应该和com.alibaba.druid.wall.WallProvider#checkInternal函数中 endOfComment 这个变量赋值改变有关系。 在 #5698 中将 endOfComment 从 parser.getLexer().isEndOfComment() 改为了 parser.getLexer().isEOF() 。如果 SQL 结尾带注释,这两个函数返回结果均为true,如果SQL 结尾不带注释,isEOF 返回 true,isEndOfComment会返回false。在这个函数中 endOfComment 接下来会赋值到 WallVisitor ,而在后续的com.alibaba.druid.wall.spi.WallVisitorUtils#checkSelelct 的校验逻辑中是这样使用的:config.isSelectWhereAlwayTrueCheck() && visitor.isSqlEndOfComment() && isSimpleConstExpr(where) 。所以针对 select * from t where 1=1 这类SQL,1.2.22之前的版本由于 visitor.isSqlEndOfComment() 为false,会直接通过;1.2.22版本则会报错。

这里我也有个疑问:conditionAndAlwayTrueAllow 是只用于校验 and 1=1 这类恒真条件吗?因为这个配置只在com.alibaba.druid.wall.spi.WallVisitorUtils#getConditionValue 这里用到了。看起来是用于对部分条件恒真的校验。

austinuMyaccount commented 1 month ago

你好,这个问题解决了吗

litao11046 commented 1 month ago

放弃了,改用了HikariCP

small-rose commented 2 weeks ago

你好,这个问题解决了吗

解决办法不少啊 (1)改动最少的,降级到1.2.21 (2)不想降级,就取消 wall 配置 (3)不想降级,也不想取消wall配置,就重写druid里校验控制类,把这个visitor.isSqlEndOfComment() 返回false (4)换其他连接池,如默认的 HikariCP