XSS stockée : comment elle devient un piratage de site
Un commentaire ou un champ qui exécute du JavaScript vole une session administrateur. Ensuite, le reste est banal : plugin, redirection, admin créé. Nettoyez le stockage, pas seulement le cookie — sinon le prochain admin qui ouvre la page redonne les clés.
Un commentaire ou un champ qui exécute du JS vole une session admin. Ensuite, le reste est banal. Nettoyez le stockage, pas seulement le cookie.
De la boîte commentaire au site pris
L'administrateur ouvre une page (commentaire en attente, avis produit, champ « HTML personnalisé »). Le navigateur exécute un script déjà enregistré en base ou en fichier. Le cookie de session part, ou une action se lance dans le contexte admin (création d'utilisateur, option changée). Vous n'avez pas « cliqué un lien louche » : vous avez fait votre métier. C'est pour ça que ça passe.
On ne décrit pas comment écrire le script. On décrit où le chercher et comment l'ôter, puis comment tuer les sessions. La XSS stockée n'est pas une injection SQL : l'une s'exécute chez le visiteur / l'admin, l'autre parle à la base. Elles s'enchaînent parfois.
Un simple spam de commentaire *texte* n'est pas une XSS. Le critère : est-ce que ça *s'exécute* ?
Où le script reste stocké
Commentaires, avis, biographies, widgets, champs ACF / builders, pages « HTML », signatures forum, noms de fichiers média, options SEO. Moins souvent : un fichier JS du thème déjà modifié (là, c'est plutôt une backdoor classique). La XSS stockée, elle, survit dans le *contenu*.
Un scan antivirus de fichiers la rate presque toujours. Il faut l'admin *ou* une copie de base, avec prudence (ne pas ouvrir les extraits dans un navigateur de travail).
Les extraits « vus par Google » dans Search Console peuvent montrer un script que votre cache admin masque. Gardez le HTML. Preuve utile, pas un tutoriel.
- Files de modération et avis.
- Widgets / HTML / builders.
- Options et SEO globaux.
Ce que vous voyez, concrètement
Redirection dès que vous ouvrez « Commentaires ». Console navigateur qui parle d'un domaine inconnu. Un admin créé après que *vous* soyez allé dans une page. Un pixel posé sans vos mains. La home visiteurs propre, l'admin piégé : classique.
Les clients ne voient parfois rien (le script cible `wp-admin` ou un referer). D'autres fois, tout le monde exécute (skimmer, redirect mobile). Testez les deux contextes.
Un bloqueur de scripts chez vous n'est pas un diagnostic. L'attaquant compte sur l'admin *sans* bloqueur.
Sessions : nécessaires, insuffisantes
Dès suspicion : invalider toutes les sessions, régénérer les sels CMS, cookies. Puis 2FA. Si le stockage n'est pas nettoyé, vous vous reconnectez, vous rouvrez « Commentaires », vous redonnez le cookie. Le reset de session seul est un cercle.
Les application passwords et les clés : révisez, le script a pu en créer. Révoquer.
Un mot de passe admin changé *sans* session tuée : théâtre déjà vu.
Nettoyer le stockage sans tout casser
Identifiez le type de contenu, copiez un extrait (preuve, hors navigateur), retirez ou neutralisez *ce* champ, pas toute la table commentaires de dix ans au jugé. Les plugins « delete all spam » aident parfois ; ils ratent un widget HTML. Passez les zones riches une par une.
Si le script est dans un article légitime injecté, éditez ou restaurez *cette* révision. Ne videz pas `wp_posts`.
Caches : purgez après, sinon l'admin recroise le HTML mort-vivant et vous croyez à une réinfection fichiers.
Champs riches, builders, avis produits
Elementor, WPBakery, blocs HTML Gutenberg, avis WooCommerce : surfaces larges, souvent mal filtrées par des add-ons vieux. MAJ ou retrait de l'add-on, pas seulement suppression de l'avis visible.
Les forums et guestbooks d'un autre âge : fermez les commentaires anonymes le temps du chantier. Ce n'est pas une stratégie éditoriale définitive ; c'est une isolation.
Un champ « tracing code » marketing est un aimant. Inventaire, comme pour les pixels.
Ce que ça change pour les données
Vol de session admin = accès au fichier clients *possible*. Skimmer JS = paiement. Replay = saisies. Le constat suit les effets, pas le mot « XSS ». Fuite si le risque est là.
Les visiteurs qui n'ont fait qu'afficher une page avec un script pub pirate : plutôt le dossier pixel. Ceux qui ont saisi une carte : autre gravité.
N'écrivez pas « ce n'est que du JavaScript, pas une fuite ». Le JavaScript *est* souvent le tuyau.
Empêcher que ça se repose
Fermer l'entrée (plugin commentaire / avis / formulaire). Modération. Moins de HTML libre pour les non-admins. MAJ. Une backdoor peut réécrire le champ : chasse fichiers en parallèle si d'autres signes.
CSP à froid, si vous savez. Un copier-coller le soir casse le checkout. Pas obligatoire pour une TPE le jour J ; le stockage propre, si.
Créer un compte si l'admin est injouable (chaque clic réexécute). Décrivez « dès que j'ouvre telle page ». C'est le diagnostic.
- Ne plus ouvrir la page piège en admin.
- Oter le stockage, puis sessions.
- Patch du composant qui acceptait le HTML.