【代码审计】CVE-2023-51074漏洞点解读&修复

最近在看内网相关的东西,好东西都写本地了没发出来,被4riH04X师傅叫去看个洞,浅写一下🤔

CVE-2023-51074 是一个影响 json-path 组件的安全漏洞,涉及基于栈的缓冲区溢出问题,可能导致拒绝服务(DoS)攻击。以下是该漏洞的详细分析:


1.漏洞背景

  • 组件说明
    json-path 是一个用于解析和查询 JSON 数据的库,广泛应用于 Java 生态系统中,例如在 Apache Kafka、Spring Boot 等框架中处理 JSON 配置或数据流。

  • 漏洞本质
    该漏洞存在于 Criteria.parse 方法中,攻击者可通过构造特定的 JSON 查询表达式触发栈溢出,导致进程崩溃或拒绝服务。


2.漏洞原理

  • 触发条件
    当 Criteria.parse 方法处理包含深度嵌套结构复杂递归逻辑的 JSON 查询表达式时,未对解析深度或递归调用进行有效限制,导致栈空间耗尽。

  • 攻击方式
    攻击者发送恶意构造的 JSON 查询请求,利用嵌套层数超过系统栈容量的表达式,触发栈溢出异常,使服务崩溃。


3.影响范围

  • 受影响版本json-path 版本 >= 2.2.0,< 2.9.0

  • 受影响系统
    使用未修复版本 json-path 的应用,尤其是依赖该库处理 JSON 查询的中间件或服务(如 Apache Camel、Kafka Connect 等)

4.漏洞复现&分析

给一段exp

package org.example;

import com.jayway.jsonpath.Criteria;

public class CriteriaFuzzerParse {

    public static void main(String[] args) {
        try {
            parseCriteria();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void parseCriteria() throws Exception {
        // 原始测试用例的解析逻辑
        Criteria result = Criteria.parse("@[\"\",/\\");
    }
}

跑出来结果,成功栈溢出

跟一下调用过程

 

走到readNextToken 

 进来的时候char为[

 又回到了readNextToken,但这时候的char变成了@

走到default调用readPropertyOrFunctionToken

 再次回到readNextToken,而这时候的char又变成了[

最终

PathCompiler#readNextToken与PathCompiler#readBracketPropertyToken

PathCompiler#readNextToken与PathCompiler#readPropertyOrFunctionToken互相依次递归调用 

5.关键解读

在 JsonPath 的语法解析器中,readBracketPropertyToken 和 readPropertyOrFunctionToken 是用于解析 JSONPath 表达式中不同部分的两个关键方法。

方法触发条件典型解析内容示例 JSONPath
readBracketPropertyToken字符为 [ 时尝试方括号内带引号的属性名$['a property']
readPropertyOrFunctionToken字符非 *.[ 时触发直接书写的属性名或函数调用$name$size()

示例解析流程

示例 1:$['user'].name

  1. $ → 根节点

  2. [ → 进入方括号解析分支:

    • readBracketPropertyToken 成功解析 'user'

  3. . → 触发 readDotToken,预期后续属性名。

  4. name → 由 readPropertyOrFunctionToken 解析(因为 name 是 default 分支)。

示例 2:$name.size()

  1. $ → 根节点

  2. n → default 分支,readPropertyOrFunctionToken 解析 name

  3. . → 触发 readDotToken

  4. s → default 分支,readPropertyOrFunctionToken 解析 size() 为函数调用。


代码暴露的关键差异

  • readBracketPropertyToken 是方括号解析的子集,需与其他方括号解析器(如数组索引、过滤器)竞争。

  • readPropertyOrFunctionToken 是兜底处理器,负责解析无特殊前缀符号的属性或函数(可能因解析器实现不同而支持非标准语法)。

重点来看PathCompiler#readBracketPropertyToken的这部分

endPosition是3,即@["",/\的第四个字符"

跟进indexOfNextSignificantChar

最后readPosition为4,即@["",/\的第五个字符,

,不等于],indexOfNextSignificantChar返回-1

但代码逻辑还对indexOfNextSignificantChar的返回值加了1,所以最后拿到的c为0

于是下一轮readNextToken去读@["",/\的第一个字符@

走到PathCompiler#readPropertyOrFunctionToken

@的下一个字符是[,走进图里的分支,设置endPosition为1

最终postion为1,下一轮读到 @["",/\的第二个字符[

从此循环递归调用

 

6.漏洞修复

https://github.com/json-path/JsonPath/commit/71a09c1193726c010917f1157ecbb069ad6c3e3b

 可以看到在indexOfNextSignificantChar处理完后返回了原数据,而没有+1,避免找不到]的时候去重读第一个字符,防止造成递归调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值