Enquête sur une préprod WordPress piratée pendant l'été
Août 2026. Je reçois des mails de WordPress : le mot de passe de mon compte administrateur vient d'être modifié. Sur un site dont je m'occupe. Et ce n'est pas moi.
Je réinitialise le mot de passe, je me connecte, et j'ouvre la liste des utilisateurs. Une série de comptes administrateurs que personne n'a créés s'y est ajoutée.
Le site en question n'est même pas lancé. C'est une préprod : la version de travail sur laquelle le client valide les pages avant la mise en ligne. Personne ne connaît son existence, à part lui et moi.
Ces comptes et ce mot de passe changé, c'étaient les dégâts. Restait à trouver comment on en était arrivé là. Alors j'ai remonté le fil.
Indice n°1 : les logs de l'hébergeur
Premier réflexe : les journaux du serveur, chez o2switch, l'hébergeur. J'y ai trouvé des requêtes d'injection, et la réponse d'o2switch : l'adresse IP d'où elles venaient avait déjà été bannie. Le site, lui, était resté en ligne.
Une injection, c'est une requête piégée qui fait exécuter ses propres commandes à la base de données. Ça expliquait tout le reste : les comptes admin et le mot de passe modifié avaient été écrits directement dans la base, sans passer par les écrans de WordPress.
Restait à savoir quelle faille l'attaquant avait exploitée.
Indice n°2 : la version de WordPress
La préprod tournait sous WordPress 7, dans une version antérieure à 7.0.2. Or le CERT-FR, l'agence nationale qui publie les alertes de sécurité en France, avait signalé en juillet deux failles du cœur de WordPress touchant exactement ces versions (alerte CERTFR-2026-ALE-007) :
- une injection SQL (CVE-2026-60137) ;
- un contournement de politique de sécurité (CVE-2026-63030).
Combinées, elles permettent d'exécuter du code à distance sans être connecté, en passant par l'API REST de WordPress. Une preuve de concept était publique, et le CERT-FR s'attendait à une exploitation de masse. Le suspect était identifié.
Indice n°3 : une mise à jour qui n'a jamais été faite
La faille était corrigée depuis juillet par la version 7.0.2. Pourquoi ma préprod ne l'avait-elle pas ?
Elle reposait sur Bedrock, une organisation de WordPress courante chez les développeurs, où le cœur est géré comme une dépendance de code. Les mises à jour automatiques y sont désactivées : rien ne bouge sans intervention humaine.
Et l'intervention humaine, c'est moi. Le site attendait les retours du client, et pendant ces phases d'attente, je ne me connecte pas forcément à la préprod. Sauf qu'en été, les retours se font rares : entre les vacances des uns et des autres, la préprod est restée sans activité pendant deux à trois mois. Personne n'y a fait la mise à jour.
Indice n°4 : un site que personne n'était censé connaître
Restait une question qui me gênait. Comment un site absent de Google, lié nulle part, a-t-il été trouvé ?
La préprod tournait sur le nom de domaine définitif du client, acheté pour le projet. Je n'ai pas de preuve, mais deux pistes sont connues. Les listes de domaines fraîchement enregistrés circulent et servent à constituer des listes de cibles. Et chaque certificat HTTPS émis pour un site est inscrit dans des registres publics, consultables par n'importe qui, en quelques minutes. Des robots surveillent ces deux sources en continu : un domaine neuf qui reçoit son certificat, c'est souvent un site en construction, donc moins bien protégé.
Pour ces robots, ne pas être sur Google ne change rien.
Pourquoi les dégâts sont restés limités
L'enquête a aussi montré une bonne nouvelle : les comptes ont été créés, mon mot de passe a été changé, mais personne ne s'est servi de ces accès.
J'installe SecuPress sur tous mes sites, préprods comprises, et je change l'adresse de la page de connexion. Les robots avaient des identifiants administrateur, mais ne savaient pas où les saisir. Et o2switch avait banni leur adresse IP.
Bedrock, qui m'avait joué un tour avec les mises à jour, a probablement aidé dans l'autre sens. Son arborescence ne ressemble pas à celle d'un WordPress classique : le dossier wp-content, que les scripts d'attaque visent par défaut pour déposer leurs fichiers, n'existe pas. Et sa configuration interdit d'installer un plugin ou de modifier du code depuis le back-office, même avec un compte administrateur. La voie habituelle, un faux plugin qui cache une porte dérobée, était fermée. Je n'ai pas de trace prouvant que les robots ont essayé, mais ils n'auraient pas trouvé grand-chose à quoi s'accrocher.
Le ménage a donc été simple : suppression des comptes illégitimes, puis mise à jour du cœur de WordPress. Rien n'a été cassé, et comme le site n'était pas encore public, aucun visiteur ni aucun client n'a rien vu. L'image de mon client est restée intacte.
On a eu de la chance, et un peu de prévoyance. Sur un site en production, avec la page de connexion à son adresse par défaut et sans hébergeur attentif, ces comptes auraient servi. Et ils auraient pu rester actifs des semaines sans que personne ne les remarque.
Ce que l'enquête m'a appris
Ce cas n'est qu'un épisode d'un constat plus large. Sur les sites que je maintiens, je retrouve depuis quelques mois le même ordre de grandeur : une faille est publiée, et environ 48 heures plus tard, les premières tentatives d'exploitation apparaissent dans les logs.
Il y a trois ou quatre ans, on comptait plutôt en semaines. C'était logique : il fallait étudier la faille soi-même, puis écrire le code d'attaque à la main, et ça prenait du temps. Mon intuition, c'est qu'une bonne partie de ce travail est aujourd'hui automatisée.
Une intuition de terrain ne suffit pas. J'ai donc creusé ce que disent les chiffres, et ce que Mozilla et Anthropic ont observé de leur côté. C'est l'objet de la suite de cette enquête, et je peux déjà vous le dire : mon intuition tient.
Ce que je conseille à un propriétaire de site
- Savoir qui applique les mises à jour de sécurité. Sur une installation classique, WordPress installe seul les versions mineures : si quelqu'un a coupé ça « pour éviter les surprises », il faut le réactiver. Sur une installation gérée par un développeur, comme ma préprod, c'est une personne qui s'en charge, et il lui faut une veille et un délai d'intervention.
- Mettre un mot de passe serveur ou un filtrage par adresse IP sur les préprods. Une préprod en attente de validation reste un site en ligne, à mettre à jour comme les autres, et une préprod qui ne sert plus se supprime.
- Déplacer la page de connexion, et lire les mails que WordPress envoie. Sur ma préprod, la page déplacée a rendu l'attaque inoffensive, et c'est un simple mail « votre mot de passe a été modifié » qui m'a alerté. Une alerte à chaque création de compte administrateur complète bien le dispositif.
- Ajouter un pare-feu applicatif. Pour les failles sans correctif, c'est lui qui bloque les requêtes d'attaque en attendant la mise à jour.
- Choisir un hébergeur qui surveille, et garder des sauvegardes externes testées. Deux couches valent mieux qu'une.
Pris un par un, ces gestes sont simples. Ce qui coince, c'est de les tenir dans la durée : une faille critique peut sortir un mardi pendant que vous êtes en rendez-vous client, et le jeudi, les robots sont déjà passés.
Pour aller plus loin, j'ai détaillé les trois failles que je retrouve sur 9 sites repris sur 10 et ce qui casse sur un WordPress sans maintenance.
Si vous préférez ne pas y penser, c'est le travail de ma maintenance WordPress : je suis les failles publiées, j'applique les mises à jour et je vérifie les sauvegardes.