Credit : Logo officiel
Vérifier l'intégrité des fichiers WordPress avec WP-CLI
Verifier l'integrite des fichiers WordPress avec WP-CLI
Mardi matin, ticket urgent : un client nous remonte que son site WordPress 6.4 redirige aleatoirement vers des pages de pari en ligne. Pas tout le temps, juste pour les visiteurs venant de Google. Le client jure qu'il a rien fait, qu'il a aucun plugin louche. Classique. Connexion SSH, je lance wp core verify-checksums --include-root et bingo : trois fichiers du core ont ete modifies, dont wp-blog-header.php qui contient une injection JavaScript conditionnelle. En 15 minutes le site est nettoye et secrete restaurees. Sans WP-CLI, j'aurais mis 2 heures en parcourant les fichiers a la main.
Quand un client nous contacte parce que son site redirige vers du phishing, affiche du contenu pharmaceutique, ou que Google Search Console signale du malware, la premiere chose qu'on fait c'est verifier l'integrite des fichiers. WP-CLI est indispensable pour ca. La doc officielle est correcte mais incomplete sur les vrais cas reels. Je te donne ma methode complete, celle que j'utilise des dizaines de fois par mois.
Pourquoi verifier l'integrite ?
Un site WordPress hacke, c'est rarement evident. Les attaquants modernes savent etre discrets : injection conditionnelle (uniquement pour Googlebot ou certains user-agents), backdoors dormantes activees a distance, redirections geo-localisees. Le client peut passer des semaines sans rien voir, jusqu'a ce que Google deindexe son site ou que Chrome affiche un avertissement de securite.
La verification d'integrite compare les fichiers de ton installation avec les versions officielles. Tout fichier modifie ou ajoute est suspect. C'est la base de la detection.
Verifier le core WordPress
wp core verify-checksums --include-root
Cette commande compare chaque fichier du core avec les checksums officiels publies par wordpress.org pour ta version exacte. L'option --include-root est cruciale : elle inclut les fichiers a la racine comme index.php, wp-login.php, xmlrpc.php, wp-blog-header.php. Sans cette option, ces fichiers sont skip et c'est justement la qu'on trouve souvent les injections.
Une sortie propre ressemble a :
Success: WordPress installation verifies against checksums.
Une sortie qui doit te faire dresser l'oreille :
Warning: File doesn't verify against checksum: wp-blog-header.php
Warning: File doesn't verify against checksum: wp-includes/vars.php
Warning: File should not exist: wp-content/wp-cache.php
Error: WordPress installation doesn't verify against checksums.
Le should not exist est encore pire que le doesn't verify : c'est un fichier qui n'existe pas dans WordPress officiel mais que quelqu'un a ajoute. Quasi systematiquement une backdoor.
Verifier tous les plugins
wp plugin verify-checksums --all
Meme principe pour tous les plugins du repository officiel. WP-CLI compare chaque fichier avec les checksums publies par chaque auteur de plugin sur wordpress.org. Les plugins premium (Elementor Pro, WPBakery, ACF Pro, WP Rocket, etc.) ne sont pas verifiables car ils n'ont pas de checksums publics.
Pour tester un plugin specifique :
wp plugin verify-checksums woocommerce
Si WooCommerce remonte des fichiers modifies, c'est generalement soit une attaque, soit un developpeur qui a edite directement les fichiers du plugin (interdit, ca saute a chaque mise a jour).
Verifier les themes
La commande pour les themes est plus recente :
wp theme verify-checksums --all
Meme regle : seuls les themes du repo officiel sont verifiables. Les themes premium achetes sur ThemeForest ou ailleurs n'ont pas de checksums.
Trouver des fichiers PHP suspects dans uploads
C'est LE red flag numero 1 du WordPress hacke. Il ne devrait jamais y avoir de fichiers PHP executables dans wp-content/uploads/ :
find /home/htdocs/wp-content/uploads -name '*.php' -type f
Sur les serveurs IONOS, on tombe regulierement sur des webshells planques dans des sous-dossiers du type wp-content/uploads/2024/03/cache.php ou wp-content/uploads/rev-slider/shell.php. Les attaquants utilisent des noms qui semblent legitimes pour passer inapercus dans une revue manuelle.
Variante plus exhaustive avec toutes les extensions executables :
find /home/htdocs/wp-content/uploads -type f \( -name '*.php' -o -name '*.php5' -o -name '*.phtml' -o -name '*.phar' -o -name '*.shtml' -o -name '*.pht' -o -name '*.phps' \)
N'oublie pas non plus wp-content/cache/ et wp-content/upgrade/, deux autres planques courantes.
Detecter les backdoors par signature
Les webshells utilisent souvent des fonctions PHP caracteristiques. On peut grep les signatures les plus courantes :
grep -rEn "(eval\(base64_decode|eval\(gzinflate|FilesMan|c99shell|r57shell|str_rot13\(base64)" /home/htdocs/wp-content/ --include="*.php"
Ca remonte les fichiers qui contiennent du code obfusque typique des shells. Attention, ca peut donner des faux positifs (certains plugins legitimes utilisent base64 pour des raisons valables), mais c'est un excellent point de depart.
Autre commande utile pour les fichiers modifies recemment :
find /home/htdocs -type f -name "*.php" -mtime -7
Tous les fichiers PHP modifies dans les 7 derniers jours. Si tu n'as fait aucune mise a jour, tout ce qui apparait est suspect.
Detecter les binaires ELF
Un truc que peu de gens connaissent : certains malwares deposent des binaires Linux compiles directement dans l'arborescence WordPress, generalement pour faire du minage de crypto ou des DDoS sortantes :
find /home/htdocs -type f -exec file {} \; | grep -E "ELF|executable"
La commande file analyse le type reel du fichier (pas son extension). Si tu trouves un binaire ELF dans un dossier WordPress, c'est du malware a 99.9%. Supprime-le immediatement et change tous les mots de passe sans attendre.
Reinstaller proprement le core
Si verify-checksums revele des modifications du core :
wp core download --force --skip-content
Le --skip-content est crucial : ca reinstalle le core sans toucher a wp-content (themes, plugins, uploads). Le --force ecrase les fichiers existants par les versions officielles.
Apres ca, tu peux relancer la verif pour confirmer :
wp core verify-checksums --include-root
Reinstaller les plugins en masse
Si plusieurs plugins ont des modifications :
wp plugin install --force $(wp plugin list --field=name --status=active)
Ca recupere la liste des plugins actifs et les reinstalle depuis le repo officiel, ecrasant les fichiers compromis.
Limitation : ca marche que pour les plugins du repo. Les premium, faut les reinstaller a la main depuis le compte du client.
Auditer les utilisateurs admin
Un site hacke a souvent un compte admin pirate cree par l'attaquant pour garder l'acces meme apres nettoyage :
wp user list --role=administrator
Verifie chaque ligne. Tout admin que le client ne reconnait pas doit etre supprime :
wp user delete <user_id> --reassign=1
Le --reassign=1 reassigne les contenus de l'utilisateur supprime a l'admin principal (id 1).
Identifier les fichiers cachettes courantes
En plus de wp-content/uploads/, voici les autres planques classiques que je verifie systematiquement lors d'un audit de securite :
# Fichiers PHP dans des dossiers ou ils ne devraient pas
find /home/htdocs -type f -name "*.php" -path "*/cache/*"
find /home/htdocs -type f -name "*.php" -path "*/upgrade/*"
find /home/htdocs -type f -name "*.php" -path "*/.well-known/*"
# Fichiers a noms suspects (avec des chiffres random)
find /home/htdocs -type f -name "[a-z0-9]{16,}.php"
# Fichiers .phtml ou .phar (executes par certains serveurs)
find /home/htdocs -type f \( -name "*.phtml" -o -name "*.phar" \)
# Fichiers htaccess en dehors de la racine (peut servir a re-router)
find /home/htdocs/wp-content -name ".htaccess" -type f
Un .htaccess dans wp-content/uploads/ est particulierement suspect : c'est generalement la pour autoriser l'execution de PHP dans uploads (ce qui ne devrait jamais se faire). Inverse, ajoute toi-meme un htaccess de protection :
# /home/htdocs/wp-content/uploads/.htaccess
<FilesMatch "\.(php|phtml|phar|php5|pht){{CONTENT}}quot;>
Require all denied
</FilesMatch>
Auditer les taches cron
Les attaquants ajoutent souvent des taches cron WordPress pour reactiver leurs backdoors :
wp cron event list
Cherche les hooks aux noms bizarres ou que tu ne reconnais pas. Une tache cron legitime a un nom explicite (woocommerce_cleanup_sessions, wp_scheduled_delete). Une tache louche s'appelle wp_check_update_status_v2 ou des trucs vagues comme ca.
Pour supprimer :
wp cron event delete <hook_name>
Automatiser la verification
Mets en place un cron qui te previent automatiquement si un fichier change :
# /etc/cron.d/wp-checksum
0 3 * * * www-data cd /home/htdocs && wp core verify-checksums --include-root 2>&1 | grep -v "Success" | mail -s "WP Checksums alert" admin@mondomaine.fr
Le grep -v Success filtre pour n'envoyer un mail que si y'a un probleme. Sinon tu recevrais un mail tous les jours pour rien et tu finirais par les ignorer.
Variante plus poussee avec un script qui verifie aussi les plugins :
#!/bin/bash
cd /home/htdocs/web
CORE=$(wp core verify-checksums --include-root 2>&1 | grep -v "Success")
PLUGINS=$(wp plugin verify-checksums --all 2>&1 | grep -v "Success")
if [ -n "$CORE$PLUGINS" ]; then
echo -e "CORE:\n$CORE\n\nPLUGINS:\n$PLUGINS" | mail -s "WP Integrity ALERT" admin@mondomaine.fr
fi
Erreurs courantes et leur fix
"Could not get checksums from WordPress.org"
Probleme reseau ou DNS. Verifie que ton serveur peut sortir :
curl -I https://api.wordpress.org/core/checksums/1.0/
Si ca timeout, ton firewall bloque la sortie HTTPS. Sur les VPS IONOS, les ports sortants sont ouverts par defaut, mais sur certains hebergements bloques (CrowdSec mal configure par exemple), faut whitelist api.wordpress.org.
"This is a development version"
Tu utilises une version nightly de WordPress, pas de checksums dispo. Repasse sur une version stable :
wp core update --version=6.5.2 --force
Plugin premium remonte modifie
Normal, les plugins premium n'ont pas de checksums publics. WP-CLI verifie quand meme certains aspects et peut remonter des faux positifs. Ignore les warnings sur les premium connus, mais reinstalle-les depuis ta source officielle si tu as un doute.
verify-checksums passe mais site reste infecte
L'infection est dans la base de donnees, pas dans les fichiers. Cherche dans les options et les posts :
wp db query "SELECT * FROM wp_options WHERE option_value LIKE '%<script%'"
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%eval(%' OR post_content LIKE '%base64_decode%'"
Permission denied sur certains fichiers
WP-CLI doit pouvoir lire tous les fichiers. Sur du mutualise IONOS, lance la commande avec le bon user :
sudo -u www-data wp core verify-checksums --include-root
Apres le nettoyage : checklist secrete
Une fois les fichiers nettoyes, il reste du boulot :
- Change tous les mots de passe : FTP, BDD, comptes WordPress admin, panneau IONOS
- Regenere les cles de salage dans
wp-config.phpvia api.wordpress.org/secret-key - Verifie qu'il n'y a pas de compte admin inconnu :
wp user list --role=administrator - Verifie les taches cron :
wp cron event list - Force la deconnexion de toutes les sessions :
wp user session destroy --all - Mets a jour tout :
wp core update && wp plugin update --all && wp theme update --all - Active 2FA sur les comptes admin (plugin Wordfence ou Two Factor)
- Demande une reconsideration dans Google Search Console si le site etait flag
La securite WordPress c'est pas juste un plugin de protection, c'est une hygiene quotidienne et une serie de reflexes.
Pour aller plus loin
- Sécuriser WordPress : guide complet anti-hack
- Activer le mode debug WordPress : wp-config.php expliqué
- Bloquer XML-RPC WordPress pour la sécurité
- Commandes WP-CLI essentielles
- Fail2ban : protéger son serveur du brute force
L'integrite, premiere ligne de defense
Verifier l'integrite c'est pas un truc qu'on fait une fois par an quand le site va mal. C'est un reflexe quotidien sur tout serveur de production. Met en place un cron, lis les alertes, et investigue chaque difference. Un fichier modifie hors mise a jour planifiee, c'est jamais anodin. Soit ton developpeur a fait une connerie, soit quelqu'un est dans la place.
WP-CLI te donne en quelques secondes ce qu'un audit manuel mettrait des heures a faire. Apprends a maitriser ces commandes, ecris tes scripts d'audit, et automatise. Le jour ou un attaquant s'invite chez ton client, tu le sauras avant Google et tu pourras nettoyer avant que le SEO en patisse.