Quand on parle de hardening WordPress, on pense souvent à WordPress lui-même, à ses plugins, à la mise à jour du noyau. Pourtant, dans la pratique, une grande partie des failles exploitables ne naît pas dans le code applicatif, mais dans l’environnement PHP qui exécute WordPress. Un paramètre mal réglé dans php.ini, une option trop permissive sur le serveur, ou une configuration qui révèle des détails au navigateur, et tout le reste devient beaucoup plus fragile.
J’ai vu des incidents très concrets partir de “petites choses” côté PHP. Un display_errors activé, et l’attaquant obtient des traces qui accélèrent le repérage. Un file_uploads laissé ouvert sans garde-fous, et l’upload devient une surface d’attaque. Une directive comme expose_php qui divulgue des informations sur la stack, puis un scan plus ciblé, puis une exploitation. Rien de spectaculaire au départ, mais le cumul finit par compter.
L’objectif ici n’est pas de “verrouiller pour verrouiller”. Il s’agit de corriger des réglages PHP de façon pragmatique pour réduire la surface d’attaque, tout en gardant WordPress fonctionnel. On va donc parler de ce qui mérite d’être ajusté, de ce qui peut casser un site si on le touche trop vite, et de comment valider sans lancer une roulette russe sur la prod.
Comprendre où PHP influence la sécurité de WordPress
WordPress exécute du PHP presque partout, mais ce n’est pas seulement “du PHP”. C’est PHP qui s’appuie sur un ensemble de paramètres d’exécution et de contraintes imposées au processus. Ces contraintes déterminent, par exemple :
- si l’application peut afficher des erreurs à l’écran, si des fonctions jugées dangereuses sont disponibles, si le serveur autorise certains formats d’accès distants, si les uploads sont acceptés et comment ils sont traités, si PHP peut lire des fichiers en dehors des répertoires attendus, quelles limites empêchent un abus par consommation mémoire ou ressources.
En hardening WordPress, c’est souvent la combinaison qui fait la différence. Un paramètre seul peut ne pas empêcher une attaque. Mais une configuration mieux cadrée réduit le “confort” de l’attaquant et augmente le coût de l’exploitation.
Les signaux qu’une configuration PHP est trop permissive
Avant de corriger, il faut observer. Les indices les plus utiles sont ceux que vous pouvez voir sans privilège spécial, par exemple via un navigateur ou vos logs applicatifs.
Sur un WordPress exposé, un mauvais réglage PHP se manifeste souvent par :
- des erreurs PHP affichées dans la page (même sans survenue d’un incident), des réponses qui révèlent des chemins système, des classes internes ou des informations de version, des comportements incohérents autour des uploads (acceptation inattendue de certains types, messages de taille bizarres), des lenteurs ou des pics CPU/mémoire lors de requêtes “simples”, ce qui suggère des limites absentes ou trop hautes, des logs d’erreur très bavards, parfois activés en permanence.
Mon conseil est simple : cherchez d’abord à comprendre ce qui fuit, puis ce qui manque comme garde-fou. Corriger dans le vide mène vite à des régressions.

Les réglages PHP qui ont le plus d’impact (et comment les corriger)
Je regroupe ici les corrections “à forte valeur” côté configuration PHP. L’idée est de viser une posture sûre par défaut, puis d’ajuster au besoin pour ne pas casser WordPress ou vos plugins.
Ne plus divulguer les erreurs vers le navigateur
Le premier levier est généralement le couple display_errors et log_errors (selon l’implémentation exacte et la version). Le principe : en production, WordPress et PHP ne doivent pas afficher leurs erreurs au visiteur. Les erreurs doivent partir dans les logs serveur, accessibles aux équipes, et pas au public.
- display_errors devrait être désactivé en production. log_errors doit rester activé pour diagnostiquer. error_reporting doit être raisonnable. Mettre trop large peut noyer les logs, et rendre plus difficile l’analyse.
Trade-off réel : certains sites affichent des erreurs pour “surveiller” le fonctionnement. Une fois coupé, vous ne verrez plus le symptôme dans la page, mais vous verrez les traces dans les logs. Il faut donc ajuster vos habitudes de support.
Réduire la “signature” PHP côté réponse HTTP
expose_php est un exemple classique. Quand il est activé, PHP peut divulguer qu’il est utilisé, et parfois la version. Ce n’est pas une vulnérabilité à lui seul, mais c’est une aide pour la reconnaissance. En hardening, on préfère réduire les indices.
Ce type de correction se fait généralement dans php.ini ou via le fichier de configuration du serveur. Elle est rarement risquée, mais je l’évalue au cas par cas si vous avez des intégrations externes qui dépendent de détails de headers (c’est rare, mais ça existe).
Encadrer les uploads : taille, type, emplacement
WordPress gère les uploads côté PHP, mais les limites de base dépendent du runtime PHP.
- file_uploads : s’il est désactivé, WordPress ne pourra pas uploader du tout. upload_max_filesize et post_max_size : si ces valeurs sont incohérentes, vous verrez des erreurs d’upload côté WordPress, souvent “mystérieuses” pour l’utilisateur. max_execution_time et max_input_time : si elles sont trop basses, les uploads volumineux peuvent échouer. memory_limit : certains traitements (miniatures, conversions, manipulations) peuvent consommer plus que prévu selon les plugins.
Le point délicat ici, c’est l’alignement avec les limites web (souvent Nginx ou Apache). Corriger seulement PHP peut créer une impression de “ça marche encore un peu, puis ça casse”. J’ai déjà vu des équipes ajuster upload_max_filesize dans PHP, mais la vraie limite venait d’une autre couche, ce qui générait des erreurs à mi-parcours.
Pour une correction cohérente, il faut aligner PHP et le serveur frontal sur le même maximum attendu pour vos médias. Ensuite, vous pouvez rendre la contrainte plus efficace en ajustant les limites de ressources.
Éviter l’exécution dans des contextes non attendus
Selon votre architecture, WordPress peut tourner en PHP-FPM, module Apache, ou autre. L’exposition à certains risques dépend de la façon dont le serveur associe fichiers et exécution PHP.
Côté PHP, il y a des paramètres qui influencent la lecture de fichiers. Un levier souvent recommandé est open_basedir, qui limite les répertoires accessibles par PHP. Si vous pouvez le mettre correctement, cela limite des impacts si une vulnérabilité applicative permet d’accéder à un chemin arbitraire.
Mais attention : appliquer open_basedir sans inventaire de ce que WordPress et vos plugins utilisent peut casser des fonctionnalités. Fonts, exports, imports, caches, ou uploads dans des chemins spécifiques peuvent dépendre de répertoires additionnels. Dans les environnements où vous ne contrôlez pas tous les chemins, le risque de régression est réel.
Approche pratique : vous commencez par lister les répertoires réellement nécessaires, puis vous faites une mise en place progressive, en surveillant les logs et les erreurs 500. Si vous avez un montage de stockage (NFS, S3 via plugin, montages réseau), réfléchissez avant de verrouiller open_basedir, car certains flux ne se comportent pas comme un dossier local.
Restreindre les accès distants et les fonctions inutiles
Deux familles de réglages reviennent souvent quand on veut réduire la surface d’attaque :
Les accès distants via URL (contrôles autour de allow_url_fopen, allow_url_include, ou équivalent). Les fonctions PHP considérées comme dangereuses ou rarement nécessaires.L’idée n’est pas de “désactiver tout ce qui existe”, mais de désactiver ce dont vous n’avez pas besoin. Par exemple, si aucun plugin, aucune tâche planifiée, aucune intégration externe n’utilise de récupération de contenu via URL, alors autoriser l’accès à des sources externes devient un risque gratuit.
Trade-off : certains plugins d’images distantes, certains connecteurs ou outils d’import peuvent utiliser des URL. Une désactivation trop agressive peut casser des fonctionnalités sans vous prévenir. C’est là que vos tests et votre journalisation comptent.
Encadrer les ressources pour limiter l’impact d’un abus
Les paramètres de performance côté PHP servent aussi en sécurité, parce qu’ils limitent l’impact d’attaques par déni de service applicatif. Parmi les plus importants :
- max_execution_time max_input_time memory_limit
Je préfère parler d’un cadre, pas d’une valeur unique universelle. Le “bon” réglage dépend du type de requêtes que vous autorisez : pages standards, génération de PDF, traitements d’images, imports lourds, etc. Si vous limitez trop, vous créez une vulnérabilité opérationnelle : un utilisateur peut déclencher des chemins qui échouent et perturbent la disponibilité, ou vos tâches planifiées échouent.
Ce que j’ai trouvé efficace : définir des valeurs qui couvrent les usages légitimes observés. Ensuite, vous utilisez des limites différentes pour certaines tâches si votre stack le permet (par exemple via des pools PHP séparés ou une logique de configuration par vhost). Dans beaucoup de setups, vous pouvez faire mieux que “une valeur globale pour tout”.
S’occuper des sessions : sécurité et durcissement
Les sessions PHP sont un autre endroit où des détails comptent. Le durcissement se fait surtout sur la manière dont les cookies de session sont posés :
- session.cookie_secure pour garantir l’envoi uniquement en HTTPS, session.cookie_httponly pour éviter l’accès JavaScript, parfois une configuration de durée, et la rotation selon votre framework.
Avec WordPress, une partie de la sécurité des sessions et cookies passe aussi par WordPress, mais la couche PHP détermine ce que PHP fait. Si vous avez un site accessible en HTTP pendant un moment, ou des redirections imparfaites, vos cookies de session peuvent être exposés plus facilement que prévu.
Edge case : certaines architectures de reverse proxy mal configurées posent un HTTPS ambigu aux applications, surtout si $_SERVER['HTTPS'] n’est pas cohérent. Dans ces cas, “forcer” session.cookie_secure côté PHP peut empêcher la session de fonctionner si l’application ne voit pas correctement le HTTPS. On corrige alors la détection de schéma dans le proxy, pas seulement la session.
Ne pas laisser PHP écrire librement
Même quand l’écriture ne semble pas “dangereuse”, une mauvaise posture autour des répertoires d’exécution ou des permissions peut ouvrir des portes.
Ici, ce n’est pas seulement du PHP, c’est l’ensemble : droits Unix, propriétaire des dossiers WordPress, mode d’écriture pour les caches, et emplacement des uploads. En PHP, certains réglages influencent la manière dont les fichiers temporaires sont gérés.
Votre objectif : limiter l’écriture à des répertoires que vous contrôlez, et éviter les emplacements où des fichiers temporaires pourraient être servis ou réexécutés.
Je recommande de vérifier les dossiers temporaire et cache, et de s’assurer que la configuration du serveur frontal ne permet pas l’exécution PHP dans des répertoires qui n’ont pas vocation à contenir du code PHP.
Un plan de correction réaliste, sans casser la prod
Les corrections PHP sérieuses se font rarement “d’un coup”. Le risque n’est pas uniquement technique, il est aussi opérationnel : votre site doit rester utilisable, vos emails et vos tâches planifiées doivent continuer.
Voici une manière de procéder qui limite les surprises.
- Valider le contexte de votre exécution PHP : php.ini unique, ou plusieurs fichiers par vhost, ou pools PHP-FPM distincts. Relever l’état actuel, en commençant par les erreurs et logs. Appliquer des changements minimalistes d’abord, par exemple couper la divulgation d’erreurs vers le navigateur et réduire expose_php. Ensuite seulement, ajuster les limites de taille et de ressources, et enfin les restrictions plus sensibles comme open_basedir et les accès distants.
Si vous avez accès à une staging, c’est idéal. Sinon, vous pouvez faire une fenêtre de maintenance courte sur un site non critique. Dans tous les cas, je conseille un plan de retour en arrière rapide, par exemple via rollback de configuration.
Comment vérifier que la configuration a réellement durci
Après modification, il ne suffit pas de “penser que c’est mieux”. Il faut vérifier, avec des tests qui ressemblent à l’usage réel.
Vous pouvez commencer par des validations simples, puis pousser vers des cas limites. L’objectif est d’observer deux choses : l’absence de divulgation et le bon comportement fonctionnel.
Voici une check courte qui marche bien en pratique :

- Ouvrir une page provoquant une erreur PHP dans un contexte contrôlé, vérifier que rien ne s’affiche publiquement et que le log serveur reçoit bien l’entrée Vérifier la navigation et l’upload des médias avec une taille proche de votre limite maximale attendue Tester la création de miniatures et la conversion si vous utilisez des plugins d’images Contrôler la connexion au tableau de bord et la stabilité des sessions après quelques redirections HTTPS Vérifier que les tâches planifiées (au moins les plus sensibles) terminent sans erreurs de temps ou de mémoire
Si vous constatez des erreurs après avoir durci, l’erreur donne souvent la direction. Par exemple, un “maximum execution time exceeded” pointe vers une limite trop basse sur une route particulière. Un “open_basedir restriction in effect” vous indique immédiatement qu’un chemin requis n’a pas été autorisé. On ajuste, au lieu de revenir en arrière à l’aveugle.
Cas concrets de problèmes rencontrés lors de corrections PHP
Pour rendre le sujet tangible, voici quelques scénarios typiques qui reviennent.
“Après durcissement, l’upload ne marche plus”
Le symptôme est fréquent quand upload_max_filesize ou post_max_size n’est pas aligné, ou quand un proxy au front a une limite plus basse. Un utilisateur tente un fichier, obtient une erreur dans WordPress, mais le PHP n’affiche rien.
Ce que j’ai appris sur le terrain : commencez par vérifier le max réel au niveau de la requête. Ensuite seulement, regardez php.ini. Les erreurs côté WordPress donnent parfois l’impression que PHP est en cause, alors que la limite réelle est ailleurs. L’alignement des couches évite de courir après un fantôme.
“Les erreurs PHP ne s’affichent plus, mais le support panique”
C’est l’effet attendu de la correction. Si display_errors était activé, l’équipe support se basait parfois sur ce qu’on voyait dans la page. Quand vous coupez, les symptômes deviennent moins visibles en frontal.
La solution opérationnelle : assurez-vous que les logs d’erreur PHP sont bien collectés et accessibles aux personnes qui diagnostiqueront. Un durcissement réussi est aussi un changement de méthode de support.
“Mise en place d’open_basedir, puis des plugins tombent en échec”
C’est presque inévitable si vous ajoutez des restrictions sans inventaire. Les plugins d’optimisation d’images, les outils d’import, ou certains connecteurs peuvent lire depuis des chemins non évidents. Parfois, ce sont des chemins de cache ou de fichiers temporaires.
Dans ces cas, le correctif n’est pas de désactiver open_basedir, c’est d’ajuster les répertoires autorisés au strict nécessaire, en surveillant les erreurs jusqu’à stabilisation.
“Sessions instables après verrouillage de la sécurité cookies”
Si votre reverse proxy ne remonte pas correctement “HTTPS”, forcer session.cookie_secure peut empêcher le cookie de session de s’envoyer. Résultat : déconnexion en boucle, ou redirections répétées.
La correction passe souvent par la configuration du proxy, pas uniquement par PHP. On s’assure que l’application reçoit bien le bon contexte de transport sécurisé.
Les limites de la “sécurité par configuration” en PHP
Il faut être honnête : durcir PHP réduit le risque, mais ne remplace pas les fondamentaux.
- Si un plugin WordPress est vulnérable, une configuration PHP plus stricte ralentit l’exploitation, mais elle ne la rend pas impossible par magie. Si WordPress est compromis via des identifiants, le durcissement PHP peut réduire certains effets secondaires, mais il ne nettoie pas la compromission. Si vous laissez des erreurs et des détails fuir, l’attaquant gagne du temps, même avec une configuration “correcte”.
C’est pour cela que je recommande de traiter PHP comme un pilier, pas comme un projet isolé. Un hardening WordPress efficace combine mises à jour, hygiène plugins, politique de mots de passe, règles d’accès au serveur, et durcissement runtime.
Où placer les changements : php.ini, pool PHP-FPM, et overrides
Un détail qui change tout : l’endroit où vous modifiez compte.
Selon l’hébergement, vous pouvez avoir :
- un php.ini global géré par le fournisseur, des overrides par vhost, une configuration par pool PHP-FPM, parfois des fichiers .user.ini (selon les réglages du serveur et le mode d’exécution).
La bonne pratique est de vérifier le “chemin” de configuration actif, et de comprendre ce qui prend réellement effet. Il serait dommage de corriger une valeur que PHP n’utilise pas dans votre cas, puis de conclure à tort que le hardening n’a pas fonctionné.
En cas de doute, validez avec un comportement observable et des logs. La sécurité se prouve plus par résultat que par intention.
Priorités de correction si vous devez choisir
Si vous n’avez pas https://gardewp.fr/securite-wordpress/ le temps, vous pouvez viser l’ordre qui apporte le plus de bénéfice par effort.
Une logique efficace : commencer par ce qui réduit la divulgation et les signaux visibles, puis encadrer les ressources et les uploads, et seulement ensuite appliquer les restrictions qui demandent plus de tests (comme open_basedir et les restrictions fonctionnelles).
Pour éviter de tomber dans une sécurité “en vitrine”, je privilégie toujours les changements qui ont un impact mesurable. Couper l’affichage des erreurs, réduire la signature, encadrer les tailles, puis durcir les accès distants et les répertoires. C’est progressif, et ça laisse une place à la validation.
Ce que je recommande comme méthode d’implémentation
Mon approche préférée ressemble à une discipline d’ingénierie, pas à un sortilège.
Documenter l’état actuel (au moins les valeurs qui posent problème). Écrire une intention simple pour chaque modification : quoi changer, et quel risque cela vise. Appliquer une ou deux corrections à la fois. Tester les fonctions sensibles, surtout uploads, connexion, et workflows de plugins. Conserver une trace de rollback et des observations log.
Cette méthode évite les ajustements “au feeling” et vous donne une trajectoire. Quand un site a plusieurs plugins, vous ne gagnez pas à tout verrouiller d’un coup, vous gagnez à comprendre ce qui casse et pourquoi.
Si vous faites tout cela, vous obtenez un bénéfice réel et durable : moins de fuites d’informations, moins de marge de manœuvre pour l’exploitation, et un comportement plus prévisible dans les limites de ressources.
Si vous me dites votre environnement (Apache ou Nginx, PHP-FPM ou module, et ce que vous avez comme marges sur la taille des uploads et la mémoire), je peux proposer une liste de paramètres PHP typiques à vérifier dans votre contexte, avec les risques de régression les plus probables.