Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
jackson — This repository provides a comprehensive security remediation of denial-of-service and allocation of resources without limits or throttling security vulnerabilities reported in CVE-2025-52999, GHSA-2m67-wjpj-xhg9 and sonatype-2022-6438 while maintaining full compatibility with jackson‑core 2.13.5. | Kitploit
Инструменты/GitHubGitHub/sassoftware/jackson
General Purpose UtilitiesStatic AnalysisVulnerability AnalysisCode AnalysisSupply Chain Security
GitHubsassoftware/jackson

jackson

Репозиторий
14 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →

Описание

This repository provides a comprehensive security remediation of denial-of-service and allocation of resources without limits or throttling security vulnerabilities reported in CVE-2025-52999, GHSA-2m67-wjpj-xhg9 and sonatype-2022-6438 while maintaining full compatibility with jackson‑core 2.13.5.

Поделиться

Анализ и устранение уязвимостей безопасности в 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) содержит комплексное устранение уязвимостей типа «отказ в обслуживании» (DoS) и «выделение ресурсов без ограничений или регулирования», затрагивающих jackson-core 2.13.5. В ней представлен API StreamReadConstraints — совместимый с API, введённым в jackson-core 2.15.0, но расширенный более широким охватом парсеров и дополнительными защитами от векторов атак — устраняющий атаку исчерпания глубины вложенности (CVE-2025-52999), проблему выделения ресурсов без ограничений или регулирования (SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924), обход ограничения длины документа (SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9) и атаку исчерпания длины числового токена (Sonatype-2022-6438), оставаясь при этом совместимым с публичной поверхностью API jackson-core версии 2.13.5.

История веток

ВеткаУстранённые уязвимости
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 Data Processor. В версиях до 2.15.0, если пользователь разбирает входной файл, содержащий глубоко вложенные данные, Jackson может выбросить StackOverflowError при особенно большой глубине. jackson-core 2.15.0 содержит настраиваемый лимит того, насколько глубоко Jackson будет проходить по входному документу; по умолчанию допустимая глубина составляет 1 000. jackson-core выбрасывает StreamConstraintsException при достижении лимита. jackson-databind также выигрывает от этого изменения, поскольку использует jackson-core для разбора JSON-входных данных. В качестве меры предосторожности пользователям следует избегать разбора входных файлов из ненадёжных источников.

Мера предосторожности: избегайте разбора JSON-входных данных из ненадёжных источников до развёртывания исправленной версии.


Основная причина: До версии 2.15.0 JsonParser не накладывал ограничений на глубину вложенности JSON-документа. Каждый токен массива [ или объекта { вызывал JsonReadContext.createChildArrayContext() / createChildObjectContext(), выделяя новый узел контекста в куче и увеличивая цепочку ссылок. Злоумышленник может создать документ с десятками тысяч уровней вложенности, что приведёт к исчерпанию стека потока или памяти кучи Java Virtual Machine.

Уязвимый путь кода:

Та же самая отсутствующая проверка достигается через каждую из четырёх реализаций парсера:``` 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` или асинхронный неблокирующий API подачи.

**Векторы атаки:**

| # | Стратегия | Пример полезной нагрузки | Приращение глубины | Затронутые парсеры |
|---|-----------|--------------------------|--------------------|---------------------|
| 1 | Вложенность массивов | `[[[…]]]` — 1,001 последовательных токенов `[` | +1 за каждый `[` | Все четыре |
| 2 | Вложенность объектов | `{"k":{"k":{…}}}` — 1,001 последовательных токенов `{` | +1 за каждый `{` | Все четыре |
| 3 | Чередующаяся вложенность | `[{"k":[{"k":…}]}]` — 1,001 смешанных токенов `[`/`{` | +1 за каждый `[` или `{` | Все четыре |

Ключевые наблюдения:

- **Вложенность массивов — минимальные накладные расходы:** требуются только токены `[` и `]`; не требуется ключей, значений или пробелов. Полезная нагрузка размером 2 002 байта из 1 001 пары скобок достаточна для превышения лимита по умолчанию в 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 — Неограниченная длина числового токена

**Детали безопасности**

| Поле | Значение |
|------|----------|
| ID Sonatype | [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` из неограниченного содержимого буфера.

---

**Основная причина:** До версии 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` полностью незащищённым**.
Это было обнаружено в ходе расширенного анализа поверхности атаки и исправлено в этой ветке.

**Векторы атаки:**

| # | Форма токена | Пример полезной нагрузки | `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 байтах это самая маленькая эффективная полезная нагрузка; она принуждает к созданию `BigDecimal` с порядком ±10^1001, что требует неограниченного выделения промежуточной памяти, несмотря на малый размер токена.
- **Составное число с плавающей точкой — обход раздельного ограничения:** при `fractLen = 500` и `expLen = 500` ни один из компонентов по отдельности не достигает порога в 1 000 цифр. Единая проверка `validateFPLength(intLen + fractLen + expLen)` — единственная защита, закрывающая этот пробел.
- **Неблокирующий парсер — независимый обход:** все четыре формы токена, указанные выше, независимо эксплуатируемы через `NonBlockingJsonParser` с помощью `ByteArrayFeeder`. В отличие от синхронных парсеров, `NonBlockingJsonParser` накапливает цифры в частных циклах (`_startPositiveNumber`, `_finishNumberIntegralPart`, `_startFloat`, `_finishFloatFraction`, `_finishFloatExponent`), которые напрямую записывают `_intLength` / `_fractLength` / `_expLength`, полностью минуя `ParserBase.resetInt()` и `resetFloat()`. Вышестоящий PR #827, который модифицировал только `ParserBase`, поэтому оставил этот парсер полностью незащищённым, что потребовало шести независимых исправлений в точках вызова в рамках данной коррекции.

Все четыре формы токена и обход неблокирующего парсера отклоняются на этапе токенизации — до того, как будет создан какой-либо `BigDecimal` или `BigInteger` —
с помощью `validateIntegerLength` и `validateFPLength` в `ParserBase` (синхронные
парсеры) и в шести специализированных точках вызова в `NonBlockingJsonParser` (асинхронный парсер). В версии 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)).
> Документы, превышающие этот размер (например, полезные нагрузки PoC из 199 999 цифр ≈ 200 КБ), вызывают
> `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 Advisory | [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` вообще не существовало, то есть не было способа
ограничить размер документа. Данная коррекция вводит поле `maxDocumentLength` в
`StreamReadConstraints` и применяет его во всех путях парсера.

**Уязвимые пути парсеров:**

| Парсер | Путь | Точка контроля |
|--------|------|----------------|
| `UTF8StreamJsonParser` | `InputStream` → `_loadMore()` | Проверяет `_currInputProcessed + count` после каждой дозагрузки буфера и в конце файла |
| `ReaderBasedJsonParser` | `Reader` → `_loadMore()` | Тот же шаблон, что и в `UTF8StreamJsonParser` |
| `NonBlockingJsonParser` | `feedInput()` | Проверяет `_currInputProcessed + _origBufferLen` после каждого блока входных данных |
| `UTF8DataInputJsonParser` | `DataInput` | Fail-fast: выбрасывает `StreamConstraintsException`, если `maxDocumentLength` настроен |

**Сценарий атаки:** Злоумышленник отправляет валидный, но слишком большой JSON-документ (например, глубоко вложенную
или сильно повторяющуюся структуру размером в гигабайты) сервису, который настроил
`maxDocumentLength` для предотвращения истощения ресурсов. Без применения ограничения парсер обрабатывает
весь документ независимо от настроенного лимита, потребляя неограниченную память и процессорное время.

---

## Влияние на безопасность

Все четыре уязвимости удалённо эксплуатируемы без какой-либо аутентификации:

- Любой сервис, который обрабатывает подконтрольный злоумышленнику JSON через `JsonParser` (напрямую или через
  Jackson Databind, который оборачивает `jackson-core`), находится под угрозой.
- Атака тривиально конструируется — нескольких сотен байт JSON достаточно, чтобы вызвать
  неограниченное потребление ресурсов.
- Конфиденциальность и целостность не затронуты; отказ в обслуживании (DoS) — единственный класс воздействия.

---

## Детали исправления

### Официальное обновление (рекомендуется)

Обновитесь до **jackson-core 2.15.4** или любой более поздней стабильной версии. Все выпуски 2.15.x и 2.16+
включают API `StreamReadConstraints` с безопасными значениями по умолчанию.```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

Детали реализации исправления

Новые классы

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: "Depth (%d) exceeds the maximum allowed nesting depth (%d)"
  • Number length: "Number length (%d) exceeds the maximum length (%d)"
  • String length: "String length (%d) exceeds the maximum length (%d)"
  • BigDecimal scale: "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()` — быстрый возврат | `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` | потоковый | Рекурсивный обход, симулирующий реальное использование приложения; подтверждает `StreamConstraintsException` на глубине 1001 (исправлено) и `StackOverflowError` на глубине 20 000 (2.13.5) |
| `read/ArrayParsingTest.java` | `testCustomNestingDepthConstraint` | прямой API | `StreamReadConstraints.builder().maxNestingDepth(5)` — геттер, проход на пределе, превышение вызывает исключение |
| `read/ArrayParsingTest.java` | `testObjectNestingDepthLimit` | потоковый | Объекты точно на пределе 1000 (проход), объекты на уровне 1001 вызывают исключение |
| `read/ArrayParsingTest.java` | `testDataInputParserDepthLimit` | `UTF8DataInputJsonParser` | `UTF8DataInputJsonParser` обеспечивает ограничение глубины на уровне 1001 |
| `read/ArrayParsingTest.java` | `testNonBlockingParserDepthLimit` | неблокирующий | `NonBlockingJsonParser` обеспечивает ограничение глубины на уровне 1001 |

### Sonatype-2022-6438 — Тесты длины чисел

| Тестовый файл | Тестовый метод | Режимы парсера | Покрывает |
|-----------|-------------|-------------|--------|
| `read/NumberOverflowTest.java` | `testSonatype_2022_6438` | `ALL_MODES` | Целое число на пределе (проход), целое число выше предела (отказ), число с плавающей точкой на пределе (проход), число с плавающей точкой выше предела (отказ), экспонента научной нотации на пределе (проход), экспонента выше предела (отказ) — все четыре парсера |
| `read/NumberOverflowTest.java` | `testNonBlockingParserNumericLengthLimit` | неблокирующий | `NonBlockingJsonParser` обеспечивает ограничение длины чисел |
| `read/NumberOverflowTest.java` | `testNonBlockingParserExponentLengthLimit` | неблокирующий | `NonBlockingJsonParser` обеспечивает ограничение длины экспоненты научной нотации через `validateFPLength` |
| `read/NumberOverflowTest.java` | `testCustomMaxNumberLengthConstraint` | прямой API | `StreamReadConstraints.builder().maxNumberLength(5)` — геттер, проход на пределе, превышение вызывает исключение для обеих `validateIntegerLength()` и `validateFPLength()`, формат сообщения об ошибке |

> **Легенда режимов парсера:**
> - `ALL_STREAMING_MODES` = `UTF8StreamJsonParser` (потоковый), `UTF8StreamJsonParser` (дросселированный), `ReaderBasedJsonParser`
> - `ALL_MODES` = три выше + `UTF8DataInputJsonParser`
> - `non-blocking` = `NonBlockingJsonParser` через `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` | Асинхронный парсер обеспечивает `maxDocumentLength` — документ 20K отклонён в `feedInput()` |
| `constraints/LargeDocReadTest.java` | `testAsyncUnderLimitSucceeds` | `NonBlockingJsonParser` | Асинхронный парсер принимает документ в пределах лимита |
| `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

Все 957 тестов проходят на исправленной сборке. Разбивка добавленных новых тестов безопасности:

Команда сборки:

mvn clean verify -Ptest -Pstrict -pl ...```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 — DoS длины числового токена

Все четыре формы токенов вызывают validateFPLength / validateIntegerLength перед любой попыткой преобразования BigDecimal / BigInteger.```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. Разбирает JSON из ненадёжного/внешнего источника (тела HTTP-запросов, полезные данные очередей сообщений, загрузки файлов, ответы сторонних API), И
  2. Использует jackson-core 2.x до версии 2.15.0 (напрямую или транзитивно через jackson-databind)

уязвимо для обеих атак.

Глубокоэшелонированная защита

Даже после исправления рассмотрите:

  • Ограничения размера ввода на уровне HTTP/транспорта (например, maxRequestSize в контейнерах сервлетов) чтобы отклонять чрезвычайно большие тела запросов до вызова синтаксического анализатора.
  • Тайм-ауты запросов для ограничения общего времени обработки каждого запроса.
  • Пользовательские StreamReadConstraints если ваше приложение законно требует больших или более глубоких документов — настройте ограничения до минимума, необходимого для вашего случая использования.

Совместимость

ПараметрТребование
JDK сборкиJava 8 (JDK 1.8) или новее — эта ветка требует Java 8+ для сборки и тестирования
Минимальная среда выполнения JREJava 8 или новее
Maven3.6.3 или новее (встроенный wrapper ./mvnw удовлетворяет этому автоматически)

Примечание: Оригинальный выпуск jackson-core 2.13.5 был нацелен на Java 6 (-source 1.6 -target 1.6). Начиная с этой ветки безопасности, Java 8 или новее требуется как для сборки, так и для выполнения. Никакая публичная API-поверхность Jackson 2.13 не изменена; только среды выполнения JDK 6/7 теряют совместимость из-за требований Maven и JDK.


Среда разработки

Сборка и тестирование```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.08.7 HIGH — 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 — Переполнение стека
Уведомление GitHubGHSA-h46c-h94j-95f3
PR с исправлением в восходящем проектеjackson-core#943
100,000
Тестовый файлНовые / расширенные методы
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Изменен+6Проброс throws 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НОВЫЙ — validateIntegerLength / validateFPLength в 6 местах завершения чисел; validateDocumentLength в feedInput()
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 во всех путях синтаксического анализатора
КомпонентВерсия
Base tagjackson-core-2.13.5
Branch2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9
Инструмент сборкиMaven (wrapper: ./mvnw)
Фреймворк тестированияJUnit 3 / TestCase-style
Количество тестов957