Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
jackson — 이 저장소는 jackson‑core 2.13.5와의 완전한 호환성을 유지하면서 CVE-2025-52999, GHSA-2m67-wjpj-xhg9 및 sonatype-2022-6438에서 보고된 서비스 거부(denial-of-service) 및 제한이나 스로틀링 없는 리소스 할당 보안 취약점에 대한 포괄적인 보안 수정을 제공합니다. | Kitploit
도구/GitHubGitHub/sassoftware/jackson
General Purpose UtilitiesStatic AnalysisVulnerability AnalysisCode AnalysisSupply Chain Security
GitHubsassoftware/jackson

jackson

이 저장소는 jackson‑core 2.13.5와의 완전한 호환성을 유지하면서 CVE-2025-52999, GHSA-2m67-wjpj-xhg9 및 sonatype-2022-6438에서 보고된 서비스 거부(denial-of-service) 및 제한이나 스로틀링 없는 리소스 할당 보안 취약점에 대한 포괄적인 보안 수정을 제공합니다.

저장소 보기
14개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

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) 및 제한 없이 또는 스로틀링 없이 리소스를 할당하는 취약점(Allocation of Resources Without Limits or Throttling)에 대한 포괄적인 보안 수정을 포함합니다. jackson-core 2.15.0에서 도입된 API와 정렬되면서도 더 넓은 파서 범위와 추가 공격 벡터 보호 기능으로 확장된 StreamReadConstraints 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이 입력 문서에서 탐색할 수 있는 깊이에 대한 구성 가능한 제한이 포함되어 있으며, 기본 허용 깊이는 1,000입니다. jackson-core는 한도에 도달하면 StreamConstraintsException을 발생시킵니다. jackson-databind도 JSON 입력을 구문 분석하기 위해 jackson-core를 사용하므로 이 변경의 혜택을 받습니다. 해결 방법으로, 사용자는 신뢰할 수 없는 소스의 입력 파일 구문 분석을 피해야 합니다.

해결 방법: 수정 버전이 배포될 때까지 신뢰할 수 없는 소스의 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:~
All four `JsonParser` implementations share this flaw. The attack is equally exploitable through
any of them — whether input arrives via `InputStream`, `Reader`, `DataInput`, or the async
non-blocking feeder API.

**공격 벡터:**

| # | 전략 | 예시 페이로드 | 깊이 증가 | 영향받는 파서 |
|---|----------|----------------|-----------------|------------------|
| 1 | 배열 중첩 | `[[[…]]]` — 1,001개의 연속된 `[` 토큰 | `[`마다 +1 | 4개 모두 |
| 2 | 객체 중첩 | `{"k":{"k":{…}}}` — 1,001개의 연속된 `{` 토큰 | `{`마다 +1 | 4개 모두 |
| 3 | 교차 중첩 | `[{"k":[{"k":…}]}]` — 1,001개의 혼합 `[`/`{` 토큰 | `[` 또는 `{`마다 +1 | 4개 모두 |

주요 관찰 사항:

- **배열 중첩 — 최소 오버헤드:** `[` 및 `]` 토큰만 필요합니다. 키, 값 또는 공백이 필요 없습니다. 1,001개의 대괄호 쌍으로 구성된 2,002바이트 페이로드만으로도 기본 제한 1,000을 초과하기에 충분합니다.
- **객체 중첩 — 증폭된 힙 압력:** 각 `{`는 깊이 체인 노드 위에 `JsonReadContext` 키 슬롯을 추가로 할당하여, 극단적인 깊이에서 메모리 소비를 가중시킵니다.
- **교차 중첩 — 웹 애플리케이션 방화벽(WAF) 우회:** 반복되는 `[[[` 또는 `{{{` 시퀀스를 탐지하는 패턴 매칭 방어는 교차 토큰 중첩을 인식하지 못합니다. 파서의 깊이 카운터는 토큰 유형과 관계없이 동일하게 증가합니다.
- **비차단 피더 — 동일한 페이로드, 다른 전달 표면:** 세 가지 중첩 전략 모두 `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

Path 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`에
자체적인 숫자 누적 루프가 있으며, `ParserBase.resetInt()` 또는 `resetFloat()`를 거치지 않고
`_intLength` / `_fractLength` / `_expLength`를 직접 설정합니다. 이는 업스트림 PR #827 수정(`ParserBase`에만
검증 추가)이 **`NonBlockingJsonParser`를 완전히 무방비 상태로 남겼음**을 의미합니다.
이 문제는 확장된 공격 표면 분석 중에 발견되었으며 이 브랜치에서 수정되었습니다.

**공격 벡터:**

| # | 토큰 형태 | 예시 페이로드 | `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` 인스턴스화를 강제하여 무제한 중간 힙 할당을 요구합니다.
- **복합 부동소수점 — 분할 한계 회피:** `fractLen = 500` 및 `expLen = 500`일 때 각 구성 요소는 개별적으로 1,000자리 임계값에 도달하지 않습니다. 통합 검사 `validateFPLength(intLen + fractLen + expLen)`이 이 공백을 메우는 유일한 방어책입니다.
- **비차단 파서 — 독립적 우회:** 위의 네 가지 토큰 형태 모두 `ByteArrayFeeder`를 통한 `NonBlockingJsonParser`를 통해 독립적으로 악용될 수 있습니다. 동기식 파서와 달리 `NonBlockingJsonParser`는 `_intLength` / `_fractLength` / `_expLength`를 직접 기록하는 비공개 루프(`_startPositiveNumber`, `_finishNumberIntegralPart`, `_startFloat`, `_finishFloatFraction`, `_finishFloatExponent`)에서 숫자를 누적하므로 `ParserBase.resetInt()` 및 `resetFloat()`를 완전히 우회합니다. 따라서 `ParserBase`만 수정한 업스트림 PR #827은 이 파서를 완전히 무방비 상태로 남겼으며, 이번 수정에서 6개의 독립적인 호출 지점 패치가 필요했습니다.

네 가지 토큰 형태와 비차단 우회는 토큰화 시점에 거부됩니다. `BigDecimal` 또는 `BigInteger`
가 생성되기 전에, 동기식 파서에서는 `ParserBase`의 `validateIntegerLength`와 `validateFPLength`에 의해,
비동기 파서에서는 `NonBlockingJsonParser`의 6개 전용 호출 지점에서 거부됩니다. 2.13.5에서는
네 가지 토큰 형태가 모두 조용히 수락됩니다. 이번 수정을 적용하면 모든 파서가
`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 페이로드 ≈ 200KB)는 길이 제약 조건이 발동하기 전에
> `ArrayIndexOutOfBoundsException`을 트리거합니다. 따라서 `UTF8DataInputJsonParser`에 대한 숫자 길이
> 보호는 버그가 여전히 재현되는 더 짧은 페이로드(≤ 1,001자리)로 검증됩니다.

---

### 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 문서(예: 수 기가바이트에 달하는 깊게 중첩되거나 매우 반복적인 구조)를
전송합니다. 적용이 없으면 파서는 구성된 제한과 관계없이 전체 문서를 처리하여 무제한의 메모리와
CPU를 소비합니다.

---

## 보안 영향

네 가지 취약점 모두 인증 없이 원격으로 악용 가능합니다:

- 공격자가 제어하는 JSON을 `JsonParser`를 통해(직접 또는 `jackson-core`를 래핑하는 Jackson Databind를 통해) 구문 분석하는 모든 서비스가 위험합니다.
- 공격은 사소하게 구성 가능합니다 — 수백 바이트의 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을 2.15.x와 호환되는 API로 도입하고, 네 가지 JsonParser 구현 모두에 제약 조건을 연결합니다 — 업스트림 수정에서 다루지 않았던 non-blocking 파서를 포함하여 — 그리고 다음 기본 제한을 적용합니다:

제약 조건기본 제한
최대 중첩 깊이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:~
검증 메서드 (각 새 토큰에 대해 파서가 호출함):```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 스케일: "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()`를 우회하는 6개의 숫자 완성 지점이 개별적으로 수정되었습니다:

| 메서드 | 추가된 검증 |
|--------|------------------|
| `_startPositiveNumber()` — 빠른 경로 반환 | `validateIntegerLength(_intLength)` |
| `_startNegativeNumber()` — 빠른 경로 반환 | `validateIntegerLength(_intLength)` |
| `_finishNumberIntegralPart()` — 최종 반환 | `validateIntegerLength(_intLength)` |
| `_finishToken()` 케이스 `MINOR_NUMBER_INTEGER_DIGITS` | `validateIntegerLength(_intLength)` |
| `_startFloat()` / `_finishFloatFraction()` / `_finishFloatExponent()` 최종 반환 | `validateFPLength(_intLength + _fractLength + _expLength)` |
| `_finishToken()` 케이스 `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` = 위 3개 + `UTF8DataInputJsonParser`
> - `non-blocking` = `ByteArrayFeeder`를 통한 `NonBlockingJsonParser`
> - `stream` = `UTF8StreamJsonParser` (기본 `JsonFactory.createParser`)

### SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 — 문서 길이 테스트

| 테스트 파일 | 테스트 메서드 | 파서 모드 | 설명 |
|-----------|-------------|-------------|--------|
| `constraints/LargeDocReadTest.java` | `testInputStreamExceedsLimit` | `UTF8StreamJsonParser` | InputStream 파서가 `maxDocumentLength`를 적용 — 10K 한도에서 20K 문서가 거부됨 |
| `constraints/LargeDocReadTest.java` | `testInputStreamUnderLimitSucceeds` | `UTF8StreamJsonParser` | InputStream 파서가 한도 내 문서를 허용 |
| `constraints/LargeDocReadTest.java` | `testReaderExceedsLimit` | `ReaderBasedJsonParser` | Reader 파서가 `maxDocumentLength`를 적용 — 10K 한도에서 20K 문서가 거부됨 |
| `constraints/LargeDocReadTest.java` | `testReaderUnderLimitSucceeds` | `ReaderBasedJsonParser` | Reader 파서가 한도 내 문서를 허용 |
| `constraints/LargeDocReadTest.java` | `testAsyncExceedsLimit` | `NonBlockingJsonParser` | Async 파서가 `maxDocumentLength`를 적용 — 20K 문서가 `feedInput()`에서 거부됨 |
| `constraints/LargeDocReadTest.java` | `testAsyncUnderLimitSucceeds` | `NonBlockingJsonParser` | Async 파서가 한도 내 문서를 허용 |
| `constraints/LargeDocReadTest.java` | `testDataInputWithDocLengthLimitFails` | `UTF8DataInputJsonParser` | DataInput 파서는 `maxDocumentLength`가 구성되면 빠르게 실패 |
| `constraints/LargeDocReadTest.java` | `testDataInputWithoutDocLengthLimitWorks` | `UTF8DataInputJsonParser` | DataInput 파서는 `maxDocumentLength` 구성 없이 정상 작동 |
| `constraints/LargeDocReadTest.java` | `testDefaultFactoryNoLimit` | `UTF8StreamJsonParser` | 기본 팩토리(제한 없음)는 대용량 문서를 허용 |

---

## 전체 테스트 스위트 결과```
Tests run: 957, Failures: 0, Errors: 0, Skipped: 0

All 957 tests pass on the remediated build. Breakdown of new security tests added:

빌드 명령:```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:~
**수정된 빌드에 대한 두 테스트 모두: PASS.**

---

## 개념 증명

### 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 — 숫자 토큰 길이 DoS

네 가지 토큰 형태 모두 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 이슈: 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. 신뢰할 수 없거나 외부 소스(HTTP 요청 본문, 메시지 큐 페이로드, 파일 업로드, 타사 API 응답)에서 JSON을 파싱하고, 그리고
  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 런타임만 호환성이 사라집니다.


개발 환경

빌드 및 테스트```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 (extended to include exponent cases), 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수정됨+20getNestingDepth() 추가
src/main/java/.../TSFBuilder.java수정됨+15_streamReadConstraints 필드 및 streamReadConstraints() 세터 추가
src/main/java/.../JsonFactory.java수정됨+12생성자에 빌더 제약 조건 연결; maxDocumentLength에 대한 DataInput 빠른 실패
src/test/java/.../read/NumberOverflowTest.java수정됨+241testSonatype_2022_6438 (지수 경우 포함), testNonBlockingParserNumericLengthLimit, testNonBlockingParserExponentLengthLimit, testCustomMaxNumberLengthConstraint
src/test/java/.../read/NumberParsingTest.java수정됨+39verifyException 호출 지점 3곳 업데이트
src/test/java/.../read/ArrayParsingTest.java수정됨+143testCVE_2025_52999, testCustomNestingDepthConstraint
src/test/java/.../constraints/LargeDocReadTest.java새로 추가됨+200모든 파서 경로에서 maxDocumentLength 적용을 검증하는 테스트 9개
구성 요소버전
기준 태그jackson-core-2.13.5
브랜치2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9
빌드 도구Maven (래퍼: ./mvnw)
테스트 프레임워크JUnit 3 / TestCase 스타일
테스트 수957