WordPress est un excellent choix quand on veut livrer vite, itérer souvent et garder la main sur le contenu. Mais cette souplesse se paie parfois en surface d’attaque. L’une des lignes rouges les plus sensibles, parce qu’elle se voit rarement au premier regard, c’est l’exécution de code non fiable.
Quand un serveur WordPress exécute un extrait de PHP que vous n’avez jamais autorisé, vous ne subissez pas seulement un risque “classique” de piratage. Vous perdez le contrôle de votre environnement d’exécution. À partir de là, l’attaquant peut agir comme s’il était un développeur ayant accès au chantier : lire des fichiers, modifier des pages, aspirer des identifiants, installer des persistance, et parfois transformer votre site en passerelle pour d’autres opérations.
Ce billet pose les bases concrètes pour renforcer la sécurité WordPress autour de ce point précis : empêcher qu’un contenu ou un mécanisme non digne de confiance déclenche du code côté serveur.
Ce que signifie “code non fiable” dans WordPress
Dans la pratique, “code non fiable” ne veut pas dire seulement “du code malveillant évident”. Cela recouvre plusieurs réalités :
- un plugin ou un thème installé alors qu’il n’était pas attendu, ou dont la provenance est floue ; une fonctionnalité qui évalue du contenu, par exemple via du code dynamique, des templates, ou des entrées manipulées côté serveur ; un canal d’injection, comme un paramètre d’URL ou une valeur enregistrée, qui finit évaluée plutôt que traitée comme une simple donnée ; un fichier modifié hors de votre processus normal, parfois via une faille de dépendance ou via un accès perdu (identifiants).
Le point commun est le même : une entrée ou un artefact entre dans un chemin qui mène à l’exécution. Si vous bloquez ce chemin, vous réduisez l’impact même quand une autre couche échoue.
J’ai déjà vu des sites où “tout avait l’air normal” côté pages. Aucun message agressif, aucun redirection. Mais en inspectant le filesystem, on découvre un fichier PHP minuscule, souvent dans un dossier de cache, de session ou un répertoire “oublié” par l’équipe. Le site continuait à afficher son contenu habituel, car le code malveillant se déclenchait uniquement dans certains cas, par exemple quand une URL contenait un paramètre précis, ou quand un utilisateur n’était pas connecté.
Ce genre de situation illustre bien pourquoi il faut penser en termes de chemin d’exécution, pas seulement en termes de contenu visible.

Pourquoi l’exécution est le vrai moment du risque
L’exécution de code est un basculement. Avant, l’attaquant manipule des données. Après, il manipule des instructions. En sécurité applicative, ce changement détermine souvent la gravité.
Dans WordPress, ce basculement peut se produire à plusieurs endroits :
- au moment où le serveur PHP charge un fichier (inclusion, require, include) ; au moment où du code dynamique est interprété (évaluation) ; au moment où des flux de données sont réinjectés dans un contexte dangereux, puis “re-traités” côté serveur.
Le problème, c’est que WordPress, par conception, autorise une grande variété d’extensions. Si vous laissez trop de latitude à des choses non contrôlées, vous multipliez les chemins possibles.
C’est aussi là qu’apparaît une erreur fréquente, même dans des équipes sérieuses : “on a corrigé la vulnérabilité identifiée, donc c’est bon”. Or l’exécution peut venir d’un autre vecteur. Un plugin “propre” peut devenir dangereux s’il interagit avec un autre composant défaillant, ou s’il est trompé par des entrées non validées.
Les scénarios typiques qui mènent à l’exécution non fiable
On peut classer les scénarios sans tomber dans la recette universelle. Voici les plus courants sur des environnements WordPress réellement rencontrés sur le terrain.
1) Modifications non autorisées de fichiers PHP
Un fichier change, souvent dans des chemins qui semblent secondaires : des dossiers de sauvegarde, des répertoires de plugins, parfois même des fichiers à la racine. Le code peut être discret, ne se déclencher que sous conditions, et masquer sa présence en modifiant uniquement le strict nécessaire.
Ce qui rend ce scénario redoutable, c’est que le site peut rester fonctionnel. Une détection par “défacement visuel” échoue souvent. Il faut penser en intégrité : qui a modifié quoi, et quand.
2) Injection menant à une inclusion de fichier
Quand le code d’un plugin ou d’un thème construit un chemin de fichier à partir d’une entrée, et finit par inclure ce fichier, on obtient un scénario où la donnée devient un chemin. Si le contrôle est insuffisant, l’attaquant peut viser un fichier de configuration, un fichier temporaire, ou un script déposé quelque part.
Même sans aller jusqu’à l’inclusion “totale”, on peut obtenir une exécution progressive : l’application inclut un fichier inattendu, qui charge ensuite d’autres éléments.
3) Évaluation de contenu ou “code dynamiquement interprété”
Certains composants, plugins ou configurations utilisent des mécanismes qui évaluent du texte, interprètent des expressions ou reconvertissent des données en instructions. Dans un contexte WordPress, ce n’est pas toujours mauvais en soi, mais dès qu’une partie du contenu vient de l’extérieur, le risque augmente fortement.
Ce type de vulnérabilité est parfois subtil : l’évaluation n’est pas visible dans un fichier unique, elle se cache dans l’enchaînement “paramètre -> traitement -> stockage -> re-traitement”.
4) Chaîne d’approvisionnement : dépendances, mises à jour, bundles
L’exécution non fiable peut aussi arriver avant même l’installation. Un plugin fourni avec une dépendance compromise, ou un thème distribué avec du code ajouté, peut introduire un canal d’exécution.
La bonne nouvelle, c’est que les mesures de réduction de surface fonctionnent ici aussi : limiter ce qui tourne, limiter ce qui est modifiable, et rendre les changements observables.
5) Comptes compromis et droits excessifs
Un compte admin compromis, c’est comme une porte d’entrée qui n’a pas besoin de faille technique complexe. Une fois dans l’interface, l’attaquant peut déposer ou activer des éléments qui déclenchent du code.
Même si vous gardez WordPress à jour, une erreur de gestion des accès peut neutraliser vos efforts. L’idée n’est pas de “supposer la mauvaise intention”, mais de réduire la capacité de nuire quand l’identité est douteuse.
Renforcer la sécurité WordPress avec des contrôles axés “chemins d’exécution”
L’approche la plus efficace est rarement un seul réglage magique. Elle combine plusieurs garde-fous, avec un objectif : empêcher qu’une entrée non fiable arrive jusqu’à un point d’exécution.
Contrôle 1 : réduire ce qui peut écrire et déposer du PHP
Sur un WordPress, l’écriture sur le filesystem est un levier très puissant. Si un attaquant ne peut pas déposer de fichiers, beaucoup de scénarios basculent en “impasse”.
D’un point de vue pratique, ça passe par deux idées : limiter les droits d’écriture côté serveur et contrôler les changements.
- Les répertoires et fichiers qui ne doivent pas être modifiés en production ne devraient pas être écrits par le processus web. Les plugins et thèmes doivent suivre un cycle de déploiement maîtrisé, pas des installations “à la volée” sur une machine exposée.
Sur certains hébergements, le contrôle des permissions est trop permissif par défaut. Une simple vérification peut déjà faire gagner des semaines de traitement incident. Le piège, c’est de corriger sans comprendre l’impact sur les mises à jour et la génération de cache.
Contrôle 2 : la règle d’or, traiter les entrées comme des données, pas comme des instructions
Le risque d’exécution non fiable provient souvent d’un traitement dangereux des entrées.
Dans un thème ou un plugin, la discipline consiste à :
- valider la donnée dès l’entrée, avec des contraintes strictes (type, format, longueur) ; ne jamais concaténer une entrée utilisateur dans un chemin de fichier ou une instruction ; séparer clairement le stockage des données et leur ré-interprétation.
Dans l’interface WordPress, on voit parfois des champs qui acceptent du texte “pour être pratique”. Le texte devient plus tard un paramètre exploité dans un autre contexte. Tant que l’équipe ne documente pas le chemin de données, l’exécution non fiable apparaît comme un accident.
Si vous développez en interne, je recommande d’écrire cette traçabilité dans votre revue de code : “où arrive la donnée, où elle est stockée, où elle est lue, sous quel contexte”.
Contrôle 3 : surveiller l’intégrité, pas seulement la disponibilité
Une intrusion peut être lente, et le site rester en ligne. C’est pour ça que l’observabilité doit inclure des indicateurs d’intégrité : modifications de fichiers, ajouts, changements de signatures, ou même simples différences de hash.
Sans exagérer, on veut au minimum savoir :
- quels fichiers ont changé depuis la dernière fenêtre contrôlée ; si des scripts PHP apparaissent dans des zones inattendues ; si des patterns typiques d’obfuscation sont présents.
On peut mettre en place cette surveillance avec des outils adaptés à votre stack. L’essentiel est d’éviter le “je regarde quand ça tombe”.
Contrôle 4 : verrouiller l’environnement d’exécution (dans la limite du raisonnable)
WordPress s’exécute dans PHP, et PHP a des comportements et des réglages qui peuvent limiter certains abus.
Sans entrer dans une liste exhaustive de paramètres, l’idée est de faire en sorte que l’environnement soit “durci” :
- exécuter avec les options et fonctions minimales nécessaires ; empêcher ou limiter les fonctions dangereuses si votre hébergeur le permet ; contrôler la capacité du code à charger dynamiquement du contenu ou à manipuler des fichiers.
Attention aux faux positifs : trop de durcissement casse des plugins légitimes. Le bon compromis consiste à durcir progressivement, en testant d’abord sur un environnement de staging. Si vous avez déjà un parc de plugins, partez des plus critiques et testez les scénarios réels.
Contrôle 5 : filtrer la voie “contenu -> interprétation”
WordPress permet beaucoup de personnalisation. Cela inclut des zones où l’on accepte du HTML, parfois du JavaScript, ou des fragments qui passent par des filtres. Le risque, c’est quand un fragment non fiable arrive jusqu’à une interprétation côté serveur, ou qu’il contourne des filtres.
Le meilleur garde-fou est la séparation stricte :
- vous pouvez autoriser des formats pour l’affichage, à condition d’assainir correctement et de limiter les sources ; mais vous évitez d’utiliser ce contenu dans des contextes qui déclenchent du traitement serveur dangereux.
Dans les cas où vous devez accepter des “shortcodes” ou des blocs, assurez-vous que leur exécution ne peut pas être contrôlée par un utilisateur non digne de confiance, et que les paramètres attendus sont strictement validés.
Des signes qui doivent vous faire ouvrir le dossier technique immédiatement
Il y a des indices qui, combinés, deviennent très parlants. Aucun n’est une preuve à lui seul, mais ils justifient d’agir vite, surtout si vous cherchez spécifiquement des chemins d’exécution non fiable.
Voici les signaux que je traite comme des alertes “prioritaires” :
- un nouveau fichier PHP dans un répertoire que vous n’avez jamais utilisé en production (ou un fichier très petit, avec du contenu obfusqué) ; des erreurs PHP ou des logs qui montrent un chargement inattendu de fichiers, ou des inclusions répétées ; des pics de requêtes vers des endpoints sans trafic marketing correspondant, parfois avec des paramètres inhabituels ; un comportement conditionnel sur le site, par exemple une redirection uniquement pour certains navigateurs ou seulement quand un paramètre est présent ; des changements dans la liste des plugins ou des thèmes, y compris des mises à jour “arrivées toutes seules”.
Quand vous voyez plusieurs de ces points ensemble, vous n’êtes plus dans le doute. Il faut basculer en mode investigation, documenter l’état avant correction, et limiter ce que vous modifiez pour ne pas perdre la capacité de remonter la cause.
Mettre en place une stratégie de durcissement réaliste
Les meilleures défenses sont celles que vous pouvez maintenir. Une stratégie efficace doit être compatible avec votre rythme de publication et votre capacité à gérer des incidents.
Une façon pragmatique de procéder consiste à prioriser l’impact. D’abord, réduire l’exécution possible, ensuite renforcer la détection.
Voici une trame courte, orientée “empêcher l’exécution non fiable” :
Limiter le nombre de plugins et de thèmes en production, et supprimer ce qui n’est pas utilisé. Exiger une source de confiance pour toute installation, avec un processus de revue pour les plugins moins courants. Mettre en place un contrôle d’intégrité des fichiers PHP, au minimum sur les répertoires sensibles. Durcir les permissions filesystem, sans casser les mises à jour, et vérifier après déploiement. Réduire les droits des comptes, et imposer une hygiène d’accès robuste (mots de passe uniques, 2FA quand c’est possible).C’est volontairement concret, parce que la sécurité “sur le papier” s’effondre au premier incident.
Une note importante : WordPress peut exécuter, mais vous devez pouvoir expliquer pourquoi
Un site WordPress sain exécute du PHP, évidemment. La question n’est pas “est-ce que ça exécute”, c’est “est-ce que cette exécution est attendue, traçable et contrôlée”.
Quand je travaille un dossier d’incident, j’aime bien revenir à une question simple : “si ce code s’exécute, quelle chaîne de décisions y mène, et est-ce que cette chaîne est légitime ?”
Par exemple :
- un plugin tiers peut légitimement générer des pages et exécuter des hooks, mais pas déclencher une inclusion de fichier arbitraire ; un thème peut ajouter des styles et des templates, mais pas récupérer des contenus distants non nécessaires et les interpréter comme du PHP ; un compte admin peut activer une fonctionnalité, mais pas exister sans que personne ne se souvienne de sa création.
Cette logique ne nécessite pas de maîtriser tout le code. Elle exige un cadre d’enquête, un langage commun, et des preuves.
Cas concrets : comment l’exécution non fiable apparaît en enquête
Sans “récit de film”, les cas réels ressemblent souvent à ceci.
Sur un site qui a été compromis via une faiblesse d’un plugin, le reste du temps, le comportement était gardewp.fr quasi normal. Les pages servaient correctement, et les visiteurs ne voyaient rien. En revanche, côté logs, on observait une activité régulière, avec des requêtes qui ne correspondaient pas au trafic. En inspectant le filesystem, on a repéré un fichier PHP placé dans un dossier non utilisé par l’application. Il ne s’exécutait pas “tout le temps”, seulement sur des requêtes qui correspondaient à un motif précis.
Le correctif n’a pas été seulement “supprimer le fichier”. Il a fallu :
- désinstaller le plugin fautif ; vérifier les modifications de fichiers sur toute l’arborescence WordPress ; invalider les sessions, changer les secrets, réinitialiser les identifiants ; verrouiller les permissions pour que le processus web ne puisse pas déposer plus facilement du code.
Ce cas illustre une vérité dure : vous pouvez corriger le symptôme, mais si vous ne remontez pas la chaîne, vous laissez une porte ouverte.
Dans un autre scénario, la compromission venait d’un compte admin. Là, le fichier malveillant n’était pas dans un dossier évident. Il avait été ajouté via l’interface, puis utilisé comme relais pour exécuter du code à certains moments. Là aussi, le durcissement a compté, mais surtout la gouvernance des accès.
Les compromis inévitables, et comment les gérer
Renforcer la sécurité WordPress, ce n’est pas seulement “plus de restrictions”. C’est aussi gérer ce que vous cassez et ce que vous autorisez.
Première contrainte : le parc de plugins. Plus vous durcissez, plus vous augmentez le risque de casser des fonctionnalités. La solution, c’est le staging et la réversibilité. Si vous appliquez un durcissement à la racine de PHP ou à des fonctions sensibles, testez vos chemins réels : publication, formulaires, paiements si vous en avez, intégrations marketing.
Deuxième contrainte : la détection. Le monitoring d’intégrité peut générer du bruit. Il faut définir ce qui change “normalement” dans votre environnement. Sur WordPress, certains dossiers bougent en permanence, comme cache ou uploads. Sur ces zones, la surveillance doit être ciblée. L’objectif n’est pas de vous noyer dans des alertes, mais de rendre les changements inattendus visibles.
Troisième contrainte : la maintenance. Une stratégie qui dépend d’actions manuelles, chaque fois, finit abandonnée. Je préfère les approches où vous pouvez automatiser la vérification d’intégrité et la comparaison de versions, tout en gardant une supervision humaine.
Une checklist mentale avant toute correction
Quand une suspicion d’exécution non fiable apparaît, j’encourage une discipline minimale, parce que l’ordre des actions influence la suite.
Avant de supprimer ou de remplacer des fichiers, essayez de préserver les éléments utiles à l’enquête : copies, logs, horodatages, et liste des changements récents. Ensuite seulement, vous corrigez et vous revenez à un état connu.
Cela ne veut pas dire “ne rien faire”. Ça veut dire “agir, mais sans effacer les preuves plus vite que vous ne les comprenez”.
Si vous n’êtes pas sûr de l’origine, la restauration à partir d’une sauvegarde fiable est souvent le chemin le plus rapide, à condition d’être certain que la sauvegarde précède l’infection. Sinon, vous réintroduisez le problème.
Points clés à retenir pour éviter l’exécution de code non fiable
La prévention de l’exécution non fiable repose sur une idée simple : vous ne laissez pas des entrées, des fichiers ou des modules non dignes de confiance atteindre le serveur sous une forme exécutable.
Si vous ne deviez garder que quelques principes, ce seraient ceux-ci :
- traquer l’inattendu, surtout dans les fichiers PHP ; limiter les droits d’écriture et la surface de déploiement ; valider strictement les entrées qui alimentent un traitement côté serveur ; surveiller l’intégrité et les comportements anormaux, même quand le site reste “en ligne” ; gouverner les accès et réduire les dépendances.
WordPress n’a pas besoin d’être verrouillé à l’extrême pour être solide. Il a surtout besoin d’un cadre : un environnement maîtrisé, des changements visibles, et des chemins d’exécution qui restent cohérents avec votre intention.
Si vous cherchez à faire un premier pas concret, commencez par l’inventaire de vos thèmes et plugins, puis vérifiez l’intégrité des fichiers dans les zones sensibles. C’est souvent là que l’histoire se raconte, avant même que la prochaine alerte ne tombe.