TL;DR / Key Takeaways
Тревога, которая потрясла интернет
Для React Server Components наступил худший сценарий: обнаружена уязвимость удаленного выполнения кода с максимальной оценкой CVSS 10.0, которую исследователи по безопасности быстро охарактеризовали как "катастрофическую." Под угрозой оказались любые приложения, использующие уязвимый React серверный пакет, от любительских проектом на Next.js до высоконагруженных производственных сайтов, внезапно ставших уязвимыми для неавторизованных злоумышленников. Один искусно составленный HTTP-запрос мог выполнить произвольный код на сервере, без необходимости входа в систему.
Сопредседатели React ответили на выпуск фреймворка необычно прямолинейным языком, призвав разработчиков «незамедлительно обновиться» на всех затронутых версиях. Хостинговые платформы последовали их примеру: Vercel, Cloudflare и другие поспешили выпустить экстренные WAF правила, при этом предупредив, что эти фильтры являются лишь частичной защитой. Команды безопасности отнеслись к этому предупреждению как к учениям по нулевым дням, внедряя патчи в продакшн в течение нескольких часов.
Списки рассылки по безопасности и каналы Discord заполнились красными баннерами и сообщениями «бросьте всё и обновите React». Команды DevOps приостановили развертывание функций, чтобы отдать приоритет обновлению зависимостей, фиксации зависимостей и повторным развертываниям. CI-пайплайны, которые обычно требуют дней на изменения, внезапно начали поставлять новые сборки React за считанные минуты.
Название для ошибки пришло так же быстро. Исследователи и сообщество React сосредоточились на React2Shell, что является намеренным отголоском Log4Shell, сигнализируя о той же категории кошмара: повсеместный компонент, недостаток сериализации и тривиальное удаленное выполнение кода. Специальный сайт react2shell.com и растущая экосистема GitHub с доказательствами концепции укрепили этот брендинг.
Сравнения с Log4Shell были не просто маркетингом. Как и Log4j в 2021 году, React Server Components находятся глубоко в современных веб-стэках, скрытыми за фреймворками, шаблонами и стартовыми проектами. Многие команды тратили часы только на то, чтобы ответить на базовый вопрос: "Используем ли мы где-либо React Server Components, и на каких версиях?"
Сообщения о активной эксплуатации поступили практически сразу. Команды безопасности AWS предупредили о том, что «группы киберугроз стремительно пытаются это использовать», и сканеры扫или интернет в поисках уязвимых серверов Next.js. Охотники за уязвимостями и преступные организации начали обмениваться вредоносными кодами, которые превращали один единственный POST-запрос в командную строку на чужой инфраструктуре.
React2Shell: Ночь кошмаров с CVSS 10.0
React2Shell находится в ужасном разделе уязвимостей: неаутентифицированное удаленное выполнение кода на серверах, доступных в интернете. Никакого входа в систему, никакого CSRF-токена, никакого обмана пользователя, чтобы заставить его нажать на что-либо. Один специально подготовленный HTTP-запрос попадает на конечную точку React Server Components, и нападающий выполняет произвольные команды с теми привилегиями, которые имеет ваш процесс Node.
Специалисты по безопасности боятся RCE, потому что это подрывает все остальные защитные меры. Как только злоумышленник может выполнить код, он может прочитать переменные окружения, извлечь базы данных, загрузить веб-оболочки, установить криптомайнеры или углубиться в вашу облачную инфраструктуру. В этот момент вы уже не просто "утечка данных"; вы становитесь хостингом для операционного центра кого-то другого.
React2Shell не останавливается на Next.js. Уязвимость существует в пакете React server и его реализации протокола React Flight, поэтому любой фреймворк, который интегрируется в этот стек, наследует радиус поражения. Это включает проекты, такие как Waku, серверные функции React Router и любые пользовательские бэкенды, которые решили взаимодействовать с Flight напрямую.
CVSS 10.0 — это не маркетинговый трюк; это вершина стандартизированной шкалы риска. Такую высокую оценку подразумевает три вещи одновременно: тривиальная эксплуатация, отсутствие барьеров аутентификации и полный компромисс конфиденциальности, целостности и доступности. Вам не нужны цепочные уязвимости, условия гонки или локальный доступ; достаточно доступности в интернете и уязвимой версии.
Согласно CVSS, React2Shell достигает максимальных значений по всем показателям: Вектор атаки: Сеть, Сложность атаки: Низкая, Требуемые привилегии: Нет, Взаимодействие с пользователем: Нет. Метрики воздействия также достигают максимума, поскольку выполнение произвольного кода означает полный контроль над данными приложения и возможность вывести службу из строя или переработать её. Вот почему в рекомендациях это помечено как "Критическое", а не "Высокое".
Самая ужасная деталь: вам не нужно включать экзотические функции, чтобы столкнуться с проблемами. Уязвимый код находится в основной последовательности сериализации, которую компоненты сервера React используют по умолчанию, поэтому новый проект, созданный с помощью "npx create-next-app" на затронутых версиях, содержит уязвимую логику с первого дня. Никакие серверные действия, никакие пользовательские десериализаторы и никаких экспериментальных флагов не требуется.
React2Shell превращает шаблонные решения в уязвимую поверхность атаки. Если ваш стек взаимодействует с Flight через уязвимый пакет React-сервера и доступен по HTTP, вы попадаете под угрозу.
Ваше приложение имеет уязвимости (даже если вы не используете серверные действия)
React2Shell не принадлежит Server Actions. Он находится в самом протоколе React Flight — низкоуровневом сериализаторе/десериализаторе, который обеспечивает работу всех React Server Components. Если ваш стек обрабатывает загрузки Flight с уязвимой версией `react-server`, вы унаследуете неаутентифицированный RCE, независимо от того, использовали ли вы когда-либо `use server` в вашем коде.
Консультация Meta указывает на пакет `react-server` как уязвимый в определённых сборках 19.x. Любой фреймворк, который включает эти версии и предоставляет конечную точку Flight, подпадает под действие. Этот список включает Next.js, а также других пользователей Flight, таких как API данных React Router и новые фреймворки RSC.
App Router в Next.js делает это особенно опасным, поскольку его архитектура по умолчанию настраивает Flight за вас. Новое приложение, созданное с помощью `create-next-app` и использующее App Router, а также уязвимый релиз Next.js (например, 14.x с React 19.0.0–19.2.0), создает конечные точки, которые принимают данные форм Flight без дополнительной конфигурации. Постройте, разверните, и у вас имеется поверхность RCE, открытая для интернета.
Каждый HTTP-обработчик, который принимает нагрузку серверного компонента, становится потенциальной точкой входа. Это включает в себя: - Встроенные конечные точки данных маршрутизатора приложения - Пользовательские обработчики маршрутов, которые вызывают `renderToReadableStream` или подобные API Flight - Любая прокси или пограничная функция, которая пересылает нагрузки Flight на сервер Node
Аутентификация по умолчанию не защищает вас. Если злоумышленник сможет обратиться к конечной точке Flight до аутентификации, он получит предварительный удалённый код исполнения (RCE). Если ваш парсер Flight находится за входом в систему, но вы открываете его для браузеров, любое межсайтовое подделывание запросов или кража токенов мгновенно приводит к полному компрометации сервера.
Собственный отчет Meta, Критическая уязвимость безопасности в серверных компонентах React (CVE-2025-55182), ясно предупреждает, что правила WAF провайдеров хостинга являются лишь временной мерой. Обновите `react-server` и ваш фреймворк, или предполагаете, что любой открытый конечный пункт Flight уже подвергается проверке.
Анатомия атаки: Один запрос для взлома сервера
Одного HTTP-запроса достаточно, чтобы злоумышленник добился своего. React2Shell превращает скучный POST-эндпоинт в приложении React Server Components в удалённый шелл, используя недостатки в том, как протокол React Flight десериализует потоковые данные компонентов. Не требуется аутентификация, CSRF-токен или сессия пользователя.
Злоумышленники начинают с создания вредоносного POST-запроса, который выглядит как обычная отправка в браузере. Тело запроса использует `multipart/form-data`, тот же формат, который React Flight использует для потоковой передачи полезных нагрузок Серверных Компонентов и Серверных Действий. Внутри этих данных формы злоумышленник скрывает серию «фрагментов», которые имитируют внутренний синтаксис ссылок с префиксом `$`, используемый в Flight.
Каждый фрагмент делает вид, что является частью легитимного дерева компонентов, но структура использует уязвимость. Одно поле указывает на другой фрагмент, используя `$0`, `$1`, `$2` и так далее, в то время как специально составленная строка пути использует `:` как разделители для доступа к вложенным свойствам. Закопанный в этом пути находится реальный payload: попытка получить доступ к `__proto__` и проникнуть в внутренние объекты JavaScript.
Когда уязвимый сервер получает запрос, десериализатор Flight React срабатывает автоматически. Он разбирает данные формы, восстанавливает граф чанк и начинает разрешать ссылки `$` и пути с разделителями двоеточия. Ключевым моментом является то, что более старые версии сервера React никогда не проверяли, было ли запрашиваемое ключевое значение «собственным» свойством, поэтому `__proto__` проходил мимо.
Этот упущение превращает простую проверку в полноценное загрязнение прототипа. Разрешая путь, такой как `$1:__proto__:execSync`, десериализатор может предоставить злоумышленнику активную ссылку на `child_process.execSync` (или аналогичные примитивы), прикрепленные к загрязненному прототипу. Далее, полезная нагрузка инструктирует сервер выполнять произвольные командные оболочки в процессе десериализации.
Код для подтверждения концепции на React2Shell и оригинальные детализированные POC превращают это в однократную эксплуатацию. Пост, составленный злоумышленником, заставляет сервер выполнить команду, которая выводит "вы будете разыграны", а затем выполняет `cat secret.txt`, считывая файл, размещенный на рабочем столе сервера. В демонстрации содержимое напрямую потекает в журналы сервера Next.js, но тот же примитив может эксфильтровать секреты через `curl`, установить обратный шелл или установить постоянное вредоносное ПО с помощью одного запроса.
Внутри недостатка: Протокол React Flight
React Flight существует, чтобы решить реальную проблему: как передавать дерево React серверных компонентов от сервера к браузеру, не отправляя половину вашего серверного кода в виде JavaScript? Вместо JSON команда React разработала собственный формат передачи данных, который может описывать компоненты, свойства и ссылки в виде последовательности небольших "кусков", которые постепенно передаются по сети и последовательно обрабатываются на клиенте.
Каждый фрагмент в протоколе React Flight содержит небольшую часть пользовательского интерфейса: возможно, тип компонента, возможно, свойства, возможно, плейсхолдер для промиса. Чтобы избежать дублирования данных, Flight использует специальные строковые токены, начинающиеся с "$", чтобы ссылаться на другие фрагменты. Полезная нагрузка может содержать `"$1"`, что означает «посмотри на фрагмент 1», или `"$1:name"`, что означает «перейди к фрагменту 1, а затем следуй по пути `name` на каком-либо объекте, находящемся там».
Эти ссылки на `$` формируют компактный граф объектов, который десериализатор собирает обратно. Чанк 0 может быть просто `["$1"]`, чанк 1 может быть объектом, который сам указывает на чанк 2 и так далее. В результате на стороне сервера или клиента получается чистый объект JavaScript, такой как `{ name: "cherry" }`, даже несмотря на то, что формат передачи данных выглядел как странная смесь индексов и строковых путей.
Коренная причина React2Shell кроется в логике отслеживания пути. Десериализатор Flight с радостью принимал управляемые злоумышленником инструкции для обхода путей, такие как `"$1:__proto__:toString"`, и следовал им, не задаваясь вопросом, должны ли эти ключи быть доступными. Никаких защитных механизмов, никаких проверок свойств — только прямой доступ к тому, что описывала строка пути.
Вместо того чтобы ограничиваться пользовательскими данными, эти шаги обхода проникли прямо в внутренности JavaScript. Разрешая пути, такие как `__proto__`, на обычных объектах, десериализатор открыл дверь для классической загрязненности прототипа. Отсюда злоумышленники связали это с мощными встроенными функциями, в конечном итоге направив выполнение к `child_process` и добившись удаленного выполнения кода с помощью одного вредоносного запроса.
JSON здесь был бы скучным — и более безопасным. Стандартный JSON не содержит ссылок, путей или специальных семантик `$`; он описывает только данные, но не то, как их обходить или восстанавливать. Специфичный для Flight формат добавил ссылки между частями и синтаксис обхода, но без надежных слоев проверки, которые зрелые сериализаторы и парсеры JSON накопили за годы оценки безопасности.
Пользовательские протоколы всегда жертвуют безопасностью ради гибкости. Создав произвольный мини-язык внутри строк, подобных `"$1:foo:bar"`, формат Flight от React открыл новую вектор атаки, который не понимали универсальные инструменты — валидаторы JSON, проверяющие схемы, правила WAF. Как только этот мини-язык стал иметь доступ к `__proto__`, каждый сервер, использующий компоненты React Server, унаследовал тот же критический недостаток.
От преодоления путей к загрязнению прототипов
Промышленное загрязнение звуков абстрактно, но в JavaScript это один из самых опасных классов ошибок, которые вы можете включить в свой продукт. Вместо того чтобы испортить один единственный объект, прототипное загрязнение позволяет злоумышленнику вмешиваться в сам `Object.prototype`, общий предок почти каждого объекта в процессе Node или браузера. Как только этот корень оказывается скомпрометированным, вся объектная графа начинает наследовать свойства, контролируемые злоумышленником.
React Server Components попали в эту ловушку через свою логику прохода по пути протокола React Flight. Десериализатор поддерживает синтаксис на основе двоеточий для обхода вложенных структур, поэтому ссылка вроде `:$1:fruit:name` означает «следуй за частью 1, затем `fruit`, затем `name`». Исследователи поняли, что ничего не мешало им заменить обычный ключ на внутренности JavaScript и запросить `:__proto__` вместо этого.
Это одно изменение превратило удобную функцию в орудие. Когда уязвимый код встречал сегмент пути вроде `__proto__`, он воспринимает его просто как еще одно свойство, слепо переходя к `value['__proto__']`. В JavaScript этот переход предоставляет вам живой `Object.prototype` цели, а не безвредное поле в контейнере данных.
Как только уязвимость достигала `__proto__`, нападающие могли начать записывать в него. Отправив специальные части Flight, они могли делать такие вещи, как `payload: { ":$1:__proto__:pwned": "yes" }`, что эффективно устанавливает `Object.prototype.pwned = "yes"`. С этого момента каждый обычный объект в процессе внезапно получает свойство `pwned`, даже те, которые были созданы задолго после завершения запроса на эксплуатацию.
Загрязнение не останавливается на строковых флагах. Злоумышленники могут внедрить целые функции в прототип, такие как `Object.prototype.toJSON` или пользовательские хуки, которым доверяет последующий код. Если какая-либо позднее добавленная библиотека выполняет `JSON.stringify(user)` или вызывает `options.onSuccess?.()`, это может фактически запустить код, предоставленный злоумышленником, внедренный в прототип всего несколько минут назад.
React2Shell связывает это с удаленным выполнением кода, нацеливаясь на мощные, редко проверяемые места в стеке. Например, загрязненные свойства могут повлиять на то, как фреймворк строит команды оболочки, пути к файлам или динамические вызовы `require`. Как только загрязненное значение попадает в `child_process.exec`, движок шаблонов или динамический импорт, переход от “странного дополнительного поля” к “произвольной команде на сервере” происходит за одну строку.
Полные технические детали находятся в записи NVD для CVE-2025-55182, а детализированное доказательство концепции демонстрирует, как единственный HTTP-запрос как загрязняет `Object.prototype`, так и использует эти испорченные свойства в самых опасных API Node. Эта комбинация оправдывает оценку CVSS 10.0: один неаутентифицированный запрос, компрометация всей системы.
Финальная цепочка: Перехват обещаний для запуска кода
Проблема загрязнения прототипа сама по себе не дает возможность получить оболочку; злоумышленникам все равно нужен способ превратить испорченную объектную графику в выполняемые системные команды. Последний трюк React2Shell связал этот загрязненный прототип с полностью готовым к использованию удаленным выполнением кода, используя лишь не более экзотические средства, чем собственные функции рефлексии и асинхронные семантики JavaScript.
Как только атакующий получил контроль над прототипом базового объекта, он мог пройти по цепочке прототипов, чтобы достичь глобального конструктора Function. В JavaScript каждая функция в конечном итоге наследуется от `Function.prototype`, и сам `Function` доступен через конструкторы, такие как `({}).constructor.constructor`.
С таким доступом полезная нагрузка просто выполняет то, что делает каждый обход «no eval»: `new Function("require('child_process').execSync('id > /tmp/pwned');")`. Эта строка может содержать любую команду оболочки: `curl` для экстракции данных, `rm -rf` для удаления дисков или однострочник для создания обратной оболочки. На сервере Next.js эти команды выполняются с теми же привилегиями, что и процесс Node, часто предоставляя прямой доступ к переменным окружения, API-ключам и закрытым файлам.
Атакующие всё еще сталкивались с одной проблемой: они могли создать злонамеренную функцию, но не контролировали никакой очевидный сайт вызова. Им нужно было, чтобы собственный поток управления сервера автоматически вызывал их функцию без явного вызова `malicious()` в коде приложения.
Ключевое слово `await` в JavaScript обеспечило недостающую связь. Внутренне, `await value` проверяет, является ли `value` «thenable», и, если да, вызывает `value.then(resolve, reject)`. Это тихое поведение именно то, что приводит в действие Промисы — и именно то, что использует React2Shell.
Загрязнив общий прототип и определив свойство `.then`, указывающее на экземпляр Function злоумышленника, любой ожидаемый объект внезапно стал триггером. Когда код React Server Components достигал `await` на десериализованном значении, движок JS добросовестно вызывал `.then`, который теперь выполнял произвольные команды оболочки. Ни дополнительных хуков, ни странных гаджетов — просто обычные асинхронные кодовые пути, преобразовавшиеся в универсальный трамплин RCE.
Простое решение, которое спасло React
Исправление для React2Shell выглядит почти оскорбительно простым. После цепочки, начинающейся с обхода путей, затем переходящей к загрязнению прототипа, захваченным Promise и `child_process.execSync`, официальное исправление от команды React добавляет по сути только одного контролёра: единственный `if`, который вызывает `Object.prototype.hasOwnProperty` перед чтением свойства во время десериализации Flight.
Вместо того чтобы слепо выполнять `value = value[path]` для каждого сегмента обхода, исправленный код сначала проверяет `if (!Object.prototype.hasOwnProperty.call(value, path))` и выдает ошибку, если ключ отсутствует. Это маленькое условие меняет поведение с "обходить всю модель объектов JavaScript" на "доверять только полям, которые этот объект на самом деле владеет". Злонамеренные ссылки `__proto__`, которые существуют только в цепочке прототипов, внезапно сталкиваются с серьезной преградой.
Это работает, потому что `hasOwnProperty` полностью игнорирует унаследованную цепочку прототипов. В JavaScript каждый обычный объект наследует от `Object.prototype`, где находятся опасные мета-свойства, такие как `__proto__` и `constructor`. Настаивая на том, что каждый разыменованный ключ должен быть «собственным свойством», протокол Flight в React не позволяет злоумышленникам касаться этих внутренних элементов, таким образом загрязнённый прототип никогда не проявляется.
Исследователи в области безопасности любят утверждать, что большинство катастрофических ошибок сводятся к отсутствию проверки, и React2Shell это подтверждает. До патча десериализатор неявно доверял любому пути, который отправлял клиент, даже если он указывал прямо в «глубь» JavaScript. После внесения изменений одно это условие `if` преобразует цепочку CVSS 10.0 RCE в скучную ошибку “недопустимая ссылка”.
На фоне неаутентифицированных уязвимостей RCE в тысячах развертываний React Server Components элегантность почти тревожит. Огромная экосистема, построенная на React Server Components и Next.js, зависела от одной единственной защитной меры, которая должна была существовать с самого начала. Одна строка защитного кода теперь отделяет обычный рендер на сервере от полного захвата сервера.
Результаты: Актуальные уязвимости и обходы WAF
React2Shell перешел от теоретического кошмара к практическому набору атак всего за несколько дней. Репозитории с доказательствами концепции, описания эксплойтов и готовые к запуску полезные нагрузки теперь доступны на GitHub, что снижает порог входа с уровней государств до выходного инженера. Любое интернет-приложение, использующее уязвимые React Server Components, фактически сообщает: "неаутентифицированный шелл доступен на порту 443."
Команды безопасности уже наблюдают последствия. AWS сообщает, что «группы киберугроз стремительно пытаются это использовать», с сканерами, охватывающими огромные диапазоны IP в поисках характерных конечных точек React Flight. Независимые исследователи и MSSP описывают увеличившиеся атаки, которые отправляют искаженные полезные нагрузки Flight и следят за тонкими различиями во времени и ошибках, чтобы определить уязвимые цели.
Злоумышленникам не нужны идеальные копии исходной уязвимости. С общественными PoC и подробными статьями, такими как CVE-2025-55182 (React2Shell): удаленное выполнение кода в React Server Components, они могут бесконечно изменять полезные нагрузки. Изменяйте имена полей, переставляйте части или скрывайте загрязненную цепочку прототипов за дополнительными уровнями косвенности, и вы уже отклоняетесь от сигнатур, которые ожидают большинство правил WAF.
Провайдеры хостинга поспешили выпустить экстренные фильтры. Vercel, Cloudflare и AWS обновили WAF, чтобы блокировать очевидные схемы злоупотребления React Flight, такие как ссылки на `__proto__` в данных многочастных форм или подозрительные ссылки на фрагменты, начинающиеся с символа `$`. Эти правила помогают против атак копирования и вставки, но они нацелены только на известные формы ошибки, которая в основном заключается в том, как сервер десериализует вводимые данные.
История показывает, что защиты только на основе WAF быстро устаревают. Как только уязвимость с рейтингом CVSS 10.0 RCE становится известной, авторы эксплойтов работают быстрее, чем поставщики успевают выпустить новые сигнатуры. Трюки с обфускацией — юникодные однофонические символы, альтернативные пути доступа, такие как `constructor.prototype`, вложенные массивы или сжатые полезные нагрузки — регулярно обходят универсальные фильтры "заблокировать эту строку".
Только одно изменение в управлении меняет правила взаимодействия: обновление. Обновление React, Next.js и любого фреймворка, который включает уязвимый пакет React-сервера, полностью устраняет небезопасную десериализацию Flight. Никакая хитрая конфигурация WAF не может сравниться с уверенностью в том, что ошибка не будет запущена изначально.
Это «Log4Shell» момент для React?
React2Shell вызывает немедленные сравнения с Log4Shell по одной простой причине: масштаб разрушений. Один неаутентифицированный POST-запрос может вызвать удаленное выполнение кода практически в любом приложении, использующем уязвимые компоненты сервера React, от хоббийных проектов на Next.js до высоконагруженных панелей SaaS. Как и Log4Shell, ошибка скрыта в инфраструктурном коде, который тысячи команд приняли неявно, а не в очевидной «чувствительной к безопасности» функции, которую они осознанно включили.
Log4Shell использовал повсеместность Log4j в Java-стеке; React2Shell использует доминирование React в современных веб-фронтендах. Любой фреймворк, который интегрировал протокол React Flight — Next.js, API данных React Router, новые RSC фреймворки — внезапно унаследовал уязвимость с оценкой CVSS 10.0. Именно такой риск зависимости на уровне экосистемы и стал причиной того, что Log4Shell оказался событием, которое происходит раз в десятилетие.
Где Log4Shell разрушил представления о библиотеках логирования, React2Shell разрывает ментальную модель "фронтенд" фреймворков. Компоненты React Server размывают границу между клиентом и сервером, но эта ошибка доказывает, что безопасность также оказалась под угрозой. Дерево компонентов теперь функционирует как поверхность протокола, а формат сериализации тихо стал примитивом удаленного выполнения кода.
Ответственность за безопасность раньше была четко разделена: команды бэкенда защищали API и базы данных; команды фронтенда заботились о XSS и CSRF. Стеки эпохи RSC стирают эту грань. Когда компонент JSX может запустить серверную логику через пользовательский формат передачи данных, изменение на "фронтенде" может повлечь за собой уязвимость на бэкенде, и ни одна из сторон может не чувствовать полной ответственности.
Разработчикам теперь приходится задавать неудобный вопрос: существует ли у Server Components модель безопасности, о которой можно действительно рассуждать? React2Shell показал, как мало людей понимали внутренности Flight до этой недели, включая многих, кто внедрил его в продакшн. Если вы не можете объяснить, какие входные данные попадают в десериализатор, вы не можете адекватно оценить угрозы для вашего приложения.
Авторам фреймворков предстоит более жесткий мандат. Протоколы, такие как Flight, загрузчики данных Remix или пользовательские кодировки tRPC, заслуживают такого же внимания, как и сборщики запросов ORM или стеки TLS. Это означает необходимость формальных моделей угроз, фуззинга, проверок от красных команд и сторонних аудитов, сосредоточенных на сериализации, разрешении ссылок и межграницах потоках данных.
Быстрая патч-версия React предотвратила полный крах масштаба Log4Shell, но предупреждение звучит громко. Любой инструмент, который перемещает логику по сети — независимо от того, насколько он выглядит "фронтендным" — теперь однозначно попадает в категорию критической уязвимости атаки.
Часто задаваемые вопросы
Какова уязвимость React2Shell (CVE-2025-55182)?
React2Shell является критической уязвимостью удаленного выполнения кода (RCE) без аутентификации в серверных компонентах React. Она позволяет злоумышленнику выполнять произвольный код на сервере с помощью одного злонамеренного запроса и имеет высшую оценку степени серьезности по шкале CVSS 10.0.
Какие версии React и Next.js затронуты?
Уязвимость затрагивает версии React Server с 19.0.0 по 19.2.0. Это касается и фреймворков, использующих его, таких как Next.js. Любая версия Next.js, использующая затронутую версию React Server, например версия 16.0.6, показанная в демо, является уязвимой. Пользователям следует немедленно обновиться до последних исправленных версий.
Как работает эксплойт React2Shell?
Эксплойт использует небезопасный недостаток десериализации в протоколе React Flight. Отправляя специально подготовленный полезный заряд, злоумышленник может вызвать уязвимость 'загрязнения прототипа', изменяя основные поведения объектов JavaScript, что в конечном итоге приводит к цепочке команд и выполнению кода на сервере.
Достаточно ли WAF для защиты моего приложения от React2Shell?
Нет. Несмотря на то, что веб-фаерволы (WAF) от таких провайдеров, как Vercel и Cloudflare, могут блокировать известные схемы атак, они не являются полностью надежным решением. Злоумышленники часто могут скрывать полезную нагрузку, чтобы обойти правила WAF. Единственным надежным решением является обновление зависимостей React и Next.js до исправленных версий.