Уязвимость React2Shell показала, насколько быстро злоумышленники могут эксплуатировать тонкие особенности server-side rendering (SSR) для выполнения кода на сервере — и как сложно обнаружить атаку после её начала. Если вы запускаете React или Next.js в продакшне, этот чеклист поможет проверить критически важные точки безопасности.
Что нарушает React2Shell: понимание угрозы
React2Shell (CVE-2025-55182 и CVE-2025-66478) — это не обычная уязвимость, которую можно закрыть одним патчем. Она затрагивает сам фреймворк и класс уязвимостей, возникающих при некорректной обработке пользовательских данных в процессе SSR. Активная эксплуатация началась буквально через несколько часов после публичного раскрытия.
Ключевые допущения, которые нарушает эта уязвимость:
- Серверный контекст выполнения. Когда React-компонент рендерится на сервере, он работает не в браузерной песочнице, а в бэкенд-рантайме. Злоумышленник может внедрить JavaScript, который выполнится на сервере с теми же правами, что и само приложение — открывая доступ к cloud-credentials, внутренним API и файловой системе.
- Клиентская санитизация не работает для SSR. Паттерны, безопасные в браузере, могут стать опасными при SSR-рендеринге. Данные, никогда не предназначавшиеся для выполнения, могут быть интерпретированы как код при неправильной обработке серверным компонентом.
- Абстрагированные SSR-паттерны трудно отследить. В крупных кодовых базах SSR-логика часто переиспользуется и практически не проверяется. React2Shell возникает из неявного поведения фреймворка, а не из очевидно небезопасного кода.
Практический чеклист: что проверить немедленно
1. Инвентаризация окружения
- Определите все сервисы, использующие React Server Components (RSC), серверные компоненты Next.js или SSR.
- Не забудьте про административные панели и дашборды внутренних инструментов — они часто остаются за пределами внимания.
- Убедитесь, что версии фреймворков и пакетов обновлены в соответствии с актуальными рекомендациями безопасности.
- Зафиксируйте зависимости на конкретные версии, закоммитив
package-lock.json. Используйтеnpm auditили Socket для проверки известных уязвимостей.
2. Аудит потоков данных
- Проверьте: передаётся ли пользовательский ввод в серверные компоненты?
- Есть ли динамические пути рендеринга, оценивающие структуры данных или сериализованный контент?
- Данные из логики приложения не должны автоматически считаться безопасными — они тоже подлежат проверке.
- Используйте библиотеки валидации схем (Zod, Valibot) для проверки входящих данных. TypeScript-типизация — это первый шаг, но она не гарантирует валидность данных на рантайме.
- Создайте выделенный Data Access Layer (DAL), централизующий всю логику доступа к данным с проверками авторизации и возвратом безопасных DTO.
3. Разграничение прав доступа
- Нужен ли этому сервису исходящий доступ в интернет? Ограничьте его до минимума.
- Соответствуют ли учётные данные и права принципу минимальных привилегий?
- Могут ли контейнеры писать на диск или порождать дочерние процессы? Если не должны — ограничьте.
- Переменные с префиксом
NEXT_PUBLIC_видны на клиентской стороне — используйте их осторожно. - Только DAL должен обращаться к
process.env, чтобы предотвратить утечку секретов.
4. Защита от XSS и управление политиками
- Избегайте
dangerouslySetInnerHTML— он обходит встроенные механизмы защиты React. - Реализуйте строгую Content Security Policy (CSP) с директивой
default-src 'self'и nonce-based скриптами. - Настройте заголовок
Strict-Transport-Security(HSTS) для принудительного HTTPS. - Установите
X-Content-Type-Options: nosniffдля предотвращения content sniffing. - Используйте библиотеки Nosecone или Helmet для автоматической установки security headers.
5. Аутентификация и авторизация
- Всегда проверяйте авторизацию на сервере — никогда не полагайтесь только на клиентские проверки.
- Server Actions должны повторно проверять авторизацию пользователя при каждом вызове.
- Используйте Role-Based Access Control (RBAC) с серверными проверками и принципом наименьших привилегий.
- Применяйте SameSite cookies для защиты от CSRF-атак.
- Внедрите многофакторную аутентификацию (MFA) для критичных сервисов.
EtherRAT: что происходит после эксплуатации
В одной из реально задокументированных атак на React2Shell (исследование Sysdig Threat Research Team) был развёрнут кастомный троян удалённого доступа — EtherRAT. Его особенность: вместо традиционной C2-инфраструктуры он использует блокчейн Ethereum. Команды кодируются в транзакции блокчейна, а заражённые системы отслеживают цепочку в ожидании инструкций.
Это даёт злоумышленникам ряд преимуществ:
- Устойчивость: публичные блокчейны высокодоступны и крайне сложны для блокировки.
- Скрытность: трафик блокчейна всё чаще легитимен в корпоративных средах, что затрудняет его выявление.
- Сложность атрибуции: нет центрального сервера, который можно изъять или перехватить.
EtherRAT — не оппортунистическое вредоносное ПО. Это целенаправленный инструмент, разработанный для смешивания с нормальным операционным шумом. Вывод: вы не всегда увидите «вредоносное» поведение при эксплуатации уязвимости. Нужно знать нормальное поведение своего окружения, чтобы замечать отклонения.
Как обнаруживать скрытые угрозы в рантайме
Обнаружение злоупотреблений React2Shell требует наблюдения за поведением рабочих нагрузок в реальном времени. Вам не обязательно знать о конкретных угрозах — достаточно понимать нормальное поведение своего приложения и среды.
На уровне процессов:
- Веб-сервер или Node.js-процессы, порождающие оболочки (shells).
- Неожиданные дочерние процессы.
- Выполнения в рантайме, не соответствующие нормальному запуску приложения.
На уровне сети:
- Исходящие соединения с незнакомыми внешними эндпоинтами.
- Долгоживущие исходящие соединения без связи с функцией приложения.
- Блокчейн-трафик от веб-сервисов, не имеющих бизнес-потребности в нём.
На уровне файловой системы:
- Запись во временные директории от веб-facing процессов.
- Создание или выполнение новых бинарных файлов в рантайме.
Ключевые выводы для команд безопасности
React2Shell и EtherRAT обозначают несколько системных трендов, с которыми придётся считаться:
- Размытие границы клиент/сервер. Когда JavaScript работает везде, слепые допущения становятся крайне дорогостоящими. Серверный JavaScript — это серверный код.
- Оружие из легитимной инфраструктуры. Блокчейны, CI/CD-системы, cloud metadata services — всё это потенциальные инструменты атакующих.
- Пределы статических средств контроля. Никакое сканирование не спасёт от логических уязвимостей, которые проявляются только во время выполнения.
Относитесь к SSR-путям выполнения кода с той же строгостью, что и к бэкенд-логике. Используйте runtime-детекцию на основе нормальных и аномальных поведенческих паттернов, а не только сигнатур известных угроз. Продакшн-поведение — это новый периметр безопасности.