[CVE-ID]
CVE-2024-54762.
[PRODUCT]
RuoYi
[Vendor of Product]
https://github.com/yangzongzhuan/RuoYi
[VERSION]
ruoyi ≤4.8.0
[Vulnerability Type]
SQL Injection
[Description]
/tool/gen/createTable
route within the com/ruoyi/generator/controller/GenController
file is vulnerable to SQL injection.
The key code is as follows:
@RequiresRoles("admin")
@Log(title = "创建表", businessType = BusinessType.OTHER)
@PostMapping("/createTable")
@ResponseBody
public AjaxResult create(String sql)
{
try
{
SqlUtil.filterKeyword(sql);
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql);
List<String> tableNames = new ArrayList<>();
for (SQLStatement sqlStatement : sqlStatements)
{
if (sqlStatement instanceof MySqlCreateTableStatement)
{
MySqlCreateTableStatement createTableStatement = (MySqlCreateTableStatement) sqlStatement;
if (genTableService.createTable(createTableStatement.toString()))
{
String tableName = createTableStatement.getTableName().replaceAll("`", "");
tableNames.add(tableName);
}
}
}
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames.toArray(new String[tableNames.size()]));
String operName = Convert.toStr(PermissionUtils.getPrincipalProperty("loginName"));
genTableService.importGenTable(tableList, operName);
return AjaxResult.success();
}
catch (Exception e)
{
logger.error(e.getMessage(), e);
return AjaxResult.error("创建表结构异常");
}
}
Within it, there exists an SQL injection filtering function named sqlUtil.filterKeyword
, and its blacklist is as follows:
public static String SQL_REGEX = "\\u000B|and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
public static void filterKeyword(String value)
{
if (StringUtils.isEmpty(value))
{
return;
}
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\\\|");
for (String sqlKeyword : sqlKeywords)
{
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
{
throw new UtilException("参数存在SQL注入风险");
}
}
}
The blacklist filtering function can be bypassed using %0A
. For example, select%0A
can be used to circumvent the filter.
POC: