Aller directement au contenu principalAller directement au pied de page
Actualités sur la sécurité

wp2shell : une vulnérabilité RCE non authentifiée dans WordPress et comment la bloquer

Mise à jour Patrick Schlesinger
Schéma de la chaîne d'attaque WordPress « wp2shell » bloquée par le pare-feu ReportedIP

wp2shell est une chaîne d'exécution de code à distance sans authentification présente dans le cœur de WordPress. Elle combine une injection SQL (CVE-2026-60137) avec une faille de confusion de routes REST par lots (CVE-2026-63030) et ne nécessite ni connexion ni plugin tiers. Les sites utilisant ReportedIP sont déjà protégés : les règles sont actives dans la configuration de base fournie et publiées via l’API des règles ; ainsi, les installations gratuites et synchronisées bloquent dès aujourd’hui ce type de requête.

Commencez par appliquer le correctif au cœur de WordPress afin de passer à la version corrigée. Cela permet d’éliminer la cause première du problème. Un pare-feu protège vos sites jusqu’à ce que tous ceux de votre parc soient mis à jour et bloque les variantes, mais il ne remplace pas le correctif du cœur. Si vous utilisez Hive, mettez-le également à jour vers la version 2.1.25, car les deux nouvelles règles sont incluses dans la version de base gratuite. Le guide du plugin contient les étapes d’installation et de mise à jour, et la dernière version est disponible sur la page des versions de GitHub.

Les deux bogues, et pourquoi la chaîne est importante

Aucun de ces deux bogues n'est en soi critique. Mais lorsqu'ils sont combinés, ils permettent à une requête anonyme d'aboutir à l'exécution de code.

  • CVE-2026-60137 (injection SQL, CVSS 9,1). Le REST author_exclude Le paramètre est mappé vers le author__not_in variable de requête dans WP_Query et interpolée sous forme de chaîne dans un post_author NOT IN (…) clause. Une valeur telle que 0) UNION SELECT …-- - ferme le IN() liste et ajoute du code SQL arbitraire. En soi, cette fonctionnalité n'est accessible qu'à partir d'une requête de collecte authentifiée.
  • CVE-2026-63030 (confusion de routes dans le traitement par lots REST). Dans /wp-json/batch/v1, une sous-requête dont le chemin d'accès échoue wp_parse_url() est joint au fichier interne $validation figurer sur la liste, mais pas pour $matches. Les deux tableaux ne sont plus synchronisés, et une sous-requête validée est traitée par le gestionnaire de la sous-requête suivante. Cela permet à une GET /wp/v2/posts/999999 transport author_exclude publié dans la collection « Posts » get_items(), où se trouve la variable de requête injectable, sans authentification.

Cette escalade par lots concerne WordPress 6.9 et les versions ultérieures, qui intègrent la gestion de la confusion d'itinéraire.

D'une attaque SQLi « à l'aveugle » à un shell

Dès que l'injection atteint une requête non fractionnée (l'exploit utilise orderby=none et per_page=500 (de sorte que la ligne subsiste sous la forme d'un faux message), il crée une colonne complète de 23 colonnes wp_posts ligne avec UNION SELECT et transmet la valeur divulguée dans le reflet post_title. De là, la chaîne en génère trois oembed_cache il publie des articles, récupère leurs identifiants via la même injection, transforme ces identifiants en un ensemble de modifications pour le personnalisateur et en un graphe d'éléments de menu de navigation, puis crée un nouvel administrateur via la route REST dédiée aux utilisateurs. Une fois l'administrateur en main, le téléchargement d'un plugin ou d'un thème permet l'exécution de code. Aucun identifiant n'est requis à aucune étape.

Comment ReportedIP le bloque

Les hooks du pare-feu Hive init avec une priorité 1, et la session facultative commence encore plus tôt via un auto_prepend_file de sécurité, avant le démarrage de WordPress. Pour une requête non authentifiée, il analyse l'URI, l'agent utilisateur et le corps de la requête jusqu'à 64 Ko. Depuis la version 2.1.25, il analyse le corps à la fois sous sa forme brute et après décodage d'URL ; ainsi, une charge utile encodée en pourcentage à l'intérieur d'un lot JSON (SLEEP%283%29 au lieu de SLEEP() est visible pour les mêmes signatures. Le présentation du pare-feu aborde le moteur de manière plus approfondie.

La procédure de création d'un administrateur dépend de UNION SELECT, que la version gratuite waf_sqli_union règle déjà bloquée avant cette version. La version 2.1.25 ajoute deux règles structurelles qui ne dépendent pas de la présence des mots-clés SQL dans le corps de la requête.

  • waf_rest_batch_desync correspond à la catégorie des chemins de sous-requêtes mal formés rejetés par un analyseur par lots, tels que deux barres obliques ou plus en début de chemin, ou un schéma avec un hôte vide. Il cible directement le « desync primer » lui-même ; par conséquent, modifier le jeton ne permet pas de le contourner.
  • waf_rest_batch_nested correspond à l'invariant que l'attaque ne peut pas supprimer, à savoir une sous-requête dont le corps est lui-même un lot ("body":{…"requests":[).

Ces deux règles sont de niveau 1 selon l'échelle de Paranoia et sont toutes deux protégées contre les retours en arrière catastrophiques. Elles sont fournies dans la base de référence hors ligne incluse dans chaque installation ; la protection est donc active dès la mise à jour du plugin, sans qu'aucune synchronisation des règles ne soit nécessaire. Pour les sites « Professional », ces mêmes règles sont publiées sur l’API du jeu de règles signé et sont disponibles dès la synchronisation suivante. Lors du test de validité public, les six étapes ont toutes été rejetées sur les niveaux « Free » et « Professional », et un corpus de faux positifs composé d’appels par lots normaux, d’URL relatives au protocole et d’URL absolues n’a présenté aucun problème.

Que faire maintenant ?

Mettez à jour le cœur de WordPress sur l'ensemble de vos sites. Mettez à jour ReportedIP vers la version 2.1.25 depuis la section « Plugins », ou cliquez sur « Vérifier les mises à jour » pour le télécharger immédiatement. Les sites gratuits et non synchronisés reçoivent les deux règles lors de la mise à jour du plugin. Les sites Professional synchronisés les reçoivent lors de la prochaine synchronisation des règles, ou instantanément en cliquant sur « Synchroniser maintenant ». Si vous gérez de nombreux sites, appliquez d'abord le correctif du cœur de WordPress et laissez le pare-feu assurer la protection pendant sa propagation.

Foire aux questions

ReportedIP plugin ReportedIP remplace-t-il la mise à jour du cœur de WordPress ?

Non. C'est le correctif du noyau qui résout le problème. Hive bloque le modèle de requête en amont du code vulnérable, ce qui protège la fenêtre de correction et détecte les variantes, mais cela ne supprime pas le bogue sous-jacent.

Les sites gratuits sont-ils protégés contre wp2shell ?

Oui. Ces deux nouvelles règles sont de niveau « Paranoia 1 » et sont incluses dans la configuration de base, elles s'appliquent donc à toutes les formules dès que le plugin passe à la version 2.1.25.

Les nouvelles règles vont-elles bloquer les requêtes REST par lots légitimes ?

Non. Ils ciblent les chemins de sous-requêtes mal formés et un lot imbriqué dans le corps d'une sous-requête. Les appels de lots normaux ne produisent pas ce type de structure, ce que le corpus de faux positifs a confirmé.

Les jours qui ont entouré la divulgation apparaissent dans nos données de télémétrie : les tentatives d'accès aux points de terminaison REST par lots ont augmenté à la mi-juillet. Le rapport sur les attaques WordPress pour la période mai-juillet 2026 replace wp2shell dans son contexte, aux côtés de 1,69 million d'autres attaques, et la plateforme « Threat Reports » assure le suivi de ces données chaque trimestre.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont marqués d'un *

Remplissez ce champ
Remplissez ce champ
Veuillez saisir une adresse e-mail valide.
Vous devez accepter les conditions pour continuer