
Static code audit of CVE-2024-57521, an authenticated SQL injection in RuoYi-Vue's generator module, with source-to-sink analysis and a %0b filter bypass PoC.
本仓库仅供安全研究与教育目的使用。请勿利用本文档中的技术进行未授权的攻击行为。所有测试均在本地静态代码审计环境下完成。
ruoyi-generator 模块)ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java关键代码:
@PostMapping("/createTable")
public AjaxResult createTableSave(@RequestParam("sql") String sql, @RequestParam("tplWebType") String tplWebType)
{
try
{
SqlUtil.filterKeyword(sql); // 在进入业务前调用过滤器
分析:后台管理员可以通过 HTTP POST 请求的 sql 参数传入任意的数据库建表语句。入口点对用户输入未进行充分限制,直接交由后续过滤器处理。
截图证据:

· 文件位置:ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java
核心缺陷代码:
// 第16行:黑名单定义,注意关键词带有【尾随空格】
public static String SQL_REGEX = "\u0008|%0A|and |extractvalue|updatexml|sleep|information_schema|exec...";
// 第61-66行:过滤逻辑
String normalizedValue = value.replaceAll("\\p{Z}|\\s", ""); // 先清空了输入里的所有空格
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
for (String sqlKeyword : sqlKeywords)
{
if (StringUtils.indexOfIgnoreCase(normalizedValue, sqlKeyword) > -1)
{
throw new UtilException("请求参数包含敏感关键词" + sqlKeyword + ",可能存在安全风险");
}
}
缺陷分析:过滤器首先执行 replaceAll("\p{Z}|\s", "") 删除了输入中的所有空白字符。但是黑名单 SQL_REGEX 里的关键词(如 "and ","select ")却是带尾随空格的。这导致匹配必然失败,只要攻击者在关键词后使用 %0b(垂直制表符)替代空格,即可完美绕过黑名单检查。
截图证据:
· 文件位置:ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml
关键代码:
<update id="createTable">
${sql}
</update>
分析:MyBatis 中 ${} 会直接拼接字符串,而不是使用安全的预编译 #{}。导致已绕过过滤器的恶意 SQL 被送入数据库执行。这是典型的“黑名单过滤 + 不安全拼接”组合漏洞。
截图证据:
· 方法:攻击者使用 %0b(MySQL 的垂直制表符,属于 \s 匹配范围)替代 SQL 语句中的空格。
· 探测原理:利用 IF(<条件>, 1, 1/0) 作为布尔盲注的探测器。 · 条件为假:触发除零错误,服务器返回 HTTP 500。 · 条件为真:正常无报错。 · 提取方式:使用二分法就可以逐位猜解数据库数据。
这个漏洞是典型的“修复不彻底”导致的绕过。开发者在修复此前同类 SQL 注入时引入了黑名单机制,但忽略了黑名单依赖空格,而清空空格的前置逻辑会破坏黑名单的匹配条件,最终导致新的绕过(CVE-2024-57521)。
· 废除黑名单机制:不要依赖黑名单,白名单机制才是安全的根基。 · 使用预编译:将 MyBatis 中的 ${sql} 改为 #{} 预编译方式。如果必须动态传入 SQL(如建表、Order By),应使用严格的抽象语法树(AST)解析或严格的参数校验。 · 完善过滤器:如必须使用黑名单,需去除黑名单关键词的尾部空格,并在比对前进行统一标准化(如统一转为小写、将 %0b 等替换为空格)。
· NVD - CVE-2024-57521 · RuoYi-Vue Gitee 仓库