Durcissement WordPress : configurer correctement les droits de fichiers

Quand on parle de durcissement WordPress, on pense souvent aux mises à jour, aux plugins de sécurité, à la protection du compte admin. C’est logique. Mais, sur le terrain, les problèmes de droits de fichiers et de dossiers finissent régulièrement par être la vraie faille ou, à minima, la source la plus fréquente de casse. Un site qui “marche chez moi” mais qui échoue en production après un déploiement n’a pas besoin d’un nouveau plugin. Il a besoin de permissions cohérentes, d’un propriétaire correct, et d’une stratégie de durcissement réaliste.

L’objectif ici n’est pas de mettre “le plus restrictif possible” par principe. Un durcissement utile est celui qui limite l’impact d’une compromission, réduit les erreurs humaines, et laisse WordPress fonctionner sans se contorsionner. Les droits sont une ligne de défense. Ils ne remplacent pas la sécurité applicative, mais ils changent l’ampleur des dégâts.

Le point de départ : comprendre à quoi servent les permissions

Sur un serveur https://gardewp.fr/securite-wordpress/ Linux, un fichier ou un dossier a des droits qui contrôlent qui peut lire, écrire et exécuter. Ces permissions s’appliquent à trois catégories d’acteurs :

    le propriétaire du fichier (souvent l’utilisateur du déploiement ou celui du serveur web), le groupe du fichier, le reste des utilisateurs.

En durcissement WordPress, le piège classique consiste à “réparer” rapidement un problème d’écriture en donnant des droits trop larges. Par exemple, passer un répertoire d’uploads en 777 peut débloquer l’upload, mais cela ouvre la porte à des écritures non attendues. Ce n’est pas “seulement” un risque technique, c’est une mauvaise assurance sur la durée.

Autre piège, plus sournois : des permissions incohérentes entre fichiers et dossiers. WordPress s’appuie sur certains dossiers pour écrire : uploads, parfois des répertoires de cache, selon la configuration, et des mécanismes de maintenance. Si vous durcissez sans savoir où WordPress écrit, vous allez déclencher des erreurs de type “impossible de créer le répertoire” ou “échec d’écriture sur le disque”.

Le bon compromis consiste à :

Conserver des droits “raisonnables” sur les fichiers du code (WordPress lui-même), Autoriser l’écriture uniquement dans les zones prévues, Garantir que le propriétaire et le groupe sont alignés avec le fonctionnement du serveur web, éviter les droits “monstrueux” qui n’apportent rien à la sécurité.

Ce que WordPress doit écrire, et ce qu’il ne doit pas

WordPress n’est pas un simple site statique. Il crée des éléments pendant la vie du site : médias, thumbnails, caches éventuels, mises à jour, fichiers temporaires. Pour un durcissement propre, il faut distinguer les zones.

En pratique, la plupart des environnements ont besoin d’écriture sur :

    wp-content/uploads pour les images et autres médias, certains répertoires temporaires selon le stockage choisi, possiblement des caches (variables selon plugins et configuration).

À l’inverse, le cœur de WordPress et la majorité des fichiers PHP ne devraient pas être modifiables par “n’importe qui”. Même en cas de vulnérabilité applicative, l’excès de droits sur le filesystem augmente la capacité de l’attaquant à poser une charge utile persistante (par exemple un fichier PHP dans un endroit non prévu).

Le point important n’est pas seulement “quelle permission”, c’est “quel utilisateur” écrit. Si le processus PHP tourne sous un utilisateur donné, c’est souvent lui ou un groupe précis qui doit être propriétaire ou avoir l’accès adéquat.

Nombres usuels : 644, 755, et pourquoi ils reviennent souvent

Les valeurs chiffrées résument les droits :

    644 correspond à lecture et écriture pour le propriétaire, lecture seule pour le groupe et le reste. C’est typiquement adapté aux fichiers. 755 correspond à lecture et exécution pour le groupe et le reste, et écriture uniquement pour le propriétaire. On le voit souvent sur des dossiers, ou sur des fichiers exécutables.

Dans une base WordPress “classique”, on retrouve très souvent un pattern :

    fichiers en 644 (ou 640 selon politique de groupe), dossiers en 755 (ou 750 selon politique de groupe), wp-config.php en droits plus restrictifs (souvent 600 ou 640 selon votre gestion des groupes).

Ces valeurs sont des conventions utiles, pas une loi universelle. L’environnement décide : Nginx ou Apache, utilisateur du serveur web, système de fichiers (ext4, NFS), mécanismes de déploiement, présence de containers, mode SELinux (sur certaines distributions), et type de stockage.

Le durcissement pertinent, c’est celui qui atteint le bon niveau de restriction tout en gardant une écriture fonctionnelle là où WordPress en a besoin.

image

Durcissement réaliste : privilégier le bon propriétaire plutôt que le bon chiffre

Quand je vois des sites “cassés” après une tentative de durcissement, l’origine est souvent la même : les droits ont été changés “à l’aveugle”. Le chiffre a été “durci”, mais le propriétaire a été laissé incohérent.

Si votre serveur web tourne sous www-data (cas fréquent avec Debian/Ubuntu) et que vos dossiers uploads sont la propriété d’un autre utilisateur (par exemple deploy), WordPress peut ne pas écrire, même avec des permissions “correctes”. À l’inverse, si tout appartient à l’utilisateur du serveur web et que les permissions sont trop ouvertes, l’attaquant qui obtient un accès applicatif dispose d’une surface d’écriture plus large.

La stratégie qui marche bien dans beaucoup d’installations consiste à :

    garder le code WordPress (hors wp-content/uploads) non modifiable par le serveur web, réserver la modification à des dossiers ciblés, sous un propriétaire ou un groupe maîtrisé, aligner wp-config.php pour limiter la lecture du fichier de configuration.

En clair, le “durcissement” n’est pas un concours de chiffres. C’est une cohérence d’accès.

Cas concret : erreurs d’upload, “permission denied”, et ce que ça signifie

Imaginez un site qui publie de nouvelles images mais qui échoue après un déploiement. Vous tentez un upload, WordPress affiche un message générique. Dans les logs PHP et du serveur web, vous voyez souvent “permission denied” ou une erreur lors de la création d’un sous-répertoire.

Dans un environnement bien configuré, les causes typiques sont :

    le dossier wp-content/uploads n’a pas les droits d’écriture pour l’utilisateur PHP, le propriétaire des sous-dossiers créés avant ou après le déploiement n’est pas identique, le groupe n’est pas aligné, un mécanisme de déploiement a changé les permissions sur tout le répertoire.

Le symptôme révèle un fait : WordPress essaie d’écrire, mais l’accès filesystem ne suit pas. Le durcissement utile consiste à corriger l’accès seulement sur ce qui doit s’écrire, et à stabiliser la politique pour que les prochains sous-dossiers créés héritent de la bonne structure.

Stabiliser l’héritage de droits : le duo groupe + “setgid” sur les dossiers

Un problème fréquent dans la durée est l’apparition de sous-dossiers dont les propriétaires ou groupes diffèrent. Par exemple, vous autorisez l’écriture dans uploads, puis un script de sauvegarde, un déploiement, ou un outil de CI réapplique des permissions. Résultat : certains sous-dossiers deviennent illégitimes pour l’utilisateur PHP.

La solution la plus pratique, dans un contexte Linux classique, consiste souvent à :

    choisir un groupe commun (par exemple www-data ou un groupe dédié), appliquer l’héritage de groupe aux dossiers à l’aide du bit setgid sur les répertoires concernés.

Ainsi, même si WordPress crée un nouveau sous-dossier, il hérite du groupe attendu. Vous réduisez les dérives et vous évitez de devoir “re-harmoniser” les permissions après chaque déploiement.

Le bit setgid ne résout pas tout, mais il limite considérablement les surprises. C’est aussi une approche qui respecte le principe de moindre surprise pour les équipes qui maintiennent le site.

image

Où durcir sans casser : wp-config.php, exécutables, et PHP

wp-config.php mérite une attention particulière. C’est le fichier qui porte des informations sensibles, notamment les paramètres de base de données et souvent des clés de sécurité. Le durcissement standard vise à empêcher toute lecture par des utilisateurs non nécessaires.

Sur beaucoup de serveurs, le bon équilibre est :

    600 ou 640 pour wp-config.php, propriété cohérente avec le serveur web ou un groupe dédié qui permet au PHP d’accéder au fichier.

Ensuite, regardez la configuration côté serveur. Nginx et Apache ont parfois des protections contre l’exécution de fichiers dans des répertoires précis. C’est un autre volet du durcissement, mais il travaille main dans la main avec les droits. Même si un fichier malveillant parvient à être écrit quelque part, si l’exécution PHP y est interdite, l’impact baisse.

Enfin, évitez de rendre les fichiers PHP “exécutables” à tort (ce n’est pas seulement une question de convention). Une permission trop permissive combinée à une confusion d’exécution côté serveur est un risque inutile.

Configurer et vérifier : une méthode de travail qui évite les dégâts

Avant de changer des permissions “en masse”, adoptez une logique de diagnostic. Vous gagnez du temps et vous évitez de vous retrouver avec un site partiellement cassé.

D’abord, identifiez sous quel utilisateur et groupe tourne PHP. Sur les systèmes classiques, c’est souvent visible dans la configuration de votre pool PHP-FPM, ou dans la configuration du service. Ensuite, identifiez le point d’écriture : wp-content/uploads est généralement le premier candidat.

Ensuite, observez les permissions actuelles. Une commande d’inspection suffit souvent à voir des valeurs surprenantes (par exemple des fichiers avec le bit d’exécution, ou des dossiers avec des permissions ouvertes). À ce stade, vous pouvez décider si vous devez corriger la structure uniquement dans certains dossiers ou si un déploiement a déjà tout chamboulé.

Voici une mini check-list, simple mais efficace, que j’utilise quand je dois remettre un WordPress en ordre :

    Vérifier l’utilisateur PHP-FPM ou le contexte d’exécution PHP (utilisateur et groupe). Vérifier les droits actuels sur wp-content/uploads et sur les dossiers de cache utilisés. Vérifier la propriété et le groupe de wp-config.php. Corriger en ciblant les répertoires qui doivent être modifiés, pas l’ensemble du code. Recontrôler les droits après le prochain déploiement, pour confirmer l’absence de dérive.

Cette approche évite le changement “chirurgical de chiffres” sans comprendre la cause.

Une règle pratique pour les permissions WordPress, avec nuances

Il n’existe pas une recette unique, mais une règle pratique revient souvent dans des environnements Linux standard où WordPress tourne via PHP-FPM et où vous voulez limiter les écritures.

Idée générale :

    le code PHP et les fichiers de configuration doivent être modifiables uniquement par les personnes ou processus de déploiement, l’écriture doit se concentrer sur uploads, les droits doivent permettre la lecture au serveur web, sans ouvrir trop large.

Dans cette logique, vous pouvez viser :

    wp-config.php : droits très restrictifs (protéger la lecture), fichiers applicatifs : lecture seule pour le serveur web, écriture seulement pour le propriétaire de déploiement, dossiers applicatifs : exécution et lecture nécessaires, écriture réservée, uploads : droits d’écriture nécessaires pour la création et la maintenance.

Les nuances importantes concernent les plugins de cache, certains gestionnaires de fichiers, et les scripts de maintenance. Certains plugins écrivent dans d’autres répertoires de wp-content. La “bonne” politique doit tenir compte de vos usages. Si vous activez un plugin qui écrit dans wp-content/cache ou ailleurs, il faut lui donner le bon chemin, pas de permissions générales sur tout le site.

Permissions vs umask : le détail qui fait la différence entre “ça marche” et “ça tient”

Même avec les bons droits, un détail modifie tout : la façon dont le système crée les nouveaux fichiers et dossiers. C’est piloté par la politique d’umask du processus. Si votre processus PHP-FPM a une umask qui “trop durcit” ou “pas assez durcit”, WordPress va créer des fichiers avec des permissions inattendues.

Résultat typique : vous corrigez un dossier, puis quelques jours plus tard l’upload ne passe plus, parce que de nouveaux sous-dossiers héritent d’une politique différente. D’où l’intérêt, encore une fois, de stabiliser l’héritage de groupe avec setgid et de comprendre l’umask.

Je recommande de traiter ça comme un système. Les permissions actuelles comptent, mais la création future compte tout autant.

Les risques d’un durcissement mal appliqué

Un durcissement mal appliqué ne se limite pas à “le site ne marche plus”. Il peut créer un risque de contournement.

Par exemple, si vous verrouillez trop uploads, l’équipe peut contourner en mettant un mode “temporairement” permissif. “Pour que ça marche”, on élargit les permissions, puis on oublie. À force, la permission permissive devient l’état normal, et vous perdez le bénéfice du durcissement.

Autre cas : si vous mettez des droits très stricts partout, WordPress n’écrit pas ses fichiers temporaires correctement. Les plugins peuvent retenter, stocker au mauvais endroit, ou échouer silencieusement. Les erreurs deviennent des signaux, mais elles sont souvent ignorées jusqu’au jour où un problème plus sérieux arrive.

Le durcissement doit donc s’accompagner d’une discipline : surveiller les erreurs liées au filesystem, conserver la cohérence des déploiements, et éviter les exceptions “anonymes”.

Déploiement et permissions : organiser pour ne pas régresser

Le plus gros facteur de dérive, c’est le déploiement. Un outil de CI, un script FTP, un rsync mal paramétré, un changement de propriétaire lors d’une extraction d’archive… tout cela peut redéfinir les permissions.

Une pratique saine consiste à décider une politique “à la source” :

    Qui dépose le code WordPress et avec quel utilisateur ? Quelle commande garantit la propriété et le groupe ? À quel moment applique-t-on les permissions ? Est-ce que les fichiers de uploads sont conservés tels quels ou reconstruits ?

Si vous déployez en récrivant tout le répertoire, vous devez être conscient que même uploads pourrait subir des changements. Or c’est souvent là que la permission devient critique. Dans les déploiements manuels, la tentation est de tout faire d’un bloc. Dans un durcissement mature, vous séparez le code et les données.

Quand vous séparez, vous réduisez le risque d’avoir à “corriger” ensuite. Et chaque correction est un risque de dérive future.

Cas particuliers : environnements partagés, NFS, Docker, et SELinux

Certains environnements ne se comportent pas comme un serveur Linux “standard”.

Avec un partage réseau (NFS), les permissions peuvent être interprétées différemment ou subir des contraintes de sécurité du système de fichiers. Avec Docker, le propriétaire vu à l’intérieur du conteneur n’est pas forcément identique à celui vu depuis l’hôte, et il faut gérer les mappings d’utilisateurs. Avec SELinux, les permissions Unix ne sont pas suffisantes. Vous pouvez avoir des chiffres “corrects” et quand même bloquer l’accès via une politique SELinux.

Dans ces cas, le durcissement doit inclure la couche de sécurité correspondante. Les droits Linux restent importants, mais ils s’ajoutent à d’autres contrôles, ou parfois ils ne suffisent plus.

Comment diagnostiquer rapidement sans se perdre

Quand quelque chose ne marche pas après changement de droits, il faut une approche rapide.

Regardez d’abord les logs du serveur web et PHP. Les erreurs “permission denied” indiquent très souvent le répertoire cible et le type d’opération (création, écriture, ouverture). Ensuite, comparez la propriété du fichier ou dossier avec l’utilisateur PHP.

Souvent, le problème n’est pas le chiffre en lui-même, mais la combinaison :

    propriétaire non attendu, groupe non aligné, droits trop restrictifs ou trop ouverts pour l’acteur réel.

Si vous avez stabilisé l’héritage de groupe, le problème se réduit à quelques cas. Sinon, vous vous heurtez à des dérives de sous-dossiers.

L’autre outil utile consiste à tester l’écriture depuis WordPress et observer la création réelle. Par exemple, uploader un média simple et regarder les permissions du nouveau sous-dossier. C’est plus parlant que d’espérer deviner.

Une approche “progressive” du durcissement

Je conseille rarement un durcissement radical “en une passe” sur un site en production, surtout si vous n’avez pas le contexte exact. Une stratégie progressive fait gagner en sérénité :

    d’abord, corriger les zones manifestement trop ouvertes, ensuite, harmoniser la propriété et le groupe sur ce qui doit être écrit, enfin, ajuster les droits des fichiers sensibles comme wp-config.php.

Cette méthode réduit les chances d’introduire une régression. Elle permet aussi d’observer si WordPress et vos plugins fonctionnent correctement avec la nouvelle politique.

Exemple de politique cohérente (sans recette unique)

Sans prétendre fournir une commande magique, une politique cohérente ressemble souvent à ceci dans l’esprit :

    fichiers du code WordPress : accessibles en lecture par le serveur web, modifiables seulement par le déploiement, dossiers du code : lecture et exécution pour traverser, écriture réservée, wp-content/uploads : écriture permise pour l’utilisateur PHP, wp-config.php : lecture fortement limitée.

Le “comment” dépend ensuite de votre architecture. Le “pourquoi” reste le même : limiter ce qui peut être écrit, et réduire la capacité d’un acteur malveillant à faire persister quelque chose dans le bon format et au bon endroit.

Si vous avez des plugins qui écrivent autre part, la politique doit s’étendre à ces emplacements précis, pas à “tout WordPress”.

Mesurer le succès : ce que vous devez constater après la correction

Un durcissement réussi se voit dans deux dimensions : fonctionnement et stabilité.

Fonctionnement, parce que les opérations WordPress qui touchent le filesystem (upload, création de thumbnails, éventuels caches) doivent fonctionner sans erreurs. Stabilité, parce que dans les jours qui suivent, vous ne devez pas constater une nouvelle dérive des permissions ou l’apparition progressive de répertoires “étrangers” (propriétaires inattendus).

Si vous avez un système de surveillance, associez-le aux symptômes typiques : erreurs PHP liées à l’écriture disque, messages de WordPress sur l’impossibilité de créer des répertoires, et alertes du serveur web.

Le durcissement, ce n’est pas un événement. C’est un état maintenu.

Points de vigilance autour des backups et des restore

Les sauvegardes peuvent aussi modifier les permissions lors d’un restore. Certaines archives stockent les permissions, d’autres non. Selon l’outil, les propriétaires et groupes peuvent changer. C’est particulièrement vrai quand on restaure sur un serveur dont les utilisateurs diffèrent.

En pratique, après un restore, il faut vérifier au minimum :

    wp-config.php, wp-content/uploads, et les répertoires de cache que vos plugins utilisent.

Même si le site “se charge”, un mauvais propriétaire sur uploads peut se révéler au moment d’un upload, donc plus tard, donc plus difficile à corréler.

Conclusion implicite : la sécurité vient de la cohérence

Le durcissement WordPress via les droits de fichiers n’est pas une affaire de mode, c’est une affaire d’architecture. Le bon niveau de restriction dépend de votre manière de déployer, de la façon dont PHP s’exécute, et des endroits où WordPress et vos plugins écrivent réellement.

Si vous retenez une idée, que ce soit celle-ci : visez la cohérence entre l’utilisateur d’exécution, la propriété, et les droits sur les zones d’écriture. Vous réduisez la surface d’attaque, vous diminuez les erreurs de maintenance, et vous obtenez un site plus stable, donc plus facile à protéger sur la durée.