React2Shell CVE-2025-55182: RCE w React i Next.js
CVE-2025-55182 React2Shell ma CVSS 10.0 i umożliwia RCE bez logowania. Podatne wersje React/Next.js, publiczny PoC, ataki i patch.
- AUTOR
- Karol Rapacz / Pentester (OSCP, PNPT)
- PUBLIKACJA
- 3 grudnia 2025
- CZAS CZYTANIA
- 23 min czytania
- TEMAT
- Krytyczne CVE
CVE-2025-55182, znane jako React2Shell, to krytyczna podatność React Server Components oceniona na CVSS 10.0. Specjalnie przygotowane żądanie HTTP może bez uwierzytelnienia doprowadzić do wykonania kodu po stronie serwera podczas dekodowania danych protokołu React Flight. Luka dotyczy pakietów react-server-dom-webpack, react-server-dom-parcel i react-server-dom-turbopack w wybranych wydaniach React 19 oraz frameworków, które je osadzają, w szczególności Next.js.
Działaj natychmiast: zaktualizuj podatne pakiety RSC do 19.0.1, 19.1.2, 19.2.1 lub nowszej bezpiecznej linii, a Next.js do aktualnego poprawionego wydania. Sprawdź nie tylko bezpośrednie zależności, ale również obrazy, cache buildów i wdrożenia serverless. Google potwierdził szerokie wykorzystanie przez aktorów finansowych i szpiegowskich.
React2Shell — potwierdzone fakty
| Parametr | Wartość |
|---|---|
| CVE | CVE-2025-55182 |
| Nazwa | React2Shell |
| CVSS 3.x | 10.0 — krytyczna |
| Podatne pakiety | react-server-dom-webpack, -parcel, -turbopack |
| Podatne wersje | 19.0.0, 19.1.0, 19.1.1 i 19.2.0 |
| Pierwsze poprawki | 19.0.1, 19.1.2, 19.2.1 |
| Dostęp | zdalny, bez uwierzytelnienia i interakcji |
| Skutek | wykonanie kodu z uprawnieniami procesu serwera aplikacji |
| Publiczne PoC | tak, kilka implementacji i materiałów badawczych |
| Wykorzystanie | szerokie kampanie obserwowane krótko po ujawnieniu |
React Team opublikował advisory 3 grudnia 2025 r. i zaznaczył, że aplikacja może być podatna nawet wtedy, gdy nie definiuje własnych React Server Functions — wystarczy obsługa React Server Components przez używany framework.
Jak działa luka w protokole React Flight
React Server Components używa formatu Flight do przesyłania między klientem i serwerem referencji do komponentów, modułów i danych. Serwer dekoduje wieloczęściowe żądania oraz odtwarza referencje wskazujące na inne fragmenty modelu.
W podatnych wersjach logika rozwiązywania ścieżek referencji mogła przechodzić po właściwościach obiektu bez wystarczającego ograniczenia własnych pól. Kontrolowane dane pozwalały zbudować obiekt zachowujący się jak wewnętrzny chunk/thenable i skierować deserializację do funkcji wykonującej kod. Krytyczna operacja następowała zanim framework skutecznie potwierdził poprawność identyfikatora akcji.
Najważniejsze dla obrony:
- atak zachodzi podczas deserializacji żądania po stronie serwera;
- nie wymaga prawidłowej akcji biznesowej ani konta użytkownika;
- sam fakt obecności podatnych pakietów RSC w działającej ścieżce może tworzyć ekspozycję;
- błąd dotyczy serwera, nie kodu React wykonywanego wyłącznie w przeglądarce;
- aplikacje Next.js App Router są ważną, ale nie jedyną grupą ryzyka.
Nie każda witryna używająca React jest podatna. Statyczny SPA bez React Server Components i bez podatnych pakietów po stronie serwera nie ma tej ścieżki.
Next.js i zależności pośrednie
Next.js osadza React Server Components, dlatego podatność była początkowo śledzona również jako CVE-2025-66478, później oznaczone jako duplikat. Numery poprawionych wersji Next.js zmieniały się wraz z dodatkowymi aktualizacjami bezpieczeństwa. Nie wybieraj wersji z przypadkowej listy w mediach — użyj najnowszego advisory Next.js i aktualnej wspieranej linii.
Inwentaryzacja powinna objąć:
package-lock.json,pnpm-lock.yaml,yarn.locki monorepo;- artefakty standalone Next.js oraz warstwy obrazów kontenerów;
- funkcje serverless i edge z własnym cyklem wdrożenia;
- preview deployments i stare revision w platformach PaaS;
- zależności frameworków, które przynoszą RSC pośrednio;
- build cache, złote obrazy i środowiska disaster recovery.
Samo zmienienie package.json nie naprawia już zbudowanego obrazu. Trzeba przebudować, wdrożyć i usunąć stare repliki.
Publiczny PoC i ryzyko fałszywych exploitów
Repozytorium freeqaz/react2shell zawiera analizę, podatny serwer laboratoryjny, narzędzia detekcyjne i zestawienie publicznych PoC. To kod ofensywny, który powinien działać wyłącznie w izolowanym labie albo autoryzowanym teście.
Google Threat Intelligence Group ostrzegł, że po ujawnieniu krążyło wiele niedziałających, generowanych przez AI lub złośliwych repozytoriów. Niektóre próbki udające PoC zawierały malware wymierzone w badaczy. Dlatego:
- preferuj repozytoria wskazane przez uznane zespoły badawcze;
- sprawdź historię commitów, autora, zależności i skrypty instalacyjne;
- uruchamiaj kod bez sekretów, w jednorazowej maszynie bez dostępu do sieci firmowej;
- nie wprowadzaj prawdziwych adresów produkcyjnych do niezaufanych skanerów;
- dla produkcji opieraj decyzję na SBOM i wersji, nie na eksploitacji RCE.
Aktualizacja React i Next.js
React opublikował pierwsze poprawione wersje 19.0.1, 19.1.2 i 19.2.1. Później ujawniono dodatkowe błędy DoS i source-code exposure w tych samych pakietach, dlatego najbezpieczniej wdrożyć najnowszą poprawioną wersję w wybranej linii, a nie zatrzymać się na minimalnym patchu React2Shell.
Procedura:
- znajdź wszystkie trzy warianty
react-server-dom-*i frameworki zależne; - zaktualizuj lockfile w kontrolowanym branchu;
- uruchom testy funkcjonalne i bezpieczeństwa;
- wykonaj czysty rebuild bez starego cache;
- podpisz i wdroż nowy obraz lub artefakt;
- usuń stare revision oraz unieważnij preview deployments;
- potwierdź wersję działającego procesu przez SBOM/runtime, nie deklarację repozytorium.
WAF może czasowo blokować znane formaty żądań, ale nie jest pełną poprawką. Google i inni dostawcy wdrożyli reguły ochronne, jednak różne formaty payloadu i kodowanie zmniejszają pewność sygnatur.
Potwierdzone kampanie po ujawnieniu
GTIG obserwował szerokie wykorzystanie od 5 grudnia 2025 r. Aktorzy instalowali koparki XMRig, tunel MINOCAT, downloader SNOWLIGHT oraz backdoory HISONIC i COMPOOD. Google powiązał część aktywności z klastrami chińskiego cyberwywiadu, zaobserwował również aktywność finansową i aktorów związanych z Iranem.
Ta różnorodność pokazuje, że jeden IOC nie wystarczy. React2Shell stał się uniwersalnym initial access, a ładunek końcowy zależał od operatora.
Detekcja i threat hunting
Przejrzyj:
- nietypowe żądania multipart i nagłówki związane z Server Actions;
- wzrost odpowiedzi 500/303 i anomalie w ścieżkach App Router;
- procesy potomne Node.js: powłoki,
curl,wget, interpretery i narzędzia systemowe; - outbound DNS/HTTP z serwerów aplikacji do nowych domen;
- ukryte katalogi, nowe usługi systemd, cron i modyfikacje profili powłoki;
- koparki kryptowalut i skoki użycia CPU;
- pliki aplikacji zmienione po wdrożeniu oraz nieznane paczki npm;
- nowe klucze, tokeny i użycie sekretów CI/CD z nietypowych lokalizacji.
Jeżeli proces Node uruchomił polecenie, izoluj workload, zachowaj obraz i logi, obróć wszystkie sekrety środowiskowe oraz sprawdź platformę build/deploy. Odbuduj aplikację z czystych zależności i podpisanego artefaktu.
React2Shell jako lekcja AppSec
Nowoczesny frontend bywa pełnoprawnym serwerem aplikacyjnym z własnym protokołem RPC i deserializacją. SCA musi obejmować zależności runtime, a pentest aplikacji webowej powinien sprawdzać ścieżki frameworka, nie tylko endpointy opisane przez zespół biznesowy. Warto połączyć SBOM, aktualizacje automatyczne, testy na preview i monitoring procesów serwerowych.
Root cause i granice powierzchni ataku
Potwierdzona przyczyna znajduje się w serwerowym dekodowaniu danych React Flight w podatnych pakietach react-server-dom-*. Wpływ powstaje przed uwierzytelnieniem aplikacyjnym, dlatego logowanie użytkownika, MFA i poprawna autoryzacja endpointów biznesowych nie usuwają luki. Kod działa z uprawnieniami procesu Node lub platformy serverless, więc blast radius zależy od sekretów, filesystemu, egress i roli chmurowej tego procesu.
Powierzchnia ataku nie jest równoważna liście domen React. Trzeba ustalić, czy wdrożenie wykonuje RSC po stronie serwera i czy podatny pakiet znajduje się na aktywnej ścieżce. Obejmuje to:
- publiczne aplikacje Next.js App Router;
- wewnętrzne panele i preview dostępne przez SSO lub VPN;
- funkcje serverless, edge i regionalne repliki;
- stare revision nadal otrzymujące część ruchu;
- środowiska DR i obrazy wykorzystywane do autoscaling;
- monorepo, gdzie wspólny lockfile zasila wiele usług;
- platformy lub frameworki wnoszące pakiet RSC pośrednio.
Statyczny frontend bez serwerowego RSC nie ma tej samej ścieżki. Z kolei brak własnych Server Functions nie jest wystarczającym wykluczeniem, co podkreśla advisory React.
Bezpieczna walidacja ekspozycji
Produkcji nie trzeba exploitować. Wystarczą spójne dowody:
- wygeneruj SBOM i listę zależności z lockfile dla konkretnego artefaktu;
- ustal, który framework i build zawierają podatny pakiet;
- zmapuj aktywne revision, funkcje, regiony, preview i DR;
- potwierdź, że dany artefakt obsługuje RSC po stronie serwera;
- sprawdź digest obrazu lub identyfikator deploymentu działającej repliki;
- porównaj wynik z aktualnym advisory React i dostawcy frameworka;
- test dynamiczny wykonaj tylko na lokalnym, jednorazowym labie bez sekretów.
Proces warto powiązać z SBOM CycloneDX/SPDX i VEX oraz bezpieczeństwem obrazów kontenerów. Wynik skanera repozytorium nie wystarczy, jeżeli produkcja używa starszej warstwy obrazu. Analogicznie brak pakietu w jednym workspace nie wyklucza go w artefakcie standalone.
Telemetria i triage: request, proces, workload
Google opisał wiele rodzin narzędzi wykorzystywanych po uzyskaniu dostępu. Nie buduj detekcji wyłącznie na ich nazwach lub hashach. Łącz zachowanie:
| Warstwa | Dane | Pytanie triage |
|---|---|---|
| CDN/WAF | request ID, metoda, content type, nagłówki, status | czy żądanie dotarło do origin i którego regionu? |
| aplikacja | route, stack trace, 500/303, deployment ID | czy dekoder RSC obsłużył żądanie? |
| runtime | parent/child Node, command line, user, hash | czy proces aplikacji uruchomił nietypowe dziecko? |
| kontener/serverless | image digest, revision, cold start, file write | który artefakt i instancja były aktywne? |
| sieć | DNS, HTTP egress, nowy endpoint | czy po żądaniu nastąpiła komunikacja wychodząca? |
| tożsamość/chmura | użycie roli, tokenu i sekretu | czy dostęp rozszerzył się poza aplikację? |
| CI/CD | build, signer, provenance, deployment actor | czy później zmieniono łańcuch dostaw? |
Triage powinien najpierw ustalić wersję działającego artefaktu i korelację czasu. Następnie łączy request ID z logiem aplikacji, procesem potomnym, egress i użyciem chmurowej tożsamości. Odpowiedź 500 może wynikać z wielu błędów i sama nie dowodzi wykorzystania. Z kolei proces potomny Node bez legalnego zadania administracyjnego jest silnym sygnałem nawet bez znanego IOC.
Reguły te można utrzymywać w procesie detection engineering i Sigma, z testami dla legalnych błędów App Router i kontrolowanych zdarzeń canary.
Drzewo decyzji React2Shell
Czy artefakt zawiera jedną z podatnych wersji react-server-dom-*?
- Nie: zachowaj dowód SBOM/lockfile dla działającego deploymentu i monitoruj kolejne advisory.
- Tak lub nie wiadomo: traktuj wdrożenie jako wymagające pilnej aktualizacji oraz ustal aktywną ścieżkę RSC.
Czy podatny artefakt był osiągalny z Internetu lub niskozaufanej sieci?
- Tak: wykonaj hunting requestów, procesów, filesystemu, egress, sekretów i chmury od początku ekspozycji.
- Nie: popraw mimo wszystko i potwierdź kontrolę sieciową; phishing, SSRF lub przejęty host wewnętrzny mogą zmienić osiągalność.
Czy Node uruchomił nietypowy proces, zapisał plik lub użył sekretu?
- Tak: izoluj workload, zachowaj obraz i logi, unieważnij role/tokeny, sprawdź CI/CD i odbuduj ze zaufanego źródła.
- Nie: zakończ czysty rebuild, usuń stare revision i wykonaj retest telemetryczny.
Rotację tokenów i kluczy prowadź zgodnie z procesem zarządzania sekretami, obejmując również wartości w preview i platformie deploymentowej.
Hardening oraz weryfikacja naprawy
Najpierw wdroż najnowszą bezpieczną wersję w wspieranej linii i czysty rebuild. Następnie wymuś read-only filesystem tam, gdzie to możliwe, minimalny UID, ograniczony egress, krótkotrwałą tożsamość workloadu i brak narzędzi administracyjnych w obrazie runtime. SAST, DAST, SCA i IAST rozwiązują różne problemy; ich rolę porównuje przewodnik SAST vs DAST vs IAST.
Retest powinien wykazać:
- bezpieczną wersję w SBOM działającego digestu, nie tylko w repo;
- brak starych revision, cache i niezaktualizowanych funkcji;
- poprawne testy RSC i Server Actions po zmianie;
- zablokowanie publikacji podatnego artefaktu przez pipeline;
- widoczność nieszkodliwego requestu i canary child-process testu;
- brak nieoczekiwanego egress oraz minimalne prawa workloadu;
- zamknięcie lub rotację wszystkich sekretów osiągalnych z podatnej instancji.
PoC nie jest elementem retestu produkcyjnego. W labie można użyć go do sprawdzenia, czy zaktualizowana wersja nie zachowuje podatnego przebiegu, ale produkcja jest weryfikowana przez wersję, artefakt, telemetrię i kontrolę wdrożenia.
Lista kontrolna
- Zidentyfikowaliśmy wszystkie wdrożenia RSC i zależności pośrednie.
- Pakiety są na najnowszej bezpiecznej wersji w wybranej linii.
- Wykonaliśmy czysty rebuild oraz usunęliśmy stare revision i cache.
- Preview, serverless, edge i DR zostały zaktualizowane.
- Przejrzeliśmy procesy potomne Node, egress, persistence i użycie sekretów.
- PoC był używany wyłącznie w jednorazowym laboratorium.
- SBOM dotyczy działającego digestu i obejmuje zależności pośrednie.
- Logi CDN/WAF, aplikacji, runtime, chmury i CI/CD mają wspólny deployment ID lub czas.
- Rotacja objęła sekrety workloadu, preview i platformy deploymentowej.
- Po wdrożeniu wykonaliśmy niezależny retest.


