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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2025-29927 — This is a CVE-2025-29927 Scanner. | Kitploit
Инструменты/GitHubGitHub/houmanpashaei/cve-2025-29927
ReconnaissanceVulnerability ScannersWeb Application ExploitationWeb SecurityPenetration TestingCrawler
GitHubhoumanpashaei/cve-2025-29927

CVE-2025-29927

This is a CVE-2025-29927 Scanner.

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

Популярное

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

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

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

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

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

Advanced CVE-2025-29927 Vulnerability Scanner

Это профессиональный сканер, предназначенный для обнаружения уязвимости обхода промежуточного ПО CVE-2025-29927 в приложениях Next.js.

🧠 Что он делает

  • Использует настоящий headless-браузер (Playwright) для глубокого сканирования целевого веб-сайта (включая контент, обработанный JavaScript)
  • Проверяет внутренние пути с помощью специально созданных заголовков X-Middleware-Subrequest для обхода промежуточного ПО Next.js
  • Сравнивает HTTP-статус и длину ответа для выявления обходов
  • Полностью многопоточен для высокой производительности

🚀 Быстрый старт

Установка (локально)```bash

pip install -r requirements.txt playwright install

root@kitploit:~
### Запустите сканер```bash
python main.py --domain https://example.com --threads 10 --timeout 10 --save

Все опции CLI```bash

python main.py --help

root@kitploit:~
| Опция           | Описание                                        |
|-----------------|-------------------------------------------------|
| `--domain`      | Базовый URL целевого сайта (обязательно)        |
| `--user-agent`  | Пользовательский user-agent (по умолчанию: строка Chrome) |
| `--timeout`     | Тайм-аут запроса (по умолчанию: 10 секунд)      |
| `--proxy`       | Адрес прокси (опционально)                      |
| `--save`        | Сохранить результаты в `results.txt`            |
| `--threads`     | Количество потоков (по умолчанию: 10)           |
| `--wordlist`    | Словник включает общие пути                     |

---

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

### Сборка Docker-образа```bash
docker build -t cve-scanner .

Запустить сканер```bash

docker run -it --rm cve-scanner --domain https://example.com --save

root@kitploit:~
---

## ⚙️ GitHub Actions

Этот проект включает рабочий процесс GitHub Actions для проверки установки при пуше. Он:
- Устанавливает зависимости
- Устанавливает браузеры Playwright
- Запускает проверку `--help`

Смотрите `.github/workflows/python.yml`.

---

## 🧱 Структура```
.
├── main.py              # Entry point
├── config.py            # CLI parser
├── crawler.py           # Playwright crawler
├── scanner.py           # Multi-threaded vulnerability testing
├── requirements.txt
├── Dockerfile
└── .github/workflows

🧠 More Details

🧠 Детальная архитектура сканера уязвимости CVE-2025-29927

Обзор уязвимости CVE-2025-29927

CVE-2025-29927 — это критическая уязвимость безопасности Next.js, позволяющая злоумышленникам обходить аутентификацию и авторизацию на основе промежуточного ПО (middleware). Включив специальный внутренний заголовок (X-Middleware-Subrequest) в HTTP-запросы, злоумышленник может обмануть сервер Next.js, заставив его пропустить выполнение middleware, тем самым получив доступ к защищённым маршрутам​. На практике запрос, который обычно был бы заблокирован middleware аутентификации (например, возвращающий 401/403 или перенаправляющий на страницу входа), обрабатывается нормально, если присутствует этот заголовок, что эффективно обходит проверки безопасности. Эта уязвимость затрагивает версии Next.js с 11.1.4 по 15.2.2, и администраторам настоятельно рекомендуется установить исправление или внедрить меры защиты (например, удаление этого заголовка на прокси), чтобы защитить свои приложения.

Обход middleware Next.js путём включения специального заголовка X-Middleware-Subrequest, позволяющего прямой доступ к защищённому ресурсу (эксплойт CVE-2025-29927)

Обнаружение этой уязвимости в веб-приложении требует нахождения внутренних конечных точек и тестирования их с вредоносным заголовком, чтобы выяснить, возможен ли несанкционированный доступ. Ниже представлен план проектирования продвинутого Python-скрипта, который будет обходить целевой сайт (с полной поддержкой JavaScript) и сканировать на наличие CVE-2025-29927, удовлетворяя всем указанным требованиям.

🚀 Инструменты и библиотеки для динамического обхода и сканирования

Чтобы выполнить требование глубокого обхода, включая контент, отображаемый с помощью JavaScript, мы будем использовать Playwright (предпочтительнее Selenium из-за его скорости и современного API). Playwright — это мощная библиотека для автоматизации браузеров без головы, которая может работать с динамическими веб-приложениями и современными JS-фреймворками. По сравнению с Selenium, Playwright предлагает более современный API (построенный на Chrome DevTools Protocol) и поддерживает как синхронную, так и асинхронную работу, что может обеспечить лучшую производительность для нашего случая использования​ . Ключевые библиотеки и инструкции по их установке включают:

  • playwright — для автоматизации браузера без головы (для загрузки SPA или страниц, требующих JavaScript). (Установка: pip install playwright и запуск playwright install для получения бинарных файлов браузера).

  • requests или httpx — для отправки HTTP-запросов во время фазы сканирования. Мы можем использовать requests для простоты или httpx/aiohttp для асинхронной поддержки. (Установка: pip install requests или pip install httpx).

  • bs4 (BeautifulSoup) — для парсинга HTML и извлечения ссылок при необходимости. Playwright может напрямую запрашивать DOM, но использование BeautifulSoup с HTML-содержимым страницы — это простой способ найти теги привязки. (Установка: pip install beautifulsoup4).

  • concurrent.futures (встроенный) или asyncio — для реализации конкурентности. Для многопоточности будет использоваться Python concurrent.futures.ThreadPoolExecutor (дополнительная установка не требуется). При асинхронном подходе можно использовать Python asyncio с для параллельных запросов.

Обоснование: Playwright выбран из-за его способности извлекать динамический контент без лишних сложностей. «Используя Playwright, мы можем автоматизировать браузеры без головы... чтобы перемещаться по веб-страницам как человек, что делает его отличным для извлечения данных с динамических веб-сайтов, работающих на JavaScript»​. Это гарантирует, что наш краулер сможет видеть ссылки или элементы интерфейса, созданные скриптами (которые простой краулер на основе requests пропустил бы).

🚀 Обход с поддержкой JavaScript (динамическое обнаружение путей)

Модуль-краулер будет использовать Playwright в режиме без головы для глубокого обхода целевого сайта. Цель — обнаружить внутренние пути (конечные точки) для тестирования, включая те, которые становятся видны только после выполнения JavaScript. Ключевые моменты проектирования краулера:

Навигация в браузере без головы: Запустите экземпляр браузера (например, Chromium) в режиме без головы через Playwright. Используйте Browser Context с пользовательским User-Agent, если он указан пользователем (подробнее в следующем разделе). Например, мы можем создать контекст с помощью browser.new_context(user_agent=<user_agent_string>)​, чтобы эмулировать выбранный User-Agent. Если настроен прокси, примените его при запуске (Playwright позволяет устанавливать прокси-сервер при запуске браузера или контекста​).

Стратегия рекурсивного обхода: Начните с заданного базового URL (начального). Используйте page.goto(base_url, timeout=<T>) для загрузки страницы (таймаут настраивается). Дождитесь, пока сеть станет неактивной, или используйте небольшую задержку, чтобы динамический контент загрузился при необходимости. Затем извлеките ссылки. Мы можем извлечь ссылки одним из следующих способов:

  • Выполнение JavaScript в контексте страницы для сбора всех якорей, например: links = page.evaluate("Array.from(document.querySelectorAll('a[href]'), a => a.href)"), или
  • Получение HTML страницы (content = page.content()) и использование BeautifulSoup для парсинга и поиска всех <a href> атрибутов.

Фильтрация ссылок: Отфильтруйте ссылки, не входящие в целевой домен (чтобы оставаться на внутренних ресурсах). Также игнорируйте URL статических файлов, таких как изображения, CSS, JS и т.д. Например, пропускайте любой URL с расширениями файлов типа .css, .js, .jpg, .png, .gif, .svg, .woff и т.д. Практичный подход (вдохновлённый шаблоном ProjectDiscovery) — игнорировать любые пути, содержащие «точку» после начального слеша. Они извлекали конечные точки с помощью регулярного выражения href=['"](https://github.com/houmanpashaei/cve-2025-29927/blob/HEAD/%5C/%5B%5E.%5C%22%27%5D+)['"] – это захватывает внутренние пути, не содержащие точки (таким образом пропуская ресурсы)​. Мы реализуем аналогичную логику в коде, чтобы избежать постановки в очередь статических ресурсов или внешних ссылок.

Отслеживание и контроль глубины: Ведите набор посещённых URL, чтобы избежать бесконечных циклов или повторов. Используйте очередь (FIFO) для обхода графа ссылок сайта в ширину (BFS). Опционально позвольте пользователю указать ограничение глубины обхода или максимальное количество страниц для посещения, чтобы избежать бесконечной работы на больших сайтах.

Контент, отображаемый с помощью JavaScript: Поскольку мы используем настоящий браузер, даже ссылки, добавленные в DOM скриптами (например, приложение React, которое отображает меню после получения данных), будут видны нашему краулеру. Мы должны рассмотреть возможность кликов или взаимодействия при необходимости (например, если некоторые страницы загружаются только после действия пользователя). Однако, чтобы упростить и ускорить работу, начальный проект будет сосредоточен на сборе href из тегов на каждой загруженной странице. Мы можем улучшить его позже для обработки таких вещей, как бесконечная прокрутка или контент за кликами, если целевое приложение этого требует.

Эффективность: Playwright поддерживает параллельную работу нескольких страниц/вкладок с помощью своего асинхронного API. Мы могли бы создать несколько страниц с помощью asyncio.gather для одновременной загрузки нескольких ссылок. Для начальной реализации более простой подход — обходить последовательно (что проще реализовать) и полагаться на многопоточное сканирование для производительности. При необходимости можно использовать продвинутую оптимизацию, включающую асинхронный обход (с использованием async with async_playwright() и ожиданием нескольких вызовов page.goto). Но поскольку автоматизация браузера более ресурсоёмка, разумный подход — держать, возможно, одну или несколько страниц браузера одновременно, чтобы не перегружать систему.

🚀 Меню конфигурации пользователя и опции

Скрипт будет отображать удобное меню конфигурации при запуске, позволяя пользователю настроить параметры сканирования или принять значения по умолчанию. Это можно сделать через интерактивное консольное меню (с помощью вызовов input()) или через аргументы командной строки (с помощью argparse для более профессионального CLI-интерфейса). Опции включают:

  • Пользовательский User-Agent: Пользователь может указать свою строку User-Agent для краулера и сканера. Она будет применена к контексту браузера Playwright и к любым прямым HTTP-запросам. Использование нестандартного User-Agent может помочь избежать тривиального обнаружения ботов. (По умолчанию Playwright может использовать что-то идентифицируемое; мы можем легко переопределить это, как показано выше.) Например, пользователь может ввести строку, идентифицирующую Chrome на Windows, которую мы передадим в создание контекста Playwright​.

  • Таймаут запроса: Пользователь может установить таймаут (в секундах) для загрузки страниц и HTTP-запросов. Это предотвращает зависание сканера на слишком долгое время при обработке неотвечающих конечных точек. Мы применим эту настройку в для обхода и в запросах (например, ) для сканирования.

Скачать инструмент
httpx
  • (Опционально) argparse — для разбора аргументов командной строки, если мы хотим интерфейс командной строки вместо интерактивного меню. (встроенный модуль)

  • (Опционально) rich или colorama — для цветного или форматированного вывода в консоль для улучшения читаемости. (Установка: pip install rich или pip install colorama).

  • page.goto(timeout=...)
    requests.get(timeout=...)
  • Настройки прокси: Если пользователь хочет направлять трафик через прокси (для анонимности или доступа к внутренним узлам), он может ввести URL прокси (и учётные данные при необходимости). Скрипт настроит браузер Playwright на использование этого прокси при запуске (например, browser.launch(proxy={"server": "http://<proxy_host>:<port>", "username": "...", "password": "..."}), как показано в примерах). Аналогично для запросов мы установим параметр proxies (или переменные окружения).

  • Вывод в файл: Меню спросит, хочет ли пользователь сохранить результаты в файл (например, results.txt). Если да, скрипт будет записывать любые обнаруженные уязвимые конечные точки и детали в этот файл в дополнение к выводу на экран. Если нет, результаты будут просто выводиться в stdout. (Возможно, мы всё равно будем логировать все сканированные пути в подробный журнал при необходимости, но файл будет специально записывать положительные результаты или полный отчёт в соответствии с предпочтениями пользователя.)

  • Другие опции: Мы можем включить переключатели, такие как «Режим подробного вывода» для отладочного логирования или «Максимальная глубина/количество страниц обхода» при необходимости. Они могут помочь пользователю точнее настроить сканирование. Для начального объёма четырёх основных опций достаточно.

  • Система меню будет реализована в специальном модуле конфигурации/настройки. Это может быть просто функция, которая выводит приглашения и собирает ввод, с разумными значениями по умолчанию, если пользователь нажимает Enter (например, User-Agent по умолчанию — стандартный, таймаут по умолчанию — 10 секунд, прокси нет, вывода в файл нет). Это делает взаимодействие понятным и позволяет скрипту работать в неинтерактивном режиме (если позже мы добавим аргументы командной строки, мы сможем пропустить интерактивные подсказки, предоставив всю необходимую конфигурацию через аргументы).

    🚀 Конкурентность и улучшение производительности

    Производительность критична для сканера, особенно если обнаружено много конечных точек. Скрипт будет использовать конкурентность для ускорения, либо через многопоточность, либо через asyncio (или их комбинацию):

    • Многопоточное сканирование: Поскольку сканирование обнаруженных путей (отправка HTTP-запросов с заголовками) является задачей, связанной с вводом-выводом, мы можем безопасно использовать потоки Python для распараллеливания. Операции ввода-вывода освобождают глобальную блокировку интерпретатора, что позволяет нескольким потокам одновременно выполнять сетевые запросы​. Используя concurrent.futures.ThreadPoolExecutor, мы можем создать пул рабочих потоков, каждый из которых будет обрабатывать подмножество задач сканирования. Это может значительно ускорить процесс: например, запуск 5 потоков параллельно может сократить время сканирования примерно в 5 раз, как показано в других контекстах веб-скрапинга​. Мы позволим настраивать количество потоков или выберем разумное значение по умолчанию (например, 10 потоков), балансируя скорость и нагрузку на сервер. Каждый поток будет брать URL из общей очереди конечных точек для тестирования.

    • Асинхронная альтернатива: Кроме того, можно использовать асинхронный подход, особенно если Playwright используется в асинхронном режиме или httpx для HTTP-запросов. Мы могли бы await несколько запросов одновременно. Например, httpx.AsyncClient может отправлять много запросов одновременно и собирать результаты. Этот подход позволяет избежать накладных расходов на потоки и может быть очень эффективным для большого количества конечных точек. Однако смешивание asyncio с Playwright (который сам может использоваться асинхронно) может усложнить задачу. Прагматичное решение — использовать многопоточность для фазы HTTP-сканирования (поскольку обход с Playwright может быть проще управлять в синхронном режиме).

    • Параллельный обход: Мы также должны рассмотреть возможность распараллеливания обхода, если сайт большой. Playwright может открывать несколько страниц одновременно с помощью асинхронного контекста. Мы могли бы реализовать ограниченную конкурентность (например, 2-3 страницы одновременно) для обхода. Например, по мере извлечения новых URL мы могли бы запускать новую страницу для каждой, если используем asyncio. Это может быть продвинутой оптимизацией при необходимости. Изначально однопоточный обход проще и подходит для сайтов умеренного размера, но в проекте это можно отметить как точку для улучшения.

    • Потокобезопасность: Мы обеспечим потокобезопасную обработку общих данных. Список URL для сканирования можно обрабатывать с помощью ThreadPoolExecutor.map для простоты, или мы можем использовать потокобезопасную очередь (Python queue.Queue) и заставить потоки извлекать из неё элементы, пока она не опустеет. Набор visited для обхода доступен только краулеру (один поток, если мы не делаем параллельный обход). Потоки сканера будут только читать из своего списка URL (никаких изменений общих структур, кроме, возможно, логирования результатов, которое мы можем защитить блокировкой или просто собирать в потокобезопасный список).

    • Ограничение скорости и вежливость: Поскольку это инструмент тестирования безопасности, скорость является приоритетом, но мы всё же можем захотеть избежать перегрузки цели. Пользователю можно посоветовать установить разумное количество потоков. При необходимости мы также можем реализовать небольшую задержку или использовать семафоры для ограничения конкурентности. Например, мы можем не запускать все потоки сразу, если сеть пользователя или сервер могут захлебнуться. В продвинутом сценарии асинхронный подход может использовать семафор, чтобы разрешить, скажем, 5 одновременных запросов. Эти детали можно настроить на основе тестирования производительности скрипта.

    Таким образом, конкурентность будет в первую очередь применяться к фазе сканирования для параллельного тестирования нескольких конечных точек. Это делает сканер намного быстрее без существенной потери точности (поскольку каждый запрос независим). Как отмечает один источник, «многопоточность с помощью concurrent.futures может дать значительный прирост. Мы можем выполнять задачи ввода-вывода одновременно в нескольких потоках и наблюдать большое ускорение»​. Многопоточность здесь подходит, потому что сетевые задачи выигрывают от неё даже в Python​.

    🚀 Основная логика сканирования: тестирование конечных точек на уязвимость

    Сердце скрипта — модуль сканирования, который берёт список обнаруженных конечных точек (путей) и проверяет каждую на признаки уязвимости CVE-2025-29927. Процесс для каждой конечной точки будет следующим:

      1. Базовый запрос: Отправьте HTTP GET-запрос к конечной точке без специального заголовка, имитируя обычный запрос пользователя. Запишите код состояния и длину тела ответа (или хэш тела) для сравнения. Также отметьте любые интересные заголовки ответа. В частности, если ответ содержит какие-либо заголовки промежуточного ПО Next.js, такие как x-middleware-rewrite, x-middleware-next или x-middleware-redirect, это указывает на то, что данный маршрут защищён middleware​. Мы также проверяем, не равен ли код состояния 200 (что означает, что доступ был запрещён или произошло перенаправление), поскольку именно такие запросы потенциально могут быть обойдены. (Если код состояния уже 200 и контент загружается нормально, это либо публичная страница, либо уязвимость не применима; мы всё равно можем протестировать её, но реальный интерес представляют защищённые страницы.)
      1. Формирование вредоносных запросов: Отправьте дополнительные запросы к той же конечной точке, на этот раз включив заголовок X-Middleware-Subrequest. Мы попробуем различные значения заголовка, чтобы обеспечить обнаружение для всех версий Next.js:
    • Общее значение, например "1" или "true" (некоторые источники предполагают, что просто установка заголовка в любое значение вызывает пропуск​).

    • Конкретная нагрузка, используемая в публичных эксплойтах, например "middleware:middleware:middleware:middleware:middleware" (пять повторений "middleware")​. Известно, что она вызывает обход в последних версиях (13+). Мы включим именно это значение.

    • Альтернативная нагрузка для проектов, использующих каталог /src, например "src/middleware:src/middleware:src/middleware:src/middleware:src/middleware"​

    • Опционально, однозначные значения, такие как "middleware" или "src/middleware" для полноты (более старые версии Next.js могут использовать файл _middleware в каталоге pages, с несколько иной необходимой нагрузкой​, но указанные выше многозначные нагрузки в значительной степени покрывают известные случаи). Каждый из этих запросов будет выполняться с установленным пользовательским заголовком. Также мы обеспечим использование того же метода (GET) и включим любые заголовки из базового запроса, которые могут потребоваться (например, куки или токены аутентификации, если пользователь предоставил их для сканирования с авторизацией, хотя обычно мы сканируем без аутентификации).

      1. Сравнение ответов: Для каждого теста с заголовком сравните ответ с базовым:
    • Если базовый ответ был ошибкой или перенаправлением (например, 401 Unauthorized, 403 Forbidden или перенаправление на страницу входа) и один из ответов с инжектированным заголовком имеет код 200 OK с существенно большим телом (или иным образом указывает, что страница загрузилась), это сильный индикатор уязвимости. Например, если /admin обычно возвращает 403, а с заголовком возвращает 200 и содержит HTML панели администратора, мы помечаем это.

    • В некоторых случаях разница может быть в 302 против 200, или 404 против 200. Мы будем считать изменение кода состояния с не-200 на 200 вероятным признаком. Также, если код состояния остаётся 200, но длина содержимого кардинально меняется, это может указывать на то, что заголовок изменил поведение (менее характерно для этой конкретной ошибки, но возможно, если страница обычно отдавала одно, а с заголовком — другое).

    • Мы реализуем такие проверки: if base_status_code != 200 and test_status_code == 200: (и, возможно, также убедимся, что test_body_length > base_body_length или содержит ключевое слово для аутентификации), затем помечаем как уязвимый. Если базовый ответ был перенаправлением (например, 307 на /login), а тестовый даёт 200, также помечаем. По сути: «Был ли доступ ранее запрещён, а теперь разрешён?».

    • Если код состояния ответа с заголовком равен 404 или 500, в то время как базовый был перенаправлением, это может быть сценарием отравления кэша (обход перенаправления middleware, вызывающий 404 на источнике​). Этот сценарий сложнее обнаружить одним запросом, но наличие 404 с заголовком, когда базовый был перенаправлением, также можно отметить (хотя это не обход аутентификации, но всё же эффект уязвимости). Однако наша цель — обнаружение обхода аутентификации (доступ с кодом 200 OK).

      1. Логирование результатов: Для каждой протестированной конечной точки скрипт будет логировать результат. Если различий не найдено (не уязвимо), мы можем оставить это в подробном журнале или отбросить. Если найдена потенциальная уязвимость, мы записываем конечную точку, базовый статус и то, какое значение заголовка привело к коду 200, и т.д. Они будут выведены на консоль и сохранены в results.txt, если пользователь выбрал сохранение результатов. Мы должны отформатировать это понятно, например:
    • [*] /admin -> базовый 403, с X-Middleware-Subrequest (нагрузка X) получен 200 [УЯЗВИМО]

    • Также можно вывести что-то вроде длины ответа или фрагмента ответа для подтверждения (возможно, только длина для краткости, например, «len: 0 -> 10240 байт»). Если было опробовано несколько нагрузок, можно перечислить, какие сработали.

    • Если сайт, похоже, вообще не является приложением Next.js (например, мы не нашли /_next/static/ на главной странице, что является характерным признаком​), мы можем вывести примечание: «Индикаторы Next.js не найдены, цель может не использовать Next.js — скорее всего, не уязвима». Но мы всё равно можем продолжить общее сканирование, так как проверка Next.js является оптимизацией, а не необходимостью.Эта логика будет аккуратно инкапсулирована. Например, у нас может быть функция scan_endpoint(url, session, header_payloads)`, возвращающая объект или dict с информацией об уязвимости и деталями. Мы включим надежные проверки для избежания ложных срабатываний. В частности, требование изменения кода состояния на 200 (или других явных признаков) поможет гарантировать, что мы отмечаем только реальные обходы. Как отмечено в анализе ProjectDiscovery, сканер проверяет ответ со статусом 200 при добавлении специального заголовка, чтобы подтвердить уязвимость​.

    🚀 Форматирование вывода и отчетность

    Вывод скрипта должен быть легко читаемым и интерпретируемым, а также по желанию сохраняться в файл. Мы отформатируем консольный вывод с четкими заголовками и отступами, где это уместно. Некоторые соображения:

    • После сканирования вывести сводку результатов. Например: «Сканирование завершено: найдено 3 уязвимых конечных точки (из 45 протестированных).» Затем перечислить уязвимые конечные точки с деталями.

    • Использовать единый формат для каждой строки результата, как показано выше, возможно с тегом [VULNERABLE] для привлечения внимания. Если использовать библиотеку вроде rich, можно даже раскрасить «VULNERABLE» красным или желтым. Даже без дополнительных библиотек можно использовать ANSI-коды через colorama для выделения или просто текст в верхнем регистре.

    • Если уязвимости не найдены, сообщить об этом явно: «Уязвимости для CVE-2025-29927 не обнаружены.»

    • Если результаты нужно сохранить, убедиться, что они записаны в файл в аналогичном формате. Возможно, в более подробном виде или CSV для программного использования, но поскольку пользователь специально упомянул текстовый файл, скорее всего мы просто запишем те же строки в results.txt.

    • Также любые критические ошибки или исключения (например, невозможность загрузить определенную страницу) должны сообщаться в выводе в корректной форме (вместо трассировки стека). Мы можем перехватывать исключения и выводить предупреждение одной строкой для каждого неудачного URL: например, «Тайм-аут загрузки /blog (пропущено)». Таким образом, пользователь будет знать, какие пути не были протестированы.

    Во время выполнения мы можем показывать спиннер или прогресс (для длительных запусков) или, по крайней мере, выводить, какая страница сейчас сканируется или какая конечная точка тестируется, если включен подробный режим. Для более чистого вывода можно показывать только обнаруженные уязвимые случаи в конце, но журнал выполнения (возможно, записываемый в отдельный файл) может помочь с прозрачностью.

    Учитывая акцент на понятном формате, использование маркированных списков или табличного представления может помочь при выводе нескольких результатов:

    • Можно табулировать как: Endpoint | Base Status | Base Length | Bypass Status | Bypass Length | HeaderValueUsed | Result

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

    Предоставляя как вывод на экран, так и опциональное сохранение в файл, инструмент будет полезен как для интерактивного использования, так и для автоматического сканирования (где пользователь может позже просмотреть файл или интегрировать его в отчеты).

    🚀 Модульная структура кода и лучшие практики

    Чтобы сделать скрипт поддерживаемым и профессиональным, мы организуем код в модули, каждый из которых отвечает за отдельный аспект функциональности. Возможная структура проекта:

    • crawler.py: Содержит логику обхода с использованием Playwright. В нем будут функции вроде crawl_site(start_url, config) -> List[str], возвращающие список обнаруженных внутренних путей. Этот модуль будет обрабатывать запуск браузера, получение страниц, извлечение ссылок и применение фильтров (домен, исключение статических файлов). В нем также может быть вспомогательная логика для нормализации URL (например, удаление фрагментов URL, обработка относительных путей через urllib.parse.urljoin).

    • scanner.py: Содержит логику сканирования на уязвимость. Он будет включать такие функции, как scan_paths(url_list, config) -> List[ScanResult]. Это будет управлять созданием HTTP-запросов (с использованием requests.Session или клиента httpx), применением заголовков, сравнением ответов и сбором результатов. Если используется многопоточность, этот модуль создаст ThreadPool и будет управлять задачами. В нем может быть определен небольшой класс данных ScanResult для хранения информации о каждом пути (path, vulnerable: bool, details).

    • config.py (или settings.py): Содержит код для пользовательского меню и конфигурации. Например, функция get_user_config(), которая взаимодействует с пользователем и возвращает объект/словарь конфигурации со всеми выбранными настройками (user_agent, timeout, proxy, output_file flag и т.д.). Если используются аргументы командной строки, этот модуль может альтернативно парсить argparse.ArgumentParser. По сути, эта часть изолирует весь пользовательский ввод и обработку конфигурации.

    • utils.py: Вспомогательные функции, например, для вывода баннеров, форматирования строк вывода, обработки цветного вывода или общих хелперов, таких как is_static_resource(url) (проверка, ведет ли URL к статическому файлу). Также может включать функцию для корректного завершения (вызываемую при SIGINT).

    • main.py: Точка входа, связывающая все вместе. Она будет:

      1. Разбирать или собирать конфигурацию пользователя (с помощью config.py).
      1. Вызывать обходчик для получения списка конечных точек.
      1. Вызывать сканер для тестирования этих конечных точек.
      1. Получать результаты и выводить их в запрошенном формате.
      1. Обеспечивать очистку (закрытие браузера, закрытие файлов и т.д.). Если распространяется как один скрипт, main может быть просто внизу одного файла, но для чистоты лучше разделить.

    Каждый модуль будет спроектирован как модульный и переиспользуемый. Например, можно переиспользовать crawler.py для получения ссылок сайта для других целей, или переиспользовать scanner.py для тестирования этой уязвимости по заданному списку URL (даже без обхода).

    Обработка исключений и корректное завершение: Мы реализуем надежную обработку исключений:

    • Обернуть сетевые операции в try/except (перехватывать таймауты, ошибки соединения и т.д.). Если обход страницы не удался, логировать это и продолжать с другими. Если запрос сканирования не удался (например, ошибка прокси), пометить эту конечную точку как ошибочную, но продолжить сканирование остальных.

    • Использовать блоки finally или контекстные менеджеры для гарантии освобождения ресурсов. Например, использовать контекст async_playwright() или гарантировать, что browser.close() вызывается в конце обхода. Аналогично, после записи файлов закрывать файловые дескрипторы.

    • Обрабатывать KeyboardInterrupt (Ctrl+C): Мы можем перехватывать KeyboardInterrupt в основном цикле и инициировать корректное завершение – например, вывести «Остановка, очистка…», завершить потоки (возможно, с помощью ThreadPoolExecutor.shutdown(wait=False) для остановки запуска новых задач) и закрыть браузер. Это предотвращает появление осиротевших процессов или заблокированных файлов, если пользователь прерывает выполнение.

    • Использовать логирование для отладочных сообщений (возможно, через библиотеку logging в Python). В профессиональном инструменте будут уровни логирования; например, отладочные логи могут включать каждый сделанный запрос, а уровень info – только общий прогресс. Пользователь может установить флаг verbose для переключения. По умолчанию мы можем логировать минимум информации, чтобы не перегружать вывод.

    Качество кода: Мы будем придерживаться лучших практик кодирования:

    • Следовать стилю PEP8 для читаемости.

    • Использовать осмысленные имена функций и переменных.

    • Добавлять docstring к функциям, объясняющие их назначение и использование.

    • Использовать аннотации типов для сигнатур функций (Python 3 type annotations), чтобы код было легче понимать и выявлять проблемы с типами на ранних этапах.

    • Модулизировать константы (например, список заголовков-полезных нагрузок, списки расширений статических файлов для игнорирования и т.д.) в начале или в конфиге, чтобы их можно было легко обновить. Например, HEADER_PAYLOADS = ["middleware:middleware:...","src/middleware:..."] и т.д., определенные в одном месте.

    • Возможно, включить модульные тесты для некоторых вспомогательных функций (если бы это был более крупный проект, но для однофайлового инструмента это может быть опущено; тем не менее, проектирование с учетом тестируемости полезно).

    Профессиональные улучшения: Чтобы сделать скрипт более надежным и готовым к использованию, можно также рассмотреть:

    • Поддержка аутентификации: Позволить пользователю предоставлять куки или учетные данные, если он хочет сканировать аутентифицированную часть сайта (хотя уязвимость связана с обходом аутентификации, могут быть сценарии, где нужно сначала войти, чтобы добраться до определенных ссылок, а затем тестировать обход на них – хотя обход, вероятно, работает и без валидной аутентификации, это может помочь в обходе глубоких ссылок, которые не являются публичными).

    • Файл конфигурации: В дополнение (или вместо) интерактивного ввода, разрешить чтение опций из конфигурационного файла или переменных окружения, что полезно для автоматического развертывания сканера.

    • Форматы вывода: Предоставить вывод в нескольких форматах, таких как JSON или CSV, для интеграции с другими инструментами. Например, флаг --json может выгружать результаты в машиночитаемый JSON.

    • Интеграция с существующими фреймворками: Логика может быть интегрирована в более крупный фреймворк сканирования (например, превращение его в модуль для OWASP ZAP или интеграция с ProjectDiscovery Nuclei путем вывода совместимого отчета). Как минимум, убедиться, что вывод скрипта четко идентифицирует уязвимость и затронутые URL, чтобы его можно было использовать в отчетах.

    • Параллельные сессии браузера: Если целевые приложения очень большие, рассмотреть запуск нескольких контекстов браузера параллельно для одновременного обхода разных разделов. Playwright может обрабатывать несколько контекстов (каждый контекст изолирован, аналогично отдельным профилям браузера)​. Это может значительно ускорить обход ценой более высокого потребления ресурсов.

    • Плавная деградация: Если Playwright не сработает (например, в окружении нет дисплея или правильной установки), скрипт может переключиться на более простой обход на основе запросов (который может пропустить некоторые ссылки, но это лучше, чем ничего). Это делает инструмент более надежным в разных средах. Аналогично, если уровень параллелизма слишком высок и вызывает проблемы, перехватывать их и предлагать пользователю уменьшить количество потоков.

    Следуя чистой структуре и этим лучшим практикам, скрипт будет легче поддерживать и расширять. Каждый компонент может разрабатываться независимо – например, улучшение способности обходчика анализировать навигацию на JavaScript, или обновление сканера новыми вариациями заголовков-полезных нагрузок, если будущие исследования обнаружат дополнительные шаблоны эксплуатации.

    В заключение, этот проект описывает комплексный подход к обнаружению CVE-2025-29927 в веб-приложениях. Он использует безголовый браузер для глубокого обхода, многопоточность для эффективного сканирования и надежные практики кодирования для надежности. Сравнивая ответы с специальным заголовком и без него, он может надежно идентифицировать уязвимые конечные точки, где промежуточное ПО Next.js обходится​. Результатом является профессиональный инструмент, который помогает инженерам по безопасности и разработчикам быстро находить и устранять эту критическую уязвимость в своих приложениях.