Перейти к содержимому
← Каталог nodejs SSTI

ReDoS: catastrophic backtracking в проверке email профиля

Сервис ProfileGuard валидирует email пользователя на стороне сервера через регулярное выражение с вложенными квантификаторами. Тщательно подобранная входная строка вызывает экспоненциальный backtracking движка V8, поток событий блокируется на десятки секунд, инцидент фиксируется в логе администратора — и вместе с ним выдаётся флаг.

mediumnodejsPro
Задача
# ReDoS: catastrophic backtracking в проверке email профиля ## Что это за уязвимость ProfileGuard — внутренняя SaaS-платформа учётных записей: сотрудник логинится и через профиль может изменить контактный email. Перед сохранением сервер проверяет «корректность» адреса с помощью регулярного выражения. Кажется безобидной операцией, но регулярка написана так, что движок V8 при определённых входных данных уходит в экспоненциальное число шагов — за то время, пока он там «думает», поток событий Node.js полностью заморожен и никакой другой запрос на этом процессе не обслуживается. Это и есть Regular Expression Denial of Service (ReDoS). В отличие от классических DoS-атак на пропускную способность сети или память, здесь достаточно одного маленького HTTP-запроса с тщательно подобранной короткой строкой, чтобы воркер встал колом на десятки секунд. На однопроцессной Node-инсталляции это эквивалентно «выключи продакшен на минуту одним запросом». В лабе сделано так, что событие «валидация заняла слишком много времени» само по себе считается incident по доступности: сервер фиксирует факт в таблице инцидентов и публикует справочный токен (CTF-флаг) в админ-эндпоинте `/admin/incident-report`. На реальном сервисе там вместо токена была бы ссылка в SIEM и pager на on-call инженера — для лабы этого вектора достаточно, чтобы у студента был чёткий маркер успешной эксплуатации. ## Где искать После входа на платформе доступны: - `GET /profile` — страница профиля, форма «Проверить email». - `POST /api/profile/email-check` — REST-эндпоинт валидации, принимает JSON `{ "email": "..." }`, отвечает `{ "valid": boolean, "duration_ms": number }`. Именно этот хэндлер выполняет уязвимое регулярное выражение. - `GET /admin/incident-report` — список зафиксированных инцидентов доступности. После первого детектирования ReDoS возвращает поле `reference` с подстрокой `flag{...}`. Учётная запись для входа: `demo` / `demo`. ## Что нужно сделать 1. Авторизуйтесь как `demo` / `demo` и откройте страницу профиля. 2. Сформируйте такой email-кандидат, чтобы серверная валидация заняла секунды (а не миллисекунды) и зафиксировала incident — `duration_ms` в ответе будет ≥ 2000. 3. Откройте `/admin/incident-report`. В поле `reference` вы увидите токен формата `flag{...}` — это и есть флаг лабораторной. Уязвимость живёт целиком на сервере, в одном файле — `internal/handlers/handlers.js`. Никаких сложных payload'ов, протоколов или цепочек не требуется: суть атаки умещается в одну особую строку и понимание того, как backtracking-движок исследует пространство сопоставлений.
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru