
Uma breve discussão sobre a análise de vulnerabilidade RCE em React Server Components
Nos últimos dias, uma vulnerabilidade de RCE por desserialização no React tem causado alvoroço, com a CVSS oficial atribuindo uma pontuação máxima de 10,0, igualando-se ao Log4j da época. Imediatamente, espalharam-se rumores de que se tratava do "Log4j do frontend moderno", causando pânico entre desenvolvedores de várias empresas. Assim, ao acordar, todos começaram a pesquisar documentação e aplicar patches... Simultaneamente, também surgiram muitas vozes de dúvida online. Alguns testaram e descobriram que a vulnerabilidade não era tão grave como se propagava; pelo contrário, a exploração exigia certas condições. Por isso, decidi dedicar algum tempo para estudar a fundo esta vulnerabilidade.
react-server-dom-webpack < 19.2.0, react-server-dom-turbopack < 19.2.0A causa desta vulnerabilidade é a seguinte: no [email protected], a função chave do servidor para analisar Server Actions é requireModule (pseudocódigo):
function requireModule(metadata) {
var moduleExports = __webpack_require__(metadata[0]);
// ...
return "*" === metadata[2]
? moduleExports
: "" === metadata[2]
? moduleExports.__esModule
? moduleExports.default
: moduleExports
: moduleExports[metadata[2]]; // ← Ponto vulnerável
}
O núcleo do problema está na parte moduleExports[metadata[2]], que não valida o metadata[2]. Isso permite que o invasor não apenas acesse as propriedades exportadas pelo próprio módulo, mas também propriedades na cadeia de protótipos (como constructor, __proto__, etc.). Quando o invasor manipula metadata[0] (por exemplo, apontando-o para vm), ele pode então manipular metadata[2] para exportar métodos perigosos de módulos específicos, como vm.runInThisContext, resultando na exploração da vulnerabilidade.
Na minha análise, consultei o ambiente de teste e a exploração fornecidos por ejpir, usando como exemplo o gadget vm_runInThisContext para executar código. O processo é o seguinte (nota: em ambientes reais, o processo de exploração pode ter diferenças!):
Primeiro, após enviar uma solicitação com o payload, defino um ponto de interrupção no local onde a solicitação é recebida:


Em seguida, o programa executa até const formData = parseMultipart(buffer, boundaryMatch[1]);. Entro em parseMultipart

parseMultipart extrai os dados do corpo da solicitação e os retorna para formData

decodeAction (Entrada da Vulnerabilidade)Entro em const actionFn = await decodeAction(formData, serverManifest); Local onde a vulnerabilidade é gerada

Entro em loadServerReference


requireModuleAgora chegamos ao código principal onde a vulnerabilidade é gerada, requireModule. Entro


Retorna o valor id com o # como separador entre módulo e método, e o valor do parâmetro bound como argumento do método




Entro em actionFn e executo o payload final



A exploração da vulnerabilidade está concluída!
Esta vulnerabilidade, em si, ainda é causada por validação insuficiente de entrada, exatamente como Log4j e fastjson. No teste acima, usei vm_runInThisContext, mas na verdade existem múltiplos gadgets exploráveis para esta vulnerabilidade, como:
vm#runInThisContextvm#runInNewContextchild_process#execSyncchild_process#execFileSyncchild_process#spawnSyncfs#readFileSyncfs#writeFileSync#constructor#__proto__#prototypeO invasor pode usar esta vulnerabilidade para conseguir:
vm#runInThisContext ou child_process#execSync para executar comandos arbitrários do sistemafs#readFileSync, fs#writeFileSync para ler/escrever arquivos arbitrários.bashrc, sobrescrever arquivos da aplicação, etc..env, chaves privadas, credenciais de banco de dados, etc.)Com base nisso, podemos fornecer as seguintes medidas de defesa:
Para defesa temporária, podemos considerar os seguintes ângulos: configurar regras de bloqueio para esses campos perigosos no WAF para interceptar ataques maliciosos em tempo hábil. Além disso, também podemos fazer correspondência e bloqueio no Nginx, como abaixo:
# Exemplo de configuração Nginx
location /formaction {
# Bloquear solicitações que contenham referências a módulos perigosos
if ($request_body ~* "(vm#|child_process#|fs#|module#)") {
return 403;
}
# Bloquear tentativas de poluição de protótipo
if ($request_body ~* "(#constructor|#__proto__|#prototype)") {
return 403;
}
}
A equipe oficial já lançou uma atualização de segurança. Atualize imediatamente para a versão segura!:
# Atualizar react-server-dom-webpack
npm install react-server-dom-webpack@>=19.2.0
# Atualizar react-server-dom-turbopack
npm install react-server-dom-turbopack@>=19.2.0
# Usuários do Next.js
npm install next@>=15.0.5
Versões Corrigidas:
react-server-dom-webpack: >= 19.2.0react-server-dom-turbopack: >= 19.2.0next.js: >= 15.0.5Ao analisar a vulnerabilidade acima, consultei o exp relacionado de whiteov3rflow e escrevi uma ferramenta de detecção para a vulnerabilidade no ambiente de teste, que coloquei no repositório do GitHub.
Colegas que precisam se autoavaliar podem acessar para obter (nota: devido ao ambiente de teste do autor original, atualmente pode ser aplicável apenas ao ambiente de teste original. Aguardará melhorias futuras. Colegas que precisarem podem modificar por conta própria...). Lembre-se de usar com autorização legal. Proibido usar para destruição não autorizada!
Até agora, 5 de dezembro de 2025, o que vi online é que o "burburinho" sobre esta vulnerabilidade tem sido como uma montanha-russa: ora "bomba nuclear", ora "buraco d'água", depois novamente "bomba nuclear"... As formas de exploração são cada vez mais variadas. Com base nas informações atuais, a "bomba nuclear" pode se confirmar, mas o escopo de impacto é menor que o do Log4j. No entanto, independentemente disso, todos os envolvidos devem atualizar o mais rápido possível para evitar problemas futuros!!!
Além disso, dou um conselho de segurança aos desenvolvedores: nunca confie na entrada do usuário. Log4j, fastjson e o atual React RCE sucumbiram exatamente por isso. Portanto, no desenvolvimento real de negócios, para posições perigosas, é essencial usar métodos como sandbox ou lista de permissões para validação rigorosa, evitando tragédias!!!
Na teoria é fácil, mas na prática é preciso agir com cautela.