Deux vulnérabilités notées CVSS 9.8 ont été publiées le 12 septembre 2026 sur The Events Calendar, l'un des plugins d'agenda les plus installés de l'écosystème WordPress. Toutes deux permettent une exécution de code arbitraire sans authentification.
| CVE | Versions affectées | Fonction vulnérable |
|---|---|---|
| CVE-2026-78006 | toutes ≤ 6.17.4 | is_safe_widget_instance |
| CVE-2026-78159 | toutes ≤ 6.17.3 | Element_Classes::parse_array |
Vecteur commun : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H.
Ce qui rend ces deux CVE remarquables n'est pas le résultat — une RCE sur un plugin WordPress est hélas ordinaire — mais le chemin employé : l'attaque passe par la zone de commentaires, et la file de modération ne protège pas.
Il existe une mitigation immédiate, gratuite et efficace : désactiver les commentaires sur les événements. J'y reviens en détail plus bas.
La chaîne d'exploitation, étape par étape
C'est la partie qui mérite d'être comprise, parce qu'elle invalide une intuition très répandue.
La description NVD de CVE-2026-78006 est inhabituellement détaillée :
This is exploitable without authentication or approval because the plugin's V2 single-event template runs
do_blocks()over buffered comment HTML, and WordPress returns a moderation-hash URL that allows an unauthenticated commenter to immediately view their own pending comment, delivering the injected block markup to the vulnerable code path before any moderation occurs.
Déroulons :
1. L'attaquant poste un commentaire sur une page d'événement. Le commentaire contient un bloc Gutenberg forgé de type wp:legacy-widget.
2. Le commentaire part en modération. C'est ici que l'intuition défensive habituelle s'applique : « il n'est pas publié, donc il ne peut rien faire ». C'est faux.
3. WordPress renvoie une URL de hachage de modération. C'est une fonctionnalité voulue du cœur de WordPress : pour qu'un visiteur ne croie pas que son commentaire s'est perdu, WordPress lui permet de voir son propre commentaire en attente. Cette URL ne demande aucune authentification.
4. L'attaquant visite cette URL. La page d'événement est rendue, zone de commentaires comprise — avec son commentaire en attente à l'intérieur.
5. Le template V2 du plugin exécute do_blocks() sur le HTML des commentaires mis en tampon. C'est le défaut de conception central : le contenu d'un commentaire, c'est-à-dire une entrée non fiable fournie par un anonyme, est traité comme du balisage de blocs à interpréter.
6. Le bloc forgé atteint le code vulnérable et déclenche l'exécution.
La modération n'intervient jamais dans cette séquence. Le commentaire n'a pas besoin d'être approuvé : il suffit qu'il soit rendu une fois, et WordPress fournit lui-même le moyen de provoquer ce rendu.
Les deux failles du sink
Les deux CVE aboutissent au même endroit par deux chemins différents. Le plugin dispose d'un garde, is_safe_widget_instance(), censé vérifier qu'une instance de widget est sûre avant traitement. Les deux failles le contournent, chacune à sa manière.
CVE-2026-78006 — les méthodes magiques s'exécutent avant la vérification
Due to insufficient protection in
is_safe_widget_instance, which can be bypassed because PHP fires magic methods during its pre-parse, combined withenable_rendering_widget_copied()forging a validwp_hashintegrity attribute beforeunserialize()is reached.
Deux mécanismes se combinent.
D'abord, les méthodes magiques de PHP (__wakeup, __destruct, __toString…) se déclenchent pendant l'analyse préalable, c'est-à-dire avant que le contrôle de sûreté ne rende son verdict. Le garde vérifie un objet dont la simple construction a déjà produit des effets.
Ensuite, enable_rendering_widget_copied() forge un attribut d'intégrité wp_hash valide. Le contrôle d'intégrité qui devait empêcher la désérialisation de contenu non fiable est donc satisfait par une valeur que l'attaquant a fabriquée.
On retrouve le motif de séquencement déjà vu ce mois-ci sur PaperCut et MikroTik : le contrôle existe, mais quelque chose s'exécute avant lui.
CVE-2026-78159 — un tableau simple contourne une vérification d'objet
Due to insufficient validation of the widget 'classes' map, allowing a plain-array payload to bypass the
is_safe_widget_instance()object check and reach the callable-invocation sink inElement_Classes::parse_array().
Ici le contournement est plus direct : le garde vérifie des objets. L'attaquant fournit un tableau simple. Le contrôle ne s'applique tout simplement pas, et la charge atteint parse_array(), qui invoque un appelable — donc exécute du code.
C'est l'erreur de validation classique : un contrôle qui couvre un type de données et laisse passer les autres.
Conditions d'exploitation
Les deux CVE partagent le même prérequis, et c'est là que se trouve votre levier immédiat :
This does require comments to be enabled and visible on events.
Pour CVE-2026-78159, la description est encore plus précise :
Exploitation requires that the targeted site has comments enabled on
tribe_eventsposts and that at least one comment containing a craftedwp:legacy-widgetblock has been submitted.
Autrement dit : un site dont les événements n'acceptent pas de commentaires n'est pas exploitable.
C'est une condition réelle, pas un vœu pieux — et elle est sous votre contrôle immédiat, sans mise à jour et sans interruption.
À noter : beaucoup de sites ont les commentaires activés sur les événements sans le savoir, parce que WordPress applique par défaut le réglage global des articles aux types de contenu personnalisés qui déclarent le support des commentaires. Vérifiez plutôt que de supposer.
Versions
| CVE | Versions affectées |
|---|---|
| CVE-2026-78006 | toutes les versions jusqu'à 6.17.4 incluse |
| CVE-2026-78159 | toutes les versions jusqu'à 6.17.3 incluse |
NVD n'expose pas de numéro de version corrigée. Mets à jour vers la dernière version disponible du plugin et vérifie le journal des modifications de l'éditeur — je ne vais pas affirmer un numéro que NVD ne publie pas.
Vérifier ta version :
wp plugin get the-events-calendar --field=version
# Ou sans WP-CLI
grep -i "Version" wp-content/plugins/the-events-calendar/the-events-calendar.php | head -1
Détection
Commentaires contenant du balisage de blocs
C'est le signal le plus direct — la charge utile est stockée en base :
SELECT comment_ID, comment_post_ID, comment_date, comment_approved,
LEFT(comment_content, 200) AS extrait
FROM wp_comments
WHERE comment_content LIKE '%wp:legacy-widget%'
OR comment_content LIKE '%<!-- wp:%'
ORDER BY comment_date DESC;
Un commentaire contenant wp:legacy-widget n'a aucune raison légitime d'exister. Aucun visiteur n'écrit ça par accident.
Vérifie aussi les commentaires en attente (comment_approved = '0') : la file de modération est précisément l'endroit où la charge se trouve, puisque l'attaque n'a pas besoin d'approbation.
Intégrité des fichiers
# Fichiers PHP modifiés récemment dans wp-content
find wp-content -name "*.php" -newermt "-30 days" -ls
# Comparaison avec les sommes de contrôle officielles du cœur
wp core verify-checksums
wp plugin verify-checksums --all
Comptes et tâches
-- Utilisateurs créés récemment, en particulier administrateurs
SELECT ID, user_login, user_email, user_registered FROM wp_users
ORDER BY user_registered DESC LIMIT 20;
wp cron event list
Journaux serveur
Cherche des requêtes POST vers wp-comments-post.php suivies immédiatement d'un GET vers la même page d'événement avec un paramètre de hachage de modération, depuis la même adresse. C'est la signature exacte de la chaîne.
Mitigation
1. Désactiver les commentaires sur les événements — immédiat
C'est la mesure la plus rentable de cet article : applicable en une minute, sans mise à jour, et elle supprime la condition d'exploitation des deux CVE.
Événements → Réglages → Affichage → décocher l'affichage des commentaires
Ou globalement pour le type de contenu :
// functions.php du thème enfant
add_action( 'init', function () {
remove_post_type_support( 'tribe_events', 'comments' );
}, 100 );
Fermer les commentaires existants sur les événements :
wp post list --post_type=tribe_events --format=ids | \
xargs -d ' ' -I % wp post update % --comment_status=closed
2. Mettre à jour le plugin
C'est le seul correctif complet. Passe à la dernière version disponible.
3. Purger les commentaires suspects
Après vérification, supprime les commentaires contenant du balisage de blocs — y compris ceux en attente, qui sont les plus susceptibles de contenir la charge.
4. Si tu conclus à une compromission
- Redéployer le code depuis une source de confiance plutôt que de nettoyer sur place
- Auditer la base : utilisateurs, options
wp_optionsmodifiées récemment, tâches planifiées - Faire tourner tous les secrets : sels et clés de
wp-config.php, identifiants de base, mots de passe administrateurs, clés d'API des extensions - Forcer la réinitialisation des mots de passe et invalider les sessions
- Vérifier les fichiers hors de
wp-content— une RCE permet d'écrire n'importe où selon les droits du processus web
Pourquoi surveiller en continu vos extensions WordPress
Le cœur de WordPress est solide et se met à jour tout seul. Le risque, sur la quasi-totalité des sites compromis, vient des extensions — et la difficulté n'est pas de les mettre à jour mais de savoir lesquelles sont installées, en quelle version, sur quel site, quand une organisation en exploite plusieurs dizaines gérés par des équipes différentes.
Avec cveo.tech, inventorie tes sites WordPress et leurs extensions avec leur version exacte, et reçois une alerte automatique dès qu'une CVE critique en concerne une — pour agir le jour de la publication, pas le jour de la défiguration.