若依SQL注入黑名单绕过漏洞代码审计(CVE-2024-42913)

免责声明

本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。

前言:

我们建立了一个更多,更全的知识库。每日追踪最新的安全漏洞,追中25HW情报。

更多详情:

https://pc.fenchuan8.com/#/index?forum=101997&yqm=DHL4E

代码审计

源代码如下

@RequiresRoles("admin")
@Log(title = "创建表", businessType = BusinessType.OTHER)
@PostMapping("/createTable")
@ResponseBody
public AjaxResult create(String sql)
{
    try
    {
        // 过滤SQL中的关键字
        SqlUtil.filterKeyword(sql);
        
        // 解析SQL语句,生成SQLStatement列表
        List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql);
        
        // 用于存储表名的列表
        List<String> tableNames = new ArrayList<>();
        
        // 遍历解析后的SQL语句
        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("创建表结构异常[" + e.getMessage() + "]");
    }
}

其中filterKeyword()过滤了很多SQL关键字

/**
 * SQL关键字检查
 */
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注入风险");
        }
    }
}

看一下SQL_REGEX

注意这里的按照|进行分割的时候,每个关键字如select后边有一个空格,我们可以使用/**/来绕过字符串中空格的匹配

可以调用create函数,因为我们api的功能就是createTable功能

看一下genTableService.createTable(createTableStatement.toString())

继续跟进createTable(sql)

也就是我们写的整个sql字符串会被当做SQL语句执行,且不存在所谓预编译

测试执行

### 关于 Spring Security 中 CVE-2024-22257 漏洞详情 Spring Security 存在一个身份验证绕过漏洞,编号为CVE-2024-22257。此漏洞源于`AuthenticatedVoter#vote`方法在处理认证参数时未能正确检查null值的情况[^4]。 当应用程序调用`AuthenticatedVoter#vote`并传递null作为认证对象时,该方法错误地返回了true的结果。这使得未授权用户能够通过提供null认证信息来绕过系统的正常访问控制机制,进而可能执行越权操作或获取不应有的权限,甚至窃取系统内部的重要数据。 ```java // 易受攻击的代码片段展示 public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { if (authentication == null || !authentication.isAuthenticated()) { return ACCESS_DENIED; } // 如果传入的是null,则此处逻辑判断失误 return ACCESS_GRANTED; } ``` ### 影响范围与风险评估 受影响版本包括但不限于某些特定版本区间内的Spring Security框架实现。由于具体影响版本依赖官方通告更新,在实际环境中应当密切关注供应商发布的补丁说明文档以确认是否受到影响以及如何采取措施加以防范。 ### 修复建议 针对这一安全隐患,推荐开发者遵循如下指导方针: 1. **升级至最新稳定版**:尽快将使用的Spring Security库更新到最新的安全版本,通常新版本会包含对此类已知问题的有效修补程序。 2. **自定义投票器增强校验**:如果无法立即迁移至更高版本,可以在现有项目中重写或扩展默认的身份验证决策管理组件(如`AccessDecisionManager`),确保所有输入都经过严格的非空性和合法性检验后再参与后续流程判定。 3. **加强应用层防护策略**:除了依赖框架自带的安全特性外,还应考虑引入额外的应用级防御手段,比如API网关处设置预检规则过滤掉异常请求头/体结构;或是借助WAF(Web Application Firewall)类产品实施更广泛的流量监控和威胁拦截服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值