Rapport CTI technique du 8 août 2026
Résumé exécutif
WordPress a corrigé le 6 août 2026, dans la version 7.0.3, une XSS réfléchie pré-authentification sur l'écran de connexion touchant toutes les versions du CMS depuis la branche 4.7. Référencée CVE-2026-64638 et notée CVSS 8.9, la faille a été découverte par l'équipe pwn.ai à l'aide d'un système de pentest autonome multi-agent, qui a produit une chaîne complète baptisée XSS2Shell menant à l'exécution de code PHP sur le serveur, en s'appuyant sur la recherche SOME (Same Origin Method Execution) publiée par Paulos Yibelo en 2022. Le travail complet, de la découverte à l'exploitation reproduite, a nécessité un peu moins de quatre jours avec des modèles open source.
La XSS elle-même ne requiert ni compte ni interaction de la victime pour s'exécuter dans le navigateur de la cible : il suffit qu'elle clique sur un lien forgé. L'escalade jusqu'à l'exécution de code PHP est en revanche conditionnelle : elle exige qu'un administrateur du site (installation mono-site) clique sur ce lien alors que sa session est active, et que plusieurs capacités WordPress par défaut (Application Passwords activées, unfiltered_html, upload_plugins, stockage de plugins inscriptible) soient réunies. WordPress ne rapporte aucune exploitation active à la date de rédaction. Le délai entre divulgation et exploitation raccourcit néanmoins : Patchstack rapporte que le lot de vulnérabilités corrigé un mois plus tôt dans WordPress 7.0.2 (la chaîne wp2shell) avait été découvert par le modèle GPT-5.6 Sol Ultra en dix heures, pour un coût de recherche d'environ 25 dollars.
Chronologie
| Date | Événement |
|---|---|
| 2022 | Paulos Yibelo publie la technique SOME (Same Origin Method Execution), base technique de l'escalade XSS2Shell |
| 26 juillet 2026 | pwn.ai reproduit la chaîne complète XSS2Shell via son système autonome multi-agent |
| 27 juillet 2026 | pwn.ai transmet la vulnérabilité à WordPress selon un processus de divulgation responsable |
| 6 août 2026 | WordPress publie la version 7.0.3 corrigeant CVE-2026-64638 ainsi que 11 autres vulnérabilités, avec rétroportage jusqu'à la branche 4.7 |
| 7 août 2026 | The Hacker News et Patchstack publient l'analyse technique détaillée de la chaîne |
Fiche vulnérabilité (format fiche CTI)
CVE-2026-64638 | CVSS 8.9 (High) | WordPress Core, toutes versions depuis la branche 4.7 jusqu'à 7.0.2 inclus
Description technique : la faille prend racine dans le traitement du nom d'utilisateur transmis lors d'un échec de connexion. Cette valeur passe par sanitize_user() puis wp_strip_all_tags(), qui s'appuie sur strip_tags() de PHP. Une chaîne ressemblant à une balise, contenant un espace juste après le chevron ouvrant, survit à ce filtrage en tant que texte brut. Plus loin dans le traitement, WordPress fait passer cette même valeur par wp_kses_post(), dont le parseur, distinct du premier, interprète alors ce texte comme du HTML autorisé. Le résultat est l'injection d'éléments DOM arbitraires et actifs sur la page de connexion échouée, qui charge également user-profile.js, un script de gestion de profil normalement absent de ce contexte mais présent car la page gère aussi la réinitialisation de mot de passe. Sur cette page, deux champs de saisie que le script attend sont absents, ce qui fait passer un test d'égalité par défaut, tandis que la variable ajaxurl, normalement non définie ici, peut être écrasée par un élément DOM injecté. Cela détourne une requête REST same-origin générée par le script légitime de WordPress. Les chercheurs exploitent ensuite le support JSONP des API REST de WordPress pour transformer cette requête détournée en exécution JavaScript dans l'origine du site ; pour les déploiements retournant un HTTP 401 aux requêtes REST anonymes, le paramètre _envelope=1 enveloppe le refus dans une réponse HTTP 200, ce qui permet à jQuery de continuer à traiter la réponse comme du script exécutable. Les chercheurs notent qu'une Content Security Policy stricte basée sur un nonce avec strict-dynamic n'a pas bloqué le chemin démontré.
Conditions d'exploitation : la XSS réfléchie elle-même ne nécessite ni compte, ni interaction de la victime au-delà d'un clic sur une URL forgée, et fonctionne sans cookie ni identifiant WordPress préalable (reproduite dans des profils Chrome vierges). L'escalade vers l'exécution PHP est conditionnelle et a été démontrée séparément sur une installation locale WordPress 7.0.2 propre : elle exige qu'un administrateur mono-site clique sur le lien piégé pendant que sa session est active, que les Application Passwords (introduites en WordPress 5.6) soient activées, que le compte administrateur dispose de ses capacités unfiltered_html et upload_plugins habituelles, et que le stockage de plugins soit inscriptible sans durcissement bloquant l'exécution PHP directe depuis un répertoire de plugin inactif.
PoC disponible : oui, technique et méthodologie publiées par pwn.ai (blog XSS2Shell) et relayées avec détail par The Hacker News ; le code d'exploitation complet n'a pas été rendu public.
Patch/mitigation : mise à jour vers WordPress 7.0.3, avec rétroportage du correctif jusqu'à la branche 4.7. Les sites avec mises à jour automatiques activées reçoivent le correctif sans action. Pour les versions antérieures à 4.7, non couvertes par le rétroportage, une mise à niveau complète est nécessaire. La désactivation des Application Passwords casse ce chemin d'escalade spécifique mais ne corrige pas la XSS sous-jacente : seule la mise à jour vers 7.0.3 traite la cause racine.
Diagramme de la chaîne d'attaque

Reconstruction technique établie à partir de la publication The Hacker News du 7 août 2026 et de l'article Patchstack du 6 août 2026.
Analyse technique
Étape 1 : injection DOM via divergence de parseurs sur le nom d'utilisateur
L'attaquant construit une URL de connexion contenant un nom d'utilisateur malveillant. Ce nom passe la première couche de nettoyage (sanitize_user(), wp_strip_all_tags() reposant sur strip_tags()) grâce à une balise contenant un espace après le chevron ouvrant, une astuce de parsing qui fait considérer la chaîne comme du texte inoffensif à ce stade. Plus loin, wp_kses_post(), doté d'un parseur différent, réinterprète la même chaîne comme du HTML légitime et l'injecte dans le DOM de la page d'échec de connexion.
Étape 2 : détournement du script de profil pour forger une requête REST same-origin
La page de connexion échouée charge user-profile.js à cause de la fonctionnalité de réinitialisation de mot de passe. Ce script s'attend à trouver certains champs et variables qui n'existent pas dans ce contexte particulier. L'élément DOM injecté à l'étape précédente exploite cette absence pour faire passer un test d'égalité et pour écraser la variable ajaxurl, orientant ainsi une requête REST que le script légitime émet lui-même vers une destination choisie par l'attaquant, tout en restant dans l'origine du site WordPress.
Étape 3 : transformation de la requête détournée en exécution JavaScript via JSONP
En s'appuyant sur le support JSONP des API REST de WordPress et sur la technique SOME de Yibelo (invocation d'une méthode dans une autre fenêtre du navigateur via une chaîne de propriétés JSONP autorisée), les chercheurs convertissent la requête REST détournée en JavaScript exécuté dans l'origine du site. Le paramètre _envelope=1 permet de contourner les déploiements qui renvoient un HTTP 401 aux requêtes REST anonymes en enveloppant la réponse dans un HTTP 200 exploitable par jQuery.
Étape 4 : abus du contrôle Application Password pour obtenir un identifiant API sans vol de mot de passe
Le script XSS, désormais exécuté dans l'origine WordPress, invoque le contrôle natif d'approbation d'Application Password au sein de la session active de l'administrateur ciblé. WordPress crée alors un identifiant API et redirige vers une URL de succès HTTPS choisie par l'attaquant. Comme les Application Passwords sont des identifiants révocables destinés à l'accès API, cette étape contourne la nécessité de voler le mot de passe principal de l'administrateur.
Étape 5 : upload de plugin et exécution PHP
Avec l'identifiant API obtenu, l'attaquant effectue un accès REST authentifié pour publier une page WordPress contenant du JavaScript same-origin. Lorsque la session administrateur retenue ouvre cette page, le script embarqué récupère le nonce d'upload de plugin et téléverse un fichier ZIP fourni par l'attaquant. Le code PHP contenu peut ensuite être requêté directement depuis le répertoire du plugin extrait, sans que le plugin ait besoin d'être activé, ce qui donne à l'attaquant l'exécution de code sur le serveur avec les privilèges du worker PHP.
Indicateurs de compromission
| Type | Valeur |
|---|---|
| Paramètre de requête suspect | Présence du paramètre _envelope=1 dans des requêtes REST anonymes combinée à des noms d'utilisateur contenant des séquences de type balise avec espace après le chevron ouvrant sur /wp-login.php |
| Artefact serveur | Création inattendue d'une Application Password sur un compte administrateur, sans action explicite de l'administrateur dans l'interface |
| Artefact contenu | Publication d'une page WordPress contenant du JavaScript same-origin non attribuable à un auteur légitime, suivie d'un upload de plugin ZIP inhabituel |
| Artefact fichier | Présence de fichiers PHP exécutables dans un répertoire de plugin jamais activé |
WordPress n'a publié aucun indicateur d'exploitation active à la date de rédaction ; les éléments ci-dessus sont dérivés de la reproduction technique documentée par pwn.ai et The Hacker News.
MITRE ATT&CK
| Tactique | Technique | ID | Justification |
|---|---|---|---|
| Initial Access | Drive-by Compromise | T1189 | Déclenchement de la XSS réfléchie par simple clic de la victime sur une URL forgée, sans autre interaction |
| Execution | Exploitation for Client Execution | T1203 | Exécution du payload JavaScript dans le contexte du navigateur de l'administrateur via la divergence de parseurs HTML |
| Persistence / Privilege Escalation | Valid Accounts: Cloud Accounts | T1078.004 (adapté) | Création d'un identifiant Application Password valide utilisé ensuite pour l'accès API authentifié, sans compromission du mot de passe principal |
| Execution | Server Software Component: Web Shell (adapté) | T1505.003 | Upload d'un plugin contenant du code PHP directement exécutable comme mécanisme d'exécution serveur final |
Cette cartographie est une lecture technique construite à partir de la mêmoire documentée par pwn.ai et The Hacker News. Aucune cartographie ATT&CK officielle n'a été publiée par WordPress ou un fournisseur tiers pour cette CVE à la date de rédaction ; les techniques T1078.004 et T1505.003 sont notées comme adaptations, la première portant sur un jeton API plutôt qu'un compte cloud à proprement parler.
Remédiation : checklist opérationnelle
- Mettre à jour tout site WordPress vers la version 7.0.3 sans délai, en priorité les installations mono-site avec comptes administrateurs actifs.
- Pour les versions antérieures à la branche 4.7, non couvertes par le rétroportage du correctif, planifier une migration complète vers une version supportée.
- Vérifier que les mises à jour automatiques en arrière-plan sont activées sur les sites gérés sans supervision quotidienne.
- Auditer la liste des Application Passwords existantes sur les comptes administrateurs et révoquer celles non reconnues.
- Sur les environnements à forte exigence de durcissement, envisager la désactivation temporaire des Application Passwords en attendant la confirmation du déploiement du correctif sur l'ensemble du parc.
- Restreindre l'inscriptibilité du répertoire de plugins et bloquer l'exécution PHP directe depuis les répertoires de plugins inactifs au niveau du serveur web (règle explicite, indépendante du correctif applicatif).
- Sensibiliser les comptes à privilège administrateur au risque de clic sur des liens non sollicités, y compris ceux semblant pointer vers le propre domaine du site.
- Revoir la Content Security Policy en place : la démonstration confirme qu'une CSP stricte basée sur nonce avec strict-dynamic n'a pas suffi à bloquer ce chemin, ce qui justifie un contrôle compensatoire plutôt qu'une dépendance unique à la CSP.
- Surveiller les logs pour la présence du paramètre _envelope=1 sur des requêtes REST anonymes combinées à des tentatives de connexion échouées contenant des séquences de balises suspectes.