Durcissement WordPress : vérifier l’intégrité des fichiers WordPress

Le durcissement WordPress ne se limite pas à “forcer du HTTPS” ou à durcir les droits d’accès. Quand on parle d’intégrité, on parle d’un sujet plus concret: est-ce que les fichiers qui exécutent votre site sont encore ceux que vous avez déployés, ou bien une modification sournoise s’est glissée entre-temps? Un malware en arrière-plan, une porte dérobée dans un plugin, un script ajouté dans un fichier de thème, une configuration PHP altérée après une compromission. Dans ces cas, la première question est rarement “est-ce qu’il y a un souci?”, mais “qu’est-ce qui a changé, et où?”.

Vérifier l’intégrité des fichiers WordPress devient alors un outil de diagnostic, mais aussi une routine de prévention. Cela s’inscrit parfaitement dans une démarche de durcissement WordPress, parce que vous cherchez à réduire la surface d’attaque et surtout à détecter tôt les modifications. La clé, c’est de le faire sans vous piéger vous-même, ni casser votre exploitation (mises à jour, génération de caches, contenus). C’est là que beaucoup d’approches trop “théoriques” échouent.

Pourquoi l’intégrité est une question de temps, pas seulement de sécurité

Sur un WordPress “classique”, il y a des endroits qui changent tout le temps, même si tout va bien: les fichiers liés https://gardewp.fr/securite-wordpress/ aux thèmes et aux plugins peuvent évoluer lors d’une mise à jour, certains répertoires peuvent recevoir des fichiers temporaires, et surtout le dossier wp-content/uploads change à chaque import, ajout d’image, ou export. Si votre stratégie de contrôle ne sait pas distinguer le “stable” du “volatile”, vous allez générer des alertes en rafale, et vous finirez par ne plus regarder les alertes.

Une vérification utile doit répondre à deux besoins simultanés.

image

D’abord, donner une preuve: un hachage ou une comparaison d’empreintes qui montre que telle version de tel fichier correspond à la version attendue.

Ensuite, vous aider à agir: quand une différence apparaît, quel est le périmètre probable (core, thème, plugin), et quelle est la décision raisonnable (remplacer, corriger, investiguer, isoler)?

Sur un projet que j’ai aidé à remettre d’aplomb, la première alerte venait d’un “petit” écart sur un fichier du dossier d’un plugin. Rien d’alarmant dans le front, aucun blocage WAF, et pourtant le site envoyait des requêtes sortantes suspectes. La vérification d’intégrité avait permis de remonter à un fichier altéré, puis à l’origine probable, qui n’était pas le CMS lui-même, mais la chaîne de déploiement du plugin.

Ce que vous pouvez et ne pouvez pas “vérifier” avec WordPress

WordPress est un système vivant. Il y a des fichiers qui devraient rester identiques entre deux déploiements, comme les fichiers du noyau WordPress, à condition de comparer avec la même version. Mais il y a aussi des fichiers que vous pouvez considérer comme “configurables” ou “dépendants” de votre environnement.

En pratique, on distingue trois catégories:

1) Core WordPress: le noyau, souvent contenu dans wp-includes et wp-admin, dont le contenu est censé correspondre à la version installée.

2) Plugins et thèmes: généralement stables tant que vous ne mettez pas à jour. Mais ils changent souvent plus vite que vous ne le pensez, par exemple avec des mises à jour automatiques, des patchs manuels, ou un déploiement “partiel” en production.

3) Données et contenus: uploads, caches, fichiers générés, logs. Là, vous ne cherchez pas une égalité stricte sur tout. Vous cherchez plutôt des règles, par exemple “aucun exécutable inattendu” ou “aucun fichier PHP dans un dossier qui ne devrait pas en contenir”.

Cette distinction influence la méthode d’intégrité. Une comparaison globale “tout le dossier” est rarement la bonne. Une comparaison ciblée, et surtout une comparaison avec un référentiel clair, a plus de chance d’être utile.

image

Choisir un référentiel d’intégrité réaliste

Pour vérifier l’intégrité, il faut une référence. Cette référence peut prendre deux formes:

    Comparaison directe avec une distribution attendue: vous téléchargez la même version de WordPress (core), vous calculez des empreintes, puis vous comparez les empreintes locales. Empreintes “maison” basées sur votre déploiement: vous prenez l’état connu avant mise en production (ou après mise à jour validée), vous calculez les hashes et vous enregistrez un inventaire. Ensuite, toute dérive est une anomalie par rapport à votre propre baseline.

Les deux approches sont valables, mais elles ne répondent pas aux mêmes questions. La comparaison avec la distribution attendue vérifie que votre core n’a pas été modifié. La baseline interne vérifie que votre site, tel que déployé, n’a pas été altéré, y compris pour les fichiers que WordPress ne “contrôle” pas, comme votre configuration, ou vos ajouts.

Un compromis souvent pratique: baseline pour wp-config.php et la partie “applicative” que vous maîtrisez, comparaison attendue pour le core.

Méthode 1: vérifier le core WordPress par hachage

Le core WordPress est un bon candidat, parce que la version que vous exécutez est connue, et parce que vous pouvez la relier à un paquet téléchargeable. L’idée est simple: calculer un hachage (par exemple SHA-256) de chaque fichier du core local, puis comparer à la même liste sur la distribution de référence.

image

Là où il faut être prudent, ce sont les chemins exacts et la normalisation. Par exemple, sur certains environnements, des fichiers peuvent avoir des fins de ligne différentes ou des permissions différentes. Selon votre objectif, vous pouvez choisir de ne comparer que le contenu (hash), ce qui ignore la permission, ou de contrôler aussi la permission en dur.

Une approche robuste consiste à:

    déterminer la version WordPress réellement installée (pas uniquement la version annoncée, mais vérifier l’installation), récupérer la distribution correspondante, construire la liste des fichiers à inclure (typiquement wp-admin et wp-includes, et éventuellement certains fichiers racine), calculer des empreintes, comparer et journaliser.

Voici un mini cadre d’exécution, adapté à une vérification “manuelle mais fiable”.

Mini plan de préparation (à faire une fois, puis à réutiliser)

    Vérifier la version WordPress installée et la date de la dernière mise à jour. Lister les répertoires à contrôler (core ciblé), en excluant volontairement wp-content/uploads. Définir un format d’empreinte (SHA-256) et un fichier de rapport. Garder une copie datée de l’inventaire (baseline) dans un endroit contrôlé. Prévoir une fenêtre d’action si un écart est détecté (remplacement ou investigation).

Je le dis parce que l’étape “prévoir une action” change tout. Sans procédure, la découverte d’un écart se transforme en panique, puis en décision improvisée.

Méthode 2: utiliser une baseline interne pour plugins et thèmes

Pour les plugins et thèmes, comparer à une distribution “attendue” est parfois plus compliqué. Vous devez connaître précisément les versions, et surtout l’état des fichiers réellement installés, y compris des modifications éventuelles (traductions, assets compilés, overrides).

Une baseline interne a un avantage: elle respecte ce qui tourne réellement chez vous. Vous calculez les empreintes des fichiers de wp-content/plugins et wp-content/themes après une mise à jour validée, et vous marquez cet état comme “référence acceptable”.

Ensuite, à chaque contrôle, vous recalculer les hashes et vous comparez au baseline. Si vous maintenez une discipline de déploiement, ce contrôle devient un filet de sécurité très parlant.

Le piège, c’est l’écart normal. Un plugin peut écrire des fichiers pendant son fonctionnement (cache, génération de assets, logs). Un thème peut être manipulé par un outil de build qui regénère certains fichiers. Si votre baseline inclut des fichiers générés, vous allez déclencher des faux positifs.

Dans ce cas, la stratégie la plus saine consiste à exclure les sous-dossiers qui sont typiquement générés ou variables, ou à limiter la vérification au code source PHP et aux assets statiques qu’on s’attend à voir stables.

Méthode 3: vérifier la cohérence avec une liste “système”

Il existe une approche différente, moins “hash”, plus “hygiène” et “cohérence”, qui complète souvent les hashes.

L’idée est de regarder ce qui ne devrait pas être là, ou ce qui se trouve dans des endroits improbables. Les compromissions laissent souvent des traces: un fichier PHP ajouté dans un dossier inattendu, un script “satellite” dans uploads, un dossier nouvellement créé sous wp-content avec des noms trompeurs, ou encore une modification d’un fichier de thème ou de plugin en dehors d’un cycle de mise à jour.

Cette méthode n’apporte pas une preuve aussi mathématique qu’un hash, mais elle donne un signal immédiat. Et elle aide à trier les alertes lorsque vous voyez des différences de hashes.

Un exemple concret: lors d’un audit, on a observé qu’un dossier dans wp-content/uploads contenait des fichiers PHP. Dans une installation standard, c’est très rarement “normal”. Même si des protections serveur existent, ces fichiers ont une signification. On peut alors corréler la découverte à une modification de code détectée sur un plugin.

Exemples de scénarios et décisions raisonnables

Pour que la vérification d’intégrité soit utile, il faut savoir quoi faire quand elle signale quelque chose. Voici des scénarios typiques.

Cas 1: écart sur un fichier du core, juste après une mise à jour

Si vous venez de mettre à jour WordPress et que votre vérification est faite “trop vite”, vous pouvez comparer contre un référentiel mal aligné. Peut-être que la version installée n’est pas exactement celle que vous avez téléchargée, ou que l’upload du paquet a été partiel, ou encore que la mise à jour a laissé des restes.

Décision pragmatique: re-vérifier avec la version effectivement installée, refaire une comparaison propre, puis si l’écart persiste, envisager un remplacement contrôlé du core.

Cas 2: écart sur un plugin que vous n’avez pas mis à jour

Là, l’hypothèse la plus probable n’est pas “WordPress est instable”, mais “quelque chose a changé”. La question devient alors: est-ce une modification attendue par une configuration, ou une altération non désirée?

Décision raisonnable: isoler le plugin, vérifier s’il y a des comportements anormaux côté logs (requêtes sortantes, erreurs, changements de cron), puis comparer les hashes du plugin à une baseline datée. Si la baseline montre une altération récente, vous avez une piste forte.

Cas 3: faux positifs sur des fichiers générés

Typiquement, caches, minifications, assets compilés, ou fichiers créés par des extensions d’optimisation. Les hashes changent, mais le code PHP “exécutable” ne change pas.

Décision: affiner le périmètre de contrôle. Vous pouvez garder un contrôle de “présence” et de “type” de fichier (pas de PHP dans un dossier d’uploads, par exemple), et réduire la comparaison stricte aux fichiers réellement sensibles.

Intégrer la vérification au durcissement WordPress sans le casser

Le contrôle d’intégrité n’est pas une action unique. C’est une routine qui doit s’insérer dans votre cycle de production.

Si votre site est très vivant, par exemple e-commerce, vous ne voulez pas que la vérification prenne des heures ou produise des charges inutiles. La vérification de milliers de fichiers peut être coûteuse selon l’accès disque et le stockage.

Deux compromis courants:

    faire une vérification “core” plus fréquente, parce que c’est stable et que les modifications y sont rares, faire une vérification “plugins et thèmes” plus espacée, ou déclenchée uniquement après mise à jour ou déploiement.

Et surtout, stocker vos rapports. Sans historique, vous ne pouvez pas corréler une dérive à un événement interne. Le rapport devient la pièce centrale, pas le verdict.

Permissions, ownership, et ce que l’intégrité ne dira pas

Les hashes prouvent que le contenu a changé. Mais ils ne disent pas pourquoi, ni comment l’accès a été obtenu.

Dans une démarche de durcissement WordPress, la vérification d’intégrité devrait être accompagnée d’une hygiène de permissions. Si des fichiers de code sont modifiables par un utilisateur non nécessaire, un incident a plus de chances de “réussir” sans être bloqué.

Même sans faire de liste, le principe est clair: le compte web ne doit pas être en mesure d’écrire dans des dossiers de code de manière générale. Il peut avoir besoin d’écrire dans des zones de cache ou de logs, selon les configurations, mais on limite autant que possible.

Un cas fréquent: en cherchant un gain de temps, on met des permissions trop larges et tout devient “écrivable”. Quand l’intégrité se met à diverger, vous constatez l’effet, mais votre posture de prévention est déjà compromise.

Ce qui doit déclencher une investigation rapide

Un contrôle d’intégrité n’est pas fait pour “cocher une case”. Certaines alertes sont plus graves que d’autres, et votre temps est limité.

Sans liste, je vais vous donner des critères qui reviennent souvent dans les interventions:

    un fichier PHP détecté dans un répertoire qui ne devrait pas en contenir, une modification d’un fichier du core en dehors de toute mise à jour planifiée, une modification d’un plugin ou thème pendant une période où aucun déploiement n’a eu lieu, une série d’écarts multiples, surtout si plusieurs fichiers partagent la même date de modification, des écarts qui touchent des fichiers chargés tôt dans WordPress (bootstrap, fichiers racine, fichiers qui sont inclus au démarrage).

Quand plusieurs critères s’additionnent, on ne fait pas de “petites corrections cosmétiques”. On isole, on vérifie, puis on remplace si nécessaire.

Mettre en place une routine pratique, sans magie

Le plus dur, c’est l’exécution régulière. La routine doit être simple à lancer et facile à interpréter.

Une pratique efficace consiste à:

    lancer une comparaison core, lancer une comparaison plugins et thèmes contre baseline seulement quand il y a eu mise à jour ou modification, conserver les rapports dans un dossier protégé, et associer ces rapports à vos événements de déploiement.

Si vous utilisez un système de gestion de versions, vous pouvez aussi lier vos baselines aux commits ou aux tags de déploiement, même si tout n’est pas “Git-friendly” dans WordPress.

Le point important est de ne pas confondre “contrôle” et “correction”. Le contrôle sert à repérer, le reste dépend du résultat.

Gérer les mises à jour sans perdre votre capacité de détection

Les mises à jour sont le moment le plus “risqué” pour la détection, car beaucoup de fichiers vont changer. Si vous n’avez pas de baseline et de calendrier, vous ne saurez plus ce qui est légitime.

Une méthode qui marche bien consiste à établir une discipline:

    avant mise à jour, faire un inventaire des hashes du périmètre sensible (au moins core), après mise à jour et validation, mettre à jour la baseline à l’état “bon”.

Dans ce scénario, la vérification ultérieure redevient informative. Vous n’êtes pas en train de comparer à une date ancienne ou à une version approximative.

Et si votre déploiement est multi-étapes (staging puis production), vous pouvez faire la baseline sur staging une fois validé, puis appliquer à production lors du déploiement, à condition d’être sûr que les fichiers ne divergent pas.

Limites à connaître, pour éviter la fausse sécurité

Vérifier l’intégrité ne fait pas disparaître tous les risques. Deux limites importantes reviennent.

Première limite: une compromission peut exister sans modifier le fichier que vous contrôlez. Si l’attaque exploite une vulnérabilité, un identifiant compromis, ou un accès à la base de données, elle peut agir ailleurs. Les hashes ne vont pas vous alerter sur des modifications en base, ou sur une altération via une action dynamique.

Deuxième limite: la comparaison de fichiers ne vous dit pas quel mécanisme a modifié. Un fichier peut avoir été altéré, puis restauré, et vous ne verrez peut-être qu’un état “stable” au moment du contrôle.

C’est pour cela que dans une vraie posture de durcissement WordPress, l’intégrité est un pilier parmi d’autres: logs, durcissement d’accès, validation des permissions, mise à jour des plugins, et supervision des comportements.

Un point souvent sous-estimé: conserver et protéger les rapports

Si vos rapports d’intégrité restent dans un endroit modifiable par n’importe qui, vous créez une nouvelle surface de risque. En cas d’incident, un attaquant peut tenter de modifier votre baseline ou d’effacer les preuves.

La règle est simple: les artefacts de sécurité (baselines, rapports, journaux) doivent être protégés avec la même attention que les fichiers importants.

Selon votre contexte, cela peut signifier un stockage hors du document root, ou un accès restreint, ou une conservation avec des contrôles d’accès. L’objectif est que le rapport soit une source fiable au moment où vous en avez besoin, pas une pièce facilement falsifiable.

Par où commencer si vous voulez une approche progressive

Vous n’avez pas besoin de tout contrôler dès la première semaine. Une progression raisonnable consiste à démarrer par ce qui est le plus révélateur et le moins variable.

Voici une courte progression, sans vous noyer dans des comparaisons trop larges.

    Commencer par le core WordPress, avec une comparaison fiable sur la version installée. Construire une baseline après chaque mise à jour validée du core. Ajouter progressivement les plugins et thèmes, mais en excluant les zones clairement générées. Mettre une routine de contrôle orientée “déploiement”, pour éviter les faux positifs.

L’intérêt, c’est que vous obtenez vite une capacité de détection, puis vous affinez selon vos plugins et votre workflow.

Conclusion sans formule creuse: l’intégrité rend vos alertes actionnables

Quand vous vérifiez l’intégrité des fichiers WordPress dans un cadre de durcissement WordPress, vous ne cherchez pas juste des “preuves”. Vous cherchez de la décision.

Les différences de hashes et les incohérences de fichiers deviennent utiles seulement si vous savez ce qui est stable, ce qui bouge, et comment relier un écart à un événement de votre exploitation. Une baseline bien construite, un périmètre réaliste, des rapports protégés, et une action pré-définie en cas de signal: voilà ce qui transforme une vérification en sécurité exploitable.

Si vous me dites votre configuration (hébergeur, usage de mises à jour auto, nombre de plugins, présence d’outils de build, et si vous avez un staging), je peux vous proposer un périmètre de contrôle adapté et une stratégie de baseline qui limite au maximum les faux positifs.