CVE-2026-85575
CVSS 6.4 · Moyenne CorrigéCVE-2026-85575 : XSS stocké dans ShopEngine via la balise de titre produit
Notre PoC Author a confirmé l’XSS stockée dans ShopEngine 4.8.9, de la sauvegarde Elementor à l’exécution dans un navigateur visiteur.
Pour décider
- Impact
- Un réglage de widget peut stocker du JavaScript exécuté lors de la consultation d’une page.
- Conditions
- Notre reproduction utilise un compte Author sur ShopEngine 4.8.9. Wordfence publie une portée Contributor+.
- Action recommandée
- Mettre ShopEngine à jour en 4.9.6 ou au-delà et examiner les contenus modifiables par les rôles concernés.
Fiche de l’avis
- Paquet
- wordpress · shopengine
- Versions affectées
- ≤ 4.9.5
- Corrigé dans
- 4.9.6
- CVSS
- 6.4 Moyenne
- Faiblesse
- CWE-79
- Accès requis
- Compte requis
- Avis publié
- Crédit
- rootzero
Synthèse de l’enquête
Le widget Product Title imprimait shopengine_product_title_header_size sans liste blanche. Notre essai sur ShopEngine 4.8.9 démontre la sauvegarde par un compte Author et l’exécution dans un navigateur visiteur ; Wordfence décrit une portée Contributor+. Corrigé dans ShopEngine 4.9.6.
Du widget au navigateur visiteur
Dans notre recherche sur les extensions Elementor, nous suivions les réglages title_tag, header_size et leurs équivalents : une liste de balises proposée dans l’éditeur ne suffit pas si le serveur imprime la valeur sauvegardée comme un nom de balise. ShopEngine entrait dans cette série. Le widget Product Title reprenait shopengine_product_title_header_size sans liste blanche, alors que le widget Archive Title voisin validait sa balise. Nous avons choisi cette différence comme contrôle, puis préparé un vrai produit WooCommerce et le contexte dont le widget avait besoin.
Le 31 mai 2026, nous sommes passés de cette comparaison du code à un essai complet : un compte Author a stocké le widget forgé, la page l’a rendu et un navigateur visiteur non authentifié l’a exécuté. Les contrôles séparés et le montage WooCommerce sont détaillés plus bas. Notre signalement Wordfence du 1er juin est devenu le ticket 456374. ShopEngine a publié 4.9.6 le 13 septembre et l’avis CVE-2026-85575 a suivi le 15. Wordfence décrit une portée Contributor+ ; le rejeu conservé établit Author.
Le montage nécessaire pour faire rendre le widget
L’écart dans le code était précis : Product Title prenait shopengine_product_title_header_size comme nom de balise HTML, tandis que le widget Archive Title voisin passait sa balise par Helper::esc_options(). Ce voisin était notre contrôle négatif. L’éditeur ne proposait qu’un menu de valeurs sûres, mais le rendu serveur de Product Title n’en imposait pas les options.
Un payload trouvé dans le code aurait donné un rapport fragile. Product Title a besoin d’un vrai produit WooCommerce et d’un contexte ShopEngine pour s’afficher ; nous avons donc créé ces prérequis avec un compte administrateur dans le laboratoire. L’étape d’attaque était distincte : un compte Author neuf a créé un article publié et enregistré un JSON Elementor forgé via l’API REST de WordPress. Nous avons relu cet article avec la même session Author et retrouvé le marqueur dans _elementor_data. Dans le HTML rendu côté serveur, il devenait une balise <img> avec gestionnaire onerror. Enfin, Playwright a ouvert l’URL publique dans un nouveau contexte navigateur sans cookie WordPress : window.__SHOPENGINE_PT_POC valait 4809 et un élément image correspondant était présent. Les vérifications du stockage, du HTML et du navigateur écartaient trois faux positifs différents.
Ce laboratoire prouve le chemin Author sur ShopEngine 4.8.9, Elementor 4.1.1 et WooCommerce. L’avis Wordfence publié ensuite indique une portée Contributor+. Nous pouvons citer cette évaluation, mais le rejeu navigateur conservé n’établit pas indépendamment une sauvegarde par Contributor.
Cause racine
La vulnérabilité est un cross-site scripting stocké (CWE-79). La balise de titre est une entrée choisie par l’attaquant que le widget écrit dans le balisage de la page rendue, et l’extension ne la restreignait pas à une liste blanche de balises de titre avant de le faire. La forme est celle que partage toute cette famille :
Author dans notre essai → fixe shopengine_product_title_header_size à une valeur forgée (hors h1..h6)
Sauvegarde REST des données Elementor → stocke la valeur, le menu déroulant côté client est contourné
widget de titre produit → imprime la valeur à la position de balise, sans liste blanche
visiteur / éditeur → le navigateur interprète un élément contrôlé par l’attaquant
Comme la valeur est écrite là où va un nom de balise, un payload n’a pas besoin de ses propres chevrons : une valeur comme img src=x onerror=alert(document.domain) devient un vrai élément <img> avec un gestionnaire d’événement une fois que l’extension l’émet après un <. Les filtres de sortie de WordPress qui retirent le balisage dangereux n’aident pas ici, car au moment de l’enregistrement la valeur ne contient aucun balisage à retirer.
Exploitation
La fiche Wordfence indique le rôle Contributeur ou supérieur, à condition que le compte puisse modifier une page contenant ce widget. En modifiant le réglage Elementor enregistré, l’attaquant fixe shopengine_product_title_header_size à un payload au lieu d’une balise de titre :
shopengine_product_title_header_size = img src=x onerror=alert(document.domain)
La valeur est stockée avec la page. Le payload s’exécute lorsqu’une personne ouvre une page qui affiche le widget concerné, par exemple un éditeur qui prévisualise le travail d’un Contributor. Dans le navigateur d’un administrateur, les conséquences peuvent dépasser cette page si le script accède aux actions privilégiées et aux nonces nécessaires ; cet article ne démontre pas une prise de contrôle complète du site.
Impact
Le score CVSS 3.1 est de 6,4, vecteur AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N : la faille est accessible par le réseau avec un compte peu privilégié. La frontière est concrète : un Contributeur ne possède pas unfiltered_html et ne peut pas publier son propre article, mais l’aperçu ouvert par un Éditeur peut exécuter le payload enregistré.
Correctif
ShopEngine 4.9.6, publié le 13 septembre 2026, corrige le problème signalé. Son journal des modifications indique : « Fixed: Stored Cross-Site Scripting (XSS) vulnerability in the Product-Title-widget. » Cette mention établit la version corrigée, mais ne démontre pas à elle seule le contrôle exact ajouté par le patch. Les notes de la version 4.9.7 décrivent un durcissement plus large du titre de produit dans la même zone.
Détection et mitigation
- Mettre à jour ShopEngine vers la 4.9.6 ou une version ultérieure pour le problème signalé ; préférer la dernière version maintenue.
- Passer en revue les comptes Contributeur ou supérieurs pouvant modifier des pages qui utilisent ce widget, et retirer les accès inutiles.
- Pour la détection, inspecter les données Elementor enregistrées à la recherche de
shopengine_product_title_header_size(et des réglages de balise voisins) contenant autre chose queh1àh6oudiv/span. Une valeur contenant=, une espace ousrcmérite une analyse ; elle ne prouve pas seule une exploitation. - La règle générale pour cette famille d’extensions : une balise choisie dans un constructeur de pages est une entrée utilisateur, et elle doit être vérifiée contre une liste blanche côté serveur, jamais acceptée parce que l’éditeur n’offrait que des options sûres.
Chronologie
| Date | Événement |
|---|---|
| 31/05/2026 | Preuve locale sur ShopEngine 4.8.9 : stockage Author, rendu HTML, exécution dans un navigateur visiteur |
| 01/06/2026 | Signalement Wordfence, ticket 456374 |
| 13/09/2026 | Publication de ShopEngine 4.9.6 avec le correctif |
| 15/09/2026 | Publication de CVE-2026-85575, qui crédite notre chercheur |
Références
- Avis de l’éditeur · CVE-2026-85575 www.wordfence.com/threat-intel/vulnerabilities/id/acd7b1b5-9618-4e8a-b320-bb65978d2c92?source=cve
- Fiche NVD · CVE-2026-85575 nvd.nist.gov/vuln/detail/CVE-2026-85575
- Fiche CVE.org · CVE-2026-85575 www.cve.org/CVERecord?id=CVE-2026-85575
- MITRE CWE-79 cwe.mitre.org/data/definitions/79.html
- Dépôt du projet plugins.trac.wordpress.org/browser/shopengine
Citer cet avis
rootzero. « CVE-2026-85575 : XSS stocké dans ShopEngine via la balise de titre produit ». Recherche de vulnérabilités, rootzero, 15 septembre 2026. https://rootzero.eu/research/cve/cve-2026-85575-shopengine-stored-xss/
#Recherche de vulnérabilités
Faites auditer votre code avant qu’un autre ne le fasse.
Votre équipe doit décider quoi corriger avant une livraison ou évaluer une dépendance critique. Nous définissons une mission autour de cette décision, avec des preuves et des priorités de correction expliquées.