Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
jackson — 本仓库针对 CVE-2025-52999、GHSA-2m67-wjpj-xhg9 和 sonatype-2022-6438 中报告的拒绝服务及无限制或无节流资源分配安全漏洞,提供了全面的安全修复,同时保持与 jackson‑core 2.13.5 的完全兼容性。 | Kitploit
工具/GitHubGitHub/sassoftware/jackson
通用工具静态分析漏洞分析代码分析供应链安全
GitHubsassoftware/jackson

jackson

本仓库针对 CVE-2025-52999、GHSA-2m67-wjpj-xhg9 和 sonatype-2022-6438 中报告的拒绝服务及无限制或无节流资源分配安全漏洞,提供了全面的安全修复,同时保持与 jackson‑core 2.13.5 的完全兼容性。

查看仓库
124个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Jackson core 2.13.5 安全漏洞分析与修复

  • CVE-2025-52999
  • SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924
  • SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 (GHSA-2m67-wjpj-xhg9)
  • SNYK-JAVA-COMFASTERXMLJACKSONCORE-7569538 (Sonatype-2022-6438)

此分支(2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9)包含针对 jackson-core 2.13.5 的拒绝服务(DoS)及“无限制或节流的资源分配”漏洞的全面安全修复。它引入了 StreamReadConstraints API — 与 jackson-core 2.15.0 引入的 API 保持一致,但扩展了更广泛的解析器覆盖范围 并增加了额外的攻击向量防护 — 解决了一个嵌套深度耗尽攻击 (CVE-2025-52999)、无限制或节流的资源分配(SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924)、一个文档长度约束绕过漏洞(SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9)以及一个数值令牌长度耗尽攻击(Sonatype-2022-6438),同时保持与 jackson-core 2.13.5 版本的公共 API 表面兼容。

分支历史

分支已修复的漏洞
2.13.5-CVE-2025-52999-sonatype-2022-6438CVE-2025-52999, Sonatype-2022-6438, SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924
2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9以上所有漏洞 + GHSA-2m67-wjpj-xhg9(文档长度约束绕过)

原始分支(2.13.5-CVE-2025-52999-sonatype-2022-6438)修复了三个漏洞 并保存在 sasso 远程仓库中。此分支在其基础上增加了对 GHSA-2m67-wjpj-xhg9 的修复, 该修复在所有解析器路径上强制执行 maxDocumentLength。


漏洞概述


受影响与已修复版本


漏洞描述

CVE-2025-52999 — 无限制的 JSON 嵌套深度

NVD 条目

官方 NVD 描述

jackson-core 包含 Jackson 数据处理器使用的基本低级增量(“流式”)解析器和生成器抽象。 在 2.15.0 之前的版本中,如果用户解析一个输入文件并且该文件包含深度嵌套的数据,则当嵌套特别深时,Jackson 可能抛出 StackOverflowError。 jackson-core 2.15.0 包含一个可配置的深度限制,控制 Jackson 在输入文档中的遍历深度,默认允许深度为 1000。 当达到该限制时,jackson-core 将抛出 StreamConstraintsException。jackson-databind 也受益于此更改,因为它使用 jackson-core 解析 JSON 输入。 作为临时解决方法,用户应避免解析来自不可信来源的输入文件。

临时解决方法: 在部署修复版本之前,避免解析来自不可信来源的 JSON 输入。


根本原因: 在 2.15.0 之前,JsonParser 对 JSON 文档的嵌套深度没有设置任何限制。每个数组 [ 或对象 { 令牌都会导致 JsonReadContext.createChildArrayContext() / createChildObjectContext() 在堆上分配一个新的上下文节点并递增引用链。攻击者可以构造一个包含数万层嵌套的文档,导致 Java 虚拟机耗尽线程栈或堆内存。

易受攻击的代码路径:

该缺失检查在四个解析器实现中均可到达:``` JsonParser.nextToken() // common entry point │ ├─ ReaderBasedJsonParser → _parsePunctuationMark() ├─ UTF8StreamJsonParser → _parsePunctuationMark() ├─ UTF8DataInputJsonParser → _parsePunctuationMark() └─ NonBlockingJsonParserBase → _startArrayScope() / _startObjectScope() │ ▼ _parsingContext.createChildArrayContext() // '[' encountered _parsingContext.createChildObjectContext() // '{' encountered ⚠ no depth check — context chain grows without bound

root@kitploit:~
所有四个 `JsonParser` 实现都存在此缺陷。攻击同样可通过其中任何一个进行利用——无论输入是通过 `InputStream`、`Reader`、`DataInput` 还是异步非阻塞的 feeder API 到达。

**攻击向量:**

| # | 策略 | 示例负载 | 深度增量 | 受影响的解析器 |
|---|------|----------|---------|----------------|
| 1 | 数组嵌套 | `[[[…]]]` — 1,001 个连续的 `[` 令牌 | 每 `[` 增加 +1 | 所有四个 |
| 2 | 对象嵌套 | `{"k":{"k":{…}}}` — 1,001 个连续的 `{` 令牌 | 每 `{` 增加 +1 | 所有四个 |
| 3 | 交替嵌套 | `[{"k":[{"k":…}]}]` — 1,001 个混合 `[`/`{` 令牌 | 每 `[` 或 `{` 增加 +1 | 所有四个 |

关键观察:

- **数组嵌套——最小开销:** 仅需要 `[` 和 `]` 令牌;无需键、值或空白。一个 2,002 字节的负载包含 1,001 对括号就足以超过默认的 1,000 限制。
- **对象嵌套——放大的堆压力:** 每个 `{` 额外在深度链节点上分配一个 `JsonReadContext` 键槽,在极端深度下加剧内存消耗。
- **交替嵌套——绕过Web应用防火墙(WAF):** 检测重复 `[[[` 或 `{{{` 序列的模式匹配防御对交替令牌嵌套无效;无论令牌类型如何,解析器的深度计数器都会相同地递增。
- **非阻塞 feeder——相同负载,不同交付面:** 所有三种嵌套策略均可通过 `NonBlockingJsonParser` 和 `ByteArrayFeeder` API 同样利用。文档可以以任意小的块交付;无论字节如何到达,`NonBlockingJsonParserBase._startArrayScope()` / `_startObjectScope()` 都会在每个打开上下文的令牌上递增深度计数器,并在多个 `feedInput()` 调用中累计深度。

所有三种嵌套策略均可通过四个 `JsonParser` 实现中的任何一个达到。
在 2.13.5 中,解析会静默成功;通过此修复,所有三个向量都会抛出 `StreamConstraintsException: Depth (1001) exceeds the maximum allowed nesting depth (1000)`。

---

### Sonatype-2022-6438 — 无界数字令牌长度

**安全详情**

| 字段 | 值 |
|------|-----|
| Sonatype ID | [sonatype-2022-6438](https://guide.sonatype.com/vulnerability/sonatype-2022-6438/security-details) |
| 描述 | jackson-core — 拒绝服务 (DoS) |
| 发布时间 | 2022-12-07 |
| 来源 | Sonatype |
| CVSS v3.1 评分 | **7.5 高** — `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H` |
| CWE | [CWE-770](https://cwe.mitre.org/data/definitions/770.html) — 无限制或节流的资源分配 |
| EPSS 评分 | 0% |
| 上游修复 PR | [jackson-core#827](https://github.com/FasterXML/jackson-core/pull/827), [jackson-core#846](https://github.com/FasterXML/jackson-core/pull/846) |

**受影响的方法(由 Sonatype 识别)**

| 方法 | 备注 |
|------|------|
| `com.fasterxml.jackson.core.base.ParserBase._parseSlowInt(I)V` | 易受攻击的参数:索引 0 |
| `com.fasterxml.jackson.core.base.ParserBase.convertNumberToBigDecimal()V` | |
| `com.fasterxml.jackson.core.base.ParserMinimalBase.getValueAsDouble(D)D` | 易受攻击的参数:索引 0 |
| `com.fasterxml.jackson.core.util.TextBuffer.contentsAsDecimal()` | 返回 `BigDecimal` |
| `com.fasterxml.jackson.core.util.TextBuffer.contentsAsDouble(Z)D` | |
| `com.fasterxml.jackson.core.util.TextBuffer.contentsAsFloat(Z)F` | |

这些方法中的每一个都在未首先验证其长度的情况下处理原始数字缓冲区。当 JVM 尝试从无约束的缓冲区内容中实例化 `BigInteger` 或 `BigDecimal` 时,传递足够长的数字令牌会触发无界的堆分配和 CPU 耗尽。

---

**根本原因:** 在 2.15.0 之前,`JsonParser` 对整数、科学计数法、简单浮点数或复合浮点数令牌的字节长度没有施加限制。当解析器分配其内部 `_textBuffer` 来累积数字时,攻击者可以提供具有数百万位数字的数字,导致缓冲区无界增长并最终耗尽堆内存。

**易受攻击的代码路径:**

存在两个结构上不同的易受攻击路径——一个由三个同步解析器共享,另一个通过异步解析器的独立路径。

**路径 A — 同步解析器**(三个实现,一个共享接收器):```
JsonParser.nextToken()                         // common entry point
  │
  ├─ ReaderBasedJsonParser   ─┐
  ├─ UTF8StreamJsonParser     ├─→ ParserBase.resetInt() / resetFloat()
  └─ UTF8DataInputJsonParser ─┘         │
                                        ▼
                               _textBuffer.contentsAsString()
                               ⚠  no length check — buffer grows without bound

路径 B — 异步解析器(独立的代码路径,单独未加保护):``` NonBlockingJsonParser.nextToken() │ ├─ _startPositiveNumber() / _startNegativeNumber() // integer paths ├─ _finishNumberIntegralPart() ├─ _startFloat() // floating-point paths ├─ _finishFloatFraction() └─ _finishFloatExponent() │ ▼ writes _intLength / _fractLength / _expLength directly ⚠ never calls ParserBase.resetInt() / resetFloat() ⚠ constraint validation bypassed entirely

root@kitploit:~
非阻塞(异步)解析器是一个特别值得注意的攻击面:它在 `_startPositiveNumber`、`_startNegativeNumber`、`_finishNumberIntegralPart`、`_startFloat`、`_finishFloatFraction` 和 `_finishFloatExponent` 中拥有自己的数字累加循环,这些循环直接设置 `_intLength` / `_fractLength` / `_expLength`,而完全不经过 `ParserBase.resetInt()` 或 `resetFloat()`。这意味着上游 PR #827 的修复(仅向 `ParserBase` 添加了验证)**使 `NonBlockingJsonParser` 完全未受保护**。这一点是在扩展攻击面分析期间发现的,并在此分支中进行了修复。

**攻击向量:**

| # | Token 形状 | 示例载荷 | `intLen` | `fractLen` | `expLen` | 总计 | 约束 |
|---|------------|----------------|----------|------------|----------|-------|------------|
| 1 | 整数 | `999…` — 199,999 个连续数字 | 199,999 | 0 | 0 | 199,999 | `validateIntegerLength` |
| 2 | 十进制小数 | `0.999…` — 1 位整数部分,1,001 位小数部分 | 1 | 1,001 | 0 | 1,002 | `validateFPLength` |
| 3 | 科学计数法 | `1e999…` — 1 位有效数字,1,001 位指数 | 1 | 0 | 1,001 | 1,002 | `validateFPLength` |
| 4 | 复合浮点数 | `0.999…e999…` — 500 位小数部分,500 位指数 | 1 | 500 | 500 | 1,001 | `validateFPLength` |

关键观察:

- **整数——符号字符不是数字:** 前缀 `-` 被排除在数字累加之外;`-999…` 和 `999…` 产生相同的 `intLen` 值,并在相同阈值处触发约束。
- **十进制小数——短整数,无界小数:** 整数部分可能只有一位数字 (0),而小数部分可以无限增长;小数点本身不计入计数。
- **科学计数法——紧凑但灾难性:** 大约 1,004 字节,这是最小有效载荷;它强制实例化一个精度为 ±10^1001 的 `BigDecimal`,尽管 token 很小,却要求无界的中间堆分配。
- **复合浮点数——分界规避:** 当 `fractLen = 500` 且 `expLen = 500` 时,两个分量单独均未达到 1,000 位阈值。统一的检查 `validateFPLength(intLen + fractLen + expLen)` 是堵住这个漏洞的唯一防御。
- **非阻塞解析器——独立绕过:** 以上所有四种 token 形状都可以通过 `NonBlockingJsonParser`(通过 `ByteArrayFeeder`)独立利用。与同步解析器不同,`NonBlockingJsonParser` 在私有循环(`_startPositiveNumber`、`_finishNumberIntegralPart`、`_startFloat`、`_finishFloatFraction`、`_finishFloatExponent`)中累加数字,这些循环直接写入 `_intLength` / `_fractLength` / `_expLength`,完全绕过了 `ParserBase.resetInt()` 和 `resetFloat()`。因此,仅修改了 `ParserBase` 的上游 PR #827 使该解析器完全未受保护,本修复中需要六个独立的调用点补丁。

所有四种 token 形状以及非阻塞绕过都在词法分析阶段被拒绝——在任何 `BigDecimal` 或 `BigInteger` 被构造之前——通过 `ParserBase`(同步解析器)中的 `validateIntegerLength` 和 `validateFPLength`,以及 `NonBlockingJsonParser`(异步解析器)中的六个专用调用点。在 2.13.5 中,所有四种 token 形状都被静默接受;经过此修复,每个解析器都会抛出 `StreamConstraintsException: Number length (N) exceeds the maximum length (1000)`。

> **关于 `UTF8DataInputJsonParser` 与大载荷的说明:** DataInput 解析器有一个预先存在的内部缓冲区限制,为 65,536 字节([jackson-core#493](https://github.com/FasterXML/jackson-core/issues/493))。超过此大小的文档(例如,199,999 位 PoC 载荷 ≈ 200 KB)会在长度约束触发之前导致 `ArrayIndexOutOfBoundsException`。因此,`UTF8DataInputJsonParser` 的数字长度保护使用较短的载荷(≤ 1,001 位)进行验证,在该范围内 bug 仍然可重现。

---

### SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9 — 文档长度约束绕过

**安全详情**

| 字段 | 值 |
|-------|-------|
| Snyk ID | [SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551](https://security.snyk.io/vuln/SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551) |
| GitHub 公告 | [GHSA-2m67-wjpj-xhg9](https://github.com/FasterXML/jackson-core/security/advisories/GHSA-2m67-wjpj-xhg9) |
| 描述 | 资源分配无限制或节流 |
| 披露日期 | 2026-04-04 |
| CVSS v4.0 分数 | **8.7 高危** |
| CWE | [CWE-770](https://cwe.mitre.org/data/definitions/770.html) — 资源分配无限制或节流 |
| 受影响版本 | [2.8.0, 2.21.2) |
| 上游修复 | jackson-core 2.18.7、2.21.2 或更高版本 |
| 修复提交 | [74c9ee25](https://github.com/FasterXML/jackson-core/commit/74c9ee25) (3.x), [7ce3622f](https://github.com/FasterXML/jackson-core/commit/7ce3622f) (2.18.x) |

**根本原因:** 即使配置了 `StreamReadConstraints.maxDocumentLength`,在 2.18.7 / 2.21.2 之前的版本也未在任何解析器路径中强制执行文档长度限制。阻塞解析器(`UTF8StreamJsonParser`、`ReaderBasedJsonParser`)从未根据配置的限制验证累加的字节读取量。异步解析器(`NonBlockingJsonParser`)在 `feedInput()` 中也缺乏验证。`UTF8DataInputJsonParser` 没有任何机制来跟踪消耗的总字节数。

在 jackson-core 2.13.5 中,`maxDocumentLength` 根本不存在,因此无法约束文档大小。此修复在 `StreamReadConstraints` 中引入了 `maxDocumentLength` 字段,并在所有解析器路径中强制执行。

**受影响解析器路径:**

| 解析器 | 路径 | 执行点 |
|--------|------|-------------------|
| `UTF8StreamJsonParser` | `InputStream` → `_loadMore()` | 每次缓冲区重填后和文件结束(EOF)时验证 `_currInputProcessed + count` |
| `ReaderBasedJsonParser` | `Reader` → `_loadMore()` | 与 `UTF8StreamJsonParser` 相同模式 |
| `NonBlockingJsonParser` | `feedInput()` | 每个输入块后验证 `_currInputProcessed + _origBufferLen` |
| `UTF8DataInputJsonParser` | `DataInput` | 快速失败:如果配置了 `maxDocumentLength`,则抛出 `StreamConstraintsException` |

**攻击场景:** 攻击者向一个已配置 `maxDocumentLength` 以防止资源耗尽的服务发送一个有效但过大的 JSON 文档(例如,深度嵌套或高度重复的结构,大小达数 GB)。在没有强制执行的情况下,解析器无论配置的限制如何都会处理整个文档,消耗无限的内存和 CPU。

---

## 安全影响

所有四个漏洞均可远程利用,无需认证:

- 任何通过 `JsonParser`(直接或通过 Jackson Databind,它包装了 `jackson-core`)解析攻击者控制的 JSON 的服务都存在风险。
- 攻击很容易构造——只需几百字节的 JSON 即可触发无界的资源消耗。
- 无机密性或完整性影响;可用性(DoS)是唯一的影响类别。

---

## 修复详情

### 官方升级(推荐)

升级到 **jackson-core 2.15.4** 或任何更高稳定版本。所有 2.15.x 和 2.16+ 版本都包含带有安全默认值的 `StreamReadConstraints` API。```xml
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.15.4</version>
</dependency>

本分支(针对 2.13.5 的安全修复)

如果无法立即升级到更新的版本,本分支会对 2.13.5 代码库应用全面的修复。它引入了 StreamReadConstraints 和 StreamConstraintsException,API 与 2.15.x 兼容,并将约束接入所有四个 JsonParser 实现 —— 包括上游修复未覆盖的非阻塞解析器 —— 并强制执行以下默认限制:

约束默认限制
最大嵌套深度1,000
最大数字令牌长度1,000 位数字
最大字符串令牌长度1,000,000 个字符
最大 BigDecimal 标度量级100,000

修复实现细节

新类

StreamReadConstraints (356 行)

不可变值对象,保存每个解析器的流读取限制,通过 Builder 构造:```java // Default constraints (used by all parsers unless overridden) StreamReadConstraints defaults = StreamReadConstraints.defaults();

// Custom constraints StreamReadConstraints custom = StreamReadConstraints.builder() .maxNestingDepth(500) .maxNumberLength(2000) .maxStringLength(5000000) .build();

root@kitploit:~
验证方法(由解析器在每个新token上调用):```java
void validateNestingDepth(int depth) throws StreamConstraintsException;
void validateIntegerLength(int length) throws StreamConstraintsException;
void validateFPLength(int length) throws StreamConstraintsException;
void validateStringLength(int length) throws StreamConstraintsException;
void validateBigIntegerScale(int scale) throws StreamConstraintsException;

Exception message format:

  • "Depth (%d) exceeds the maximum allowed nesting depth (%d)"
  • "Number length (%d) exceeds the maximum length (%d)"
  • "String length (%d) exceeds the maximum length (%d)"
  • "BigDecimal scale (%d) magnitude exceeds maximum allowed (%d)"

StreamConstraintsException (52行)

继承自 StreamReadException(本身是 JsonProcessingException)。仅由 StreamReadConstraints 的验证方法抛出。


修改的文件

base/ParserBase.java

添加了 _streamReadConstraints 字段(默认为 StreamReadConstraints.defaults())。

resetInt() 和 resetFloat() 现在在令牌累积后立即验证数字令牌长度:```java protected void resetInt(boolean negative, int intLen) throws IOException { _streamReadConstraints.validateIntegerLength(intLen); // … existing reset logic … }

protected void resetFloat(boolean negative, int intLen, int decLen, int expLen) throws IOException { int totalLen = intLen + decLen + expLen; _streamReadConstraints.validateFPLength(totalLen); // … existing reset logic … }

root@kitploit:~
新的辅助方法 `_createChildArrayContext()` 和 `_createChildObjectContext()` 用深度检查包裹上下文创建:```java
protected JsonReadContext _createChildArrayContext(int line, int col) throws IOException {
    _streamReadConstraints.validateNestingDepth(_parsingContext.getNestingDepth() + 1);
    return _parsingContext.createChildArrayContext(line, col);
}

解析器实现

所有四个解析器现在都调用新的深度检查辅助函数,而不是直接访问 _parsingContext.createChild*():

  • json/ReaderBasedJsonParser.java
  • json/UTF8StreamJsonParser.java
  • json/UTF8DataInputJsonParser.java
  • json/async/NonBlockingJsonParserBase.java

JsonStreamContext.java

添加了 getNestingDepth() 方法,该方法遍历父链以计算绝对深度:```java public int getNestingDepth() { int depth = 0; JsonStreamContext curr = this; while ((curr = curr.getParent()) != null) { depth++; } return depth; }

root@kitploit:~
#### `json/JsonReadContext.java`

`createChildArrayContext()` 和 `createChildObjectContext()` 的方法签名已更新以传播 `throws IOException`。

#### `json/async/NonBlockingJsonParser.java` (仅限 Sonatype-2022-6438)

这是在上游 PR #827 范围之外发现的主要额外修复。六个绕过 `ParserBase.resetInt()` 的数字完成位点被单独修复:

| 方法 | 添加的验证 |
|------|------------|
| `_startPositiveNumber()` — fast-path return | `validateIntegerLength(_intLength)` |
| `_startNegativeNumber()` — fast-path return | `validateIntegerLength(_intLength)` |
| `_finishNumberIntegralPart()` — final return | `validateIntegerLength(_intLength)` |
| `_finishToken()` case `MINOR_NUMBER_INTEGER_DIGITS` | `validateIntegerLength(_intLength)` |
| `_startFloat()` / `_finishFloatFraction()` / `_finishFloatExponent()` final returns | `validateFPLength(_intLength + _fractLength + _expLength)` |
| `_finishToken()` cases `MINOR_NUMBER_FRACTION_DIGITS` / `MINOR_NUMBER_EXPONENT_DIGITS` | `validateFPLength(...)` |

所有位点都是可达的:快速路径方法处理完整数字在单次 `feedInput()` 调用中可用的情况;`MINOR_*` 恢复状态情况处理数字位跨多次调用到达的分块情况。两条路径都必须被防护。

---

## 测试覆盖

### CVE-2025-52999 — 嵌套深度测试

| 测试文件 | 测试方法 | 解析器模式 | 覆盖范围 |
|-----------|-------------|-------------|--------|
| `read/ArrayParsingTest.java` | `testCVE_2025_52999` | stream | 递归遍历模拟实际应用使用;确认在深度 1001 处抛出 `StreamConstraintsException`(已修复),在深度 20,000 处抛出 `StackOverflowError`(2.13.5) |
| `read/ArrayParsingTest.java` | `testCustomNestingDepthConstraint` | direct API | `StreamReadConstraints.builder().maxNestingDepth(5)` — 访问器,达到限制通过,超出限制抛出 |
| `read/ArrayParsingTest.java` | `testObjectNestingDepthLimit` | stream | 对象正好在限制 1000(通过),1001 级对象抛出 |
| `read/ArrayParsingTest.java` | `testDataInputParserDepthLimit` | `UTF8DataInputJsonParser` | `UTF8DataInputJsonParser` 强制执行 1001 级深度限制 |
| `read/ArrayParsingTest.java` | `testNonBlockingParserDepthLimit` | non-blocking | `NonBlockingJsonParser` 强制执行 1001 级深度限制 |

### Sonatype-2022-6438 — 数字长度测试

| 测试文件 | 测试方法 | 解析器模式 | 覆盖范围 |
|-----------|-------------|-------------|--------|
| `read/NumberOverflowTest.java` | `testSonatype_2022_6438` | `ALL_MODES` | 整数在限制内(通过),整数超出限制(失败),浮点数在限制内(通过),浮点数超出限制(失败),科学记数法指数在限制内(通过),指数超出限制(失败)— 所有四个解析器 |
| `read/NumberOverflowTest.java` | `testNonBlockingParserNumericLengthLimit` | non-blocking | `NonBlockingJsonParser` 强制执行数字长度 |
| `read/NumberOverflowTest.java` | `testNonBlockingParserExponentLengthLimit` | non-blocking | `NonBlockingJsonParser` 通过 `validateFPLength` 强制执行科学记数法指数长度 |
| `read/NumberOverflowTest.java` | `testCustomMaxNumberLengthConstraint` | direct API | `StreamReadConstraints.builder().maxNumberLength(5)` — 访问器,达到限制通过,超出限制对 `validateIntegerLength()` 和 `validateFPLength()` 都抛出,错误消息格式 |

> **解析器模式键:**
> - `ALL_STREAMING_MODES` = `UTF8StreamJsonParser` (stream), `UTF8StreamJsonParser` (throttled), `ReaderBasedJsonParser`
> - `ALL_MODES` = 上述三种 + `UTF8DataInputJsonParser`
> - `non-blocking` = `NonBlockingJsonParser` via `ByteArrayFeeder`
> - `stream` = `UTF8StreamJsonParser` (默认 `JsonFactory.createParser`)

### SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 — 文档长度测试

| 测试文件 | 测试方法 | 解析器模式 | 覆盖范围 |
|-----------|-------------|-------------|--------|
| `constraints/LargeDocReadTest.java` | `testInputStreamExceedsLimit` | `UTF8StreamJsonParser` | InputStream 解析器强制执行 `maxDocumentLength` — 20K 文档被 10K 限制拒绝 |
| `constraints/LargeDocReadTest.java` | `testInputStreamUnderLimitSucceeds` | `UTF8StreamJsonParser` | InputStream 解析器接受限制内的文档 |
| `constraints/LargeDocReadTest.java` | `testReaderExceedsLimit` | `ReaderBasedJsonParser` | Reader 解析器强制执行 `maxDocumentLength` — 20K 文档被 10K 限制拒绝 |
| `constraints/LargeDocReadTest.java` | `testReaderUnderLimitSucceeds` | `ReaderBasedJsonParser` | Reader 解析器接受限制内的文档 |
| `constraints/LargeDocReadTest.java` | `testAsyncExceedsLimit` | `NonBlockingJsonParser` | 异步解析器在 `feedInput()` 中强制执行 `maxDocumentLength` — 20K 文档被拒绝 |
| `constraints/LargeDocReadTest.java` | `testAsyncUnderLimitSucceeds` | `NonBlockingJsonParser` | 异步解析器接受限制内的文档 |
| `constraints/LargeDocReadTest.java` | `testDataInputWithDocLengthLimitFails` | `UTF8DataInputJsonParser` | 配置了 `maxDocumentLength` 时,DataInput 解析器快速失败 |
| `constraints/LargeDocReadTest.java` | `testDataInputWithoutDocLengthLimitWorks` | `UTF8DataInputJsonParser` | 未配置 `maxDocumentLength` 时,DataInput 解析器正常工作 |
| `constraints/LargeDocReadTest.java` | `testDefaultFactoryNoLimit` | `UTF8StreamJsonParser` | 默认工厂(无限制)接受大文档 |

---

## 完整测试套件结果```
Tests run: 957, Failures: 0, Errors: 0, Skipped: 0

所有957个测试在修复后的构建中均通过。新增安全测试的细分如下:

构建命令:```bash ./mvnw test

root@kitploit:~
---

## 验证结果

### 针对 jackson-core 2.13.5 的回归测试

CVE 测试方法被设计为在 2.13.5 代码库上**失败**,并在修复后的构建上**通过**。

**`NumberOverflowTest#testSonatype_2022_6438`** 针对 2.13.5:```
FAIL — Sonatype-2022-6438 VULNERABILITY PRESENT: parser returned VALUE_NUMBER_INT
       for a 1001-digit integer — number length limit is not enforced

ArrayParsingTest#testCVE_2025_52999 针对 2.13.5:``` FAIL — CVE-2025-52999 VULNERABILITY PRESENT: StackOverflowError after 20000 nesting levels — parser enforces no depth limit (2.13.5)

root@kitploit:~
**修复构建上的两项测试:通过。**

---

## 概念验证

### CVE-2025-52999 — 嵌套深度 DoS```java
// Build a 1001-level nested array document (just over the limit)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1001; i++) sb.append('[');
for (int i = 0; i < 1001; i++) sb.append(']');

JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(sb.toString());
try {
    while (parser.nextToken() != null) { }       // ← throws on 1001st '['
    System.err.println("VULNERABLE: no exception thrown");
} catch (StreamConstraintsException e) {
    System.out.println("REMEDIATED: " + e.getMessage());
    // Depth (1001) exceeds the maximum allowed nesting depth (1000)
} finally {
    parser.close();
}

Sonatype-2022-6438 — 数字令牌长度拒绝服务攻击

所有四种令牌形式在尝试进行 BigDecimal / BigInteger 转换之前,都会触发 validateFPLength / validateIntegerLength。```java JsonFactory factory = new JsonFactory();

// ── 1. Long integer ────────────────────────────────────────────────────────── String longInt = "9".repeat(1001); // 1001-digit integer // Negative form works identically: "-" + "9".repeat(1001)

// ── 2. Long fractional part (floating-point) ───────────────────────────────── // intLen=1, fractLen=1001, total=1002 String longFloat = "0." + "9".repeat(1001);

// ── 3. Long exponent / scientific notation ─────────────────────────────────── // intLen=1, fractLen=0, expLen=1001, total=1002 — only 1,004 bytes on the wire String longExp = "1e" + "9".repeat(1001);

// ── 4. Combined fractional + exponent ──────────────────────────────────────── // intLen=1, fractLen=500, expLen=500, total=1001 — neither part alone is over the limit String combined = "0." + "9".repeat(500) + "e" + "9".repeat(500);

for (String payload : new String[]{ longInt, longFloat, longExp, combined }) { JsonParser parser = factory.createParser("[" + payload + "]"); try { parser.nextToken(); // START_ARRAY parser.nextToken(); // ← throws on the number token System.err.println("VULNERABLE: " + payload.substring(0, 20) + "…"); } catch (StreamConstraintsException e) { System.out.println("REMEDIATED: " + e.getMessage()); // Number length (N) exceeds the maximum length (1000) } finally { parser.close(); } }

root@kitploit:~
---

## 迁移指南

### 选项1:升级到 jackson-core 2.15.4+(推荐)```xml
<!-- Maven -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.15.4</version>
</dependency>

<!-- Or with Jackson BOM -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson</groupId>
            <artifactId>jackson-bom</artifactId>
            <version>2.15.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

从2.15版本开始,如果你的应用确实需要更深的嵌套或更长的数字,你还可以在运行时调整限制:```java JsonFactory factory = JsonFactory.builder() .streamReadConstraints(StreamReadConstraints.builder() .maxNestingDepth(2000) .maxNumberLength(10000) .maxDocumentLength(50_000_000L) .build()) .build();

root@kitploit:~
### 选项2:应用此安全修复```bash
git clone https://github.com/sassoftware/jackson-core.git
cd jackson-core
git checkout 2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9
./mvnw install -DskipTests

然后更新项目的依赖,以使用本地安装的 2.13.5-SNAPSHOT 构件,或将其部署到你的内部工件仓库。


关键变更文件摘要

总计:16个文件变更,1,606次插入(根据 git diff jackson-core-2.13.5 --stat 报告)。


参考文献

CVE-2025-52999

  • NVD条目:https://nvd.nist.gov/vuln/detail/CVE-2025-52999
  • GitHub安全公告:https://github.com/FasterXML/jackson-core/security/advisories/GHSA-h46c-h94j-95f3
  • CWE-121:基于栈的缓冲区溢出(根据NVD/GitHub CNA)

Sonatype-2022-6438

  • Sonatype公告:https://guide.sonatype.com/vulnerability/sonatype-2022-6438
  • CWE-770:无限制或节流的资源分配

SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9

  • Snyk公告:https://security.snyk.io/vuln/SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551
  • GitHub安全公告:https://github.com/FasterXML/jackson-core/security/advisories/GHSA-2m67-wjpj-xhg9
  • GitHub Issue:https://github.com/FasterXML/jackson-core/issues/1570
  • CWE-770:无限制或节流的资源分配
  • 修复提交:74c9ee25 (3.x)、7ce3622f (2.18.x)

Jackson Core

  • 发布说明:https://github.com/FasterXML/jackson-core/blob/2.15/release-notes/VERSION-2.x
  • StreamReadConstraints API(2.15 javadoc):https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-core/2.15.4/com/fasterxml/jackson/core/StreamReadConstraints.html

安全注意事项

谁面临风险

任何满足以下条件的应用程序:

  1. 从不受信任/外部源解析 JSON(HTTP 请求体、消息队列负载、文件上传、第三方 API 响应),并且
  2. 使用 jackson-core 2.x 版本早于 2.15.0(直接或通过 jackson-databind 间接使用)

则容易受到这两种攻击。

纵深防御

即使在修复之后,也请考虑:

  • 在 HTTP/传输层设置输入大小限制(例如 Servlet 容器中的 maxRequestSize),以在解析器被调用之前拒绝过大的请求体。
  • 请求超时,以限制每个请求的总处理时间。
  • 自定义 StreamReadConstraints,如果你的应用确实需要更大或更深的文档——将限制调整到你的用例所需的最小值。

兼容性

维度要求
构建 JDKJava 8 (JDK 1.8) 或更高版本 — 此分支需要 Java 8+ 用于构建和测试
最低运行时 JREJava 8 或更高版本
Maven3.6.3 或更高版本(附带的包装器 ./mvnw 自动满足此要求)

注意: 原始 jackson-core 2.13.5 版本目标为 Java 6(-source 1.6 -target 1.6)。 从本安全分支开始,构建和运行均需要 Java 8 或更高版本。 未更改任何 Jackson 2.13 公共 API 表面;仅因 Maven 和 JDK 要求,JDK 6/7 运行时失去兼容性。


开发环境

Build and Test```bash

Full build and test

./mvnw test

Install to local Maven repository

./mvnw install -DskipTests

root@kitploit:~
---

## 许可证

根据 [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) 授权。```
Copyright 2024–2025 The Jackson Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

联系方式

安全漏洞研究与修复作者 : Jinwoo Hwang (https://JinwooHwang.com)

下载工具
ID类型严重性CVSS上游修复
CVE-2025-52999拒绝服务 — 无限制的嵌套深度高7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)jackson-core 2.15.0
Sonatype-2022-6438 / SNYK-JAVA-COMFASTERXMLJACKSONCORE-7569538拒绝服务 — 无限制的数值令牌长度高7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)jackson-core 2.15.0
SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924无限制或节流的资源分配高8.7 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)jackson-core 2.18.6, 2.21.1 或更高版本。
SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9无限制或节流的资源分配 — 文档长度约束绕过高8.7 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)jackson-core 2.18.7, 2.21.2 或更高版本。
版本CVE-2025-52999Sonatype-2022-6438 / SNYK-JAVA-COMFASTERXMLJACKSONCORE-7569538SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551
2.13.5受影响受影响受影响受影响
2.13.5-CVE-2025-52999-sonatype-2022-6438已修复已修复已修复受影响
2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9已修复已修复已修复已修复
2.14.x受影响受影响受影响受影响
2.15.x已修复已修复受影响受影响
2.16.x已修复已修复受影响受影响
2.17.x已修复已修复受影响受影响
2.18.6+已修复已修复已修复受影响
2.18.7+已修复已修复已修复已修复
2.21.1+已修复已修复已修复受影响
2.21.2+已修复已修复已修复已修复
字段值
CVE IDCVE-2025-52999
发布日期2025-06-25
最后修改日期2025-06-26
来源(CNA)GitHub, Inc.
CVSS v4.0 分数8.7 高 — CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
CWECWE-121 — 基于栈的缓冲区溢出
GitHub 安全公告GHSA-h46c-h94j-95f3
上游修复 PRjackson-core#943
测试文件新增/扩展方法
read/ArrayParsingTest.javatestCVE_2025_52999, testCustomNestingDepthConstraint, testObjectNestingDepthLimit, testDataInputParserDepthLimit, testNonBlockingParserDepthLimit
read/NumberOverflowTest.javatestSonatype_2022_6438 (扩展以包含指数情况), testNonBlockingParserNumericLengthLimit, testCustomMaxNumberLengthConstraint, testNonBlockingParserExponentLengthLimit
constraints/LargeDocReadTest.javatestInputStreamExceedsLimit, testInputStreamUnderLimitSucceeds, testReaderExceedsLimit, testReaderUnderLimitSucceeds, testAsyncExceedsLimit, testAsyncUnderLimitSucceeds, testDataInputWithDocLengthLimitFails, testDataInputWithoutDocLengthLimitWorks, testDefaultFactoryNoLimit
文件变更类型变更行数描述
src/main/java/.../StreamReadConstraints.java新增+356约束配置 + 5个验证方法
src/main/java/.../exc/StreamConstraintsException.java新增+52约束违反的异常类型
src/main/java/.../base/ParserBase.java修改+44在重置和上下文助手方法中的深度/长度钩子
src/main/java/.../json/JsonReadContext.java修改+6throws IOException 传播
src/main/java/.../json/ReaderBasedJsonParser.java修改+30使用深度检查的 _createChild* 助手方法
src/main/java/.../json/UTF8StreamJsonParser.java修改+26使用深度检查的 _createChild* 助手方法
src/main/java/.../json/UTF8DataInputJsonParser.java修改+26使用深度检查的 _createChild* 助手方法
src/main/java/.../json/async/NonBlockingJsonParserBase.java修改+4使用深度检查的 _createChild* 助手方法
src/main/java/.../json/async/NonBlockingJsonParser.java修改+9新增 — 在6个数字完成位置添加 validateIntegerLength / validateFPLength;在 feedInput() 中添加 validateDocumentLength
src/main/java/.../JsonStreamContext.java修改+20添加 getNestingDepth()
src/main/java/.../TSFBuilder.java修改+15添加 _streamReadConstraints 字段和 streamReadConstraints() 设置器
src/main/java/.../JsonFactory.java修改+12将构建器约束接入构造函数;DataInput 对 maxDocumentLength 进行快速失败
src/test/java/.../read/NumberOverflowTest.java修改+241testSonatype_2022_6438(包含指数情况)、testNonBlockingParserNumericLengthLimit、testNonBlockingParserExponentLengthLimit、testCustomMaxNumberLengthConstraint
src/test/java/.../read/NumberParsingTest.java修改+39更新3个 verifyException 调用点
src/test/java/.../read/ArrayParsingTest.java修改+143testCVE_2025_52999、testCustomNestingDepthConstraint
src/test/java/.../constraints/LargeDocReadTest.java新增+2009个测试,涵盖所有解析路径上的 maxDocumentLength 强制执行
组件版本
基础标签jackson-core-2.13.5
分支2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9
构建工具Maven(包装器:./mvnw)
测试框架JUnit 3 / TestCase 风格
测试数量957