WP-CLI pour constater un piratage sans casser le site
WP-CLI sert à inventorier quand wp-admin est down ou trop lent : users, options, cron, plugins inactifs. Ce n'est pas un nettoyage. Copiez avant toute commande qui écrit. Une ligne `wp db query` malheureuse est irréversible.
Lister users, options, cron, plugins inactifs. Utile quand l'admin est inaccessible. Ce n'est pas un nettoyage : c'est un inventaire. Copiez avant toute commande destructive.
À quoi WP-CLI sert pendant un incident
wp-admin redirige, un plugin de maintenance vous lock, l'admin est trop lourd, ou vous ne voulez pas exécuter le front (et donc le malware au chargement). WP-CLI parle à la base et aux fichiers en CLI, sans navigateur. `wp user list`, `wp plugin list`, `wp cron event list`, `wp option get siteurl` : vous dressez l'état. Vous ne « réparez » pas.
Beaucoup de tutos enchaînent `wp plugin delete` et `wp db query DELETE`. C'est ainsi qu'on perd la preuve et qu'on casse WooCommerce. Ici, l'ordre est : archive du compte, inventaire CLI, décisions, puis éventuellement des commandes d'écriture ciblées.
Si vous n'avez pas SSH, l'hébergeur a parfois « WP-CLI » dans le panel, ou fournit une archive. N'installez pas un plugin « WP-CLI » douteux depuis wp-admin pour contourner : vous ajoutez de la surface.
Prérequis : SSH, user, et copie d'abord
SSH ou terminal de l'hébergeur, PHP CLI, WP-CLI installé (souvent `wp` déjà dans le PATH chez o2switch, Kinsta, certains VPS). Identifiez-vous comme le user du site, pas root qui écrit des fichiers en root et casse le FTP ensuite.
Copie : fichiers + dump SQL hors machine. `wp db export ~/backup-incident.sql` est commode — stockez-le hors du web. Sans cette copie, n'enchaînez pas les `update`. Voir premiers gestes.
Évitez `wp cron event run` et les hits front : vous exécutez la file. Lisez, n'exécutez pas. Même esprit que pour wp-cron malware.
- `wp db export` hors web, horodaté.
- `wp --info` pour confirmer le bon site.
- Pas de `eval` / `run` sur des hooks inconnus.
Inventaire users, rôles, sessions
`wp user list --fields=ID,user_login,user_email,roles,user_registered` donne la photo. Filtrez les rôles `administrator`. Exportez `--format=csv`. Pour un user : `wp user get <id>` et `wp user meta list <id>` (capabilities, application passwords selon versions / commandes dispo).
`wp user session list` / `destroy` existent selon la version. Sinon, régénérer les clés AUTH dans `wp-config` reste le levier. Ne détruisez les sessions qu'une fois l'inventaire sauvé et le panel déjà tourné.
Un pic d'users à une date : croisez avec API REST et rôle élevé. La CLI constate ; elle n'explique pas le canal.
Plugins, mu-plugins, thèmes
`wp plugin list` (actifs / inactifs). Un inactif n'est pas inoffensif s'il reste lisible et qu'un include l'appelle, mais c'est déjà un tri. `wp plugin get` pour le chemin. Les mu-plugins n'apparaissent pas toujours comme les autres : listez `wp-content/mu-plugins` en `ls`. `wp theme list` et le thème stylesheet actif (`wp option get stylesheet`).
Ne faites pas `wp plugin delete --all` « pour voir ». Vous perdez WooCommerce, licences, et la trace. Désactiver un seul suspect (`wp plugin deactivate slug`) après copie peut aider à tester ; notez-le.
Options, cron, transients
`wp option get siteurl` `home` `active_plugins` `template` `stylesheet`. `wp option list --search='*widget*' --format=count` pour jauger. `wp cron event list`. `wp transient list` peut être énorme : ne flush pas encore.
Pour une option suspecte : `wp option get nom --format=json` redirigé vers un fichier hors web. Lisez. N'updatez pas à la volée une valeur sérialisée. Voir base injectée.
Chercher dans la base sans la réécrire
`wp db search '<script' --all-tables` (charge le serveur : préférez horaires calmes, ou cherchez sur le dump local). Autres motifs : un domaine inconnu, `eval(`, `base64_decode`. Exportez les hits. `wp db query` en `SELECT` seulement tant que vous constatez.
Un `DELETE FROM wp_posts WHERE ...` recopié d'un forum retire parfois des commandes WooCommerce mal typées, ou des pages légitimes. Pas de DELETE sans `SELECT` préalable et export.
Commandes qui cassent si on les lance trop tôt
`wp cache flush` : utile APRÈS correctif, trompeur avant (vous croyez avoir « enlevé » ce qui revient de la source). `wp rewrite flush` : rarement lié au malware, casse les permaliens si les règles étaient le symptôme. `wp core download --force` : remet le cœur, laisse mu-plugins et base. `wp db reset` : arme nucléaire, interdit sans dump et sans décision métier (boutique).
`wp eval-file` sur un PHP trouvé « pour voir ce qu'il fait » : vous exécutez le malware. Lisez, ne lancez pas.
Ce que WP-CLI ne voit pas
Les fichiers hors WordPress (voisin, `/old`, un PHP à la racine hors chargement WP). Le cron système. Les journaux d'envoi SMTP de l'hébergeur. Les webhooks chez Stripe. Les users FTP. WP-CLI est un œil sur le CMS, pas sur le compte. Complétez avec le panel et les logs. Voisin de serveur.
Un site trop cassé (wp-config illisible, autoload fatal) fait échouer `wp`. Là, dump SQL + fichiers, pas la CLI.
Passer la main avec un inventaire lisible
Joignez à un prestataire : CSV users, liste plugins, extraits d'options, `cron event list`, date de l'export. C'est plus utile qu'un « je crois qu'on est piratés ». Vous pouvez créer un espace et coller cet inventaire sans livrer SSH tout de suite.
Critère pour continuer seul : vous comprenez chaque commande que vous lancez et vous avez un dump de la minute d'avant. Sinon, arrêtez-vous à l'inventaire lecture.
- Export DB + CSV users + plugin list.
- Aucune commande destructive sans copie.
- Cron lu, pas exécuté.
- Panel / FTP / SMTP encore à traiter hors CLI.