Sécuriser WordPress : configurer .htaccess correctement

Sécuriser WordPress, ce n’est pas seulement “mettre des plugins”. C’est aussi comprendre le terrain sur lequel WordPress exécute du code PHP et répond à des requêtes HTTP. Quand un site tourne sur Apache, le fichier .htaccess reste un levier puissant, parce qu’il permet d’intervenir très tôt dans le traitement des requêtes: filtrage, redirection, contrôle d’accès, limitation de certains endpoints, et réduction de la surface exposée.

Le piège, c’est que .htaccess peut aussi casser votre site si vous le modifiez “au hasard”. Les règles de réécriture liées aux permaliens, les contraintes héritées du serveur, les particularités de votre thème ou de vos plugins (cache, sécurité, traduction, multilingue) peuvent entrer en conflit. L’objectif de ce billet est simple: vous aider à construire une configuration solide et réaliste, avec des garde-fous, et surtout avec une méthode pour valider chaque changement.

Avant de toucher à .htaccess : clarifier le contexte

D’abord, assurez-vous que votre site utilise bien Apache et que .htaccess est lu. Sur Nginx, ce fichier n’a aucun effet. Sur Apache, il dépend de la configuration du vhost: la directive AllowOverride doit autoriser les règles via .htaccess. Beaucoup d’hébergeurs le font par défaut pour WordPress, mais ce n’est pas garanti.

Ensuite, identifiez où placer les règles. La règle d’or: mettez-les dans le .htaccess à la racine WordPress (là où se trouvent généralement index.php, wp-admin, wp-content, wp-includes). Si votre hébergeur a déjà mis des lignes de base liées aux permaliens, votre fichier n’est pas “vide”, et les directives doivent s’insérer proprement.

Enfin, faites preuve d’hygiène de travail. Une copie du fichier actuel, un changement à la fois, et un test immédiat côté navigation et côté API. Sur des sites vivants, je privilégie une fenêtre de maintenance courte ou, au minimum, des tests en navigation privée. Il suffit d’une règle trop agressive pour déclencher des boucles de redirection ou empêcher des appels AJAX.

Comprendre les risques typiques

Une partie des risques vient de votre propre logique de sécurité. Par exemple:

    Bloquer wp-admin trop strictement peut casser des fonctionnalités légitimes, comme le backend de certains plugins, les webhooks, ou l’accès nécessaire à des prestataires. Désactiver l’exécution de PHP dans des répertoires sensibles est généralement bénéfique, mais il faut le faire dans les bons dossiers. Certains plugins dépendent de fichiers PHP dans des emplacements qui ne sont pas “évidents” au premier coup d’œil. Restreindre xmlrpc.php peut réduire le bruit d’attaques, mais certains outils de publication ou de synchronisation peuvent en dépendre (et les sites multilingues ou certains plugins y font parfois référence).

Le bon réflexe consiste à décider, pour chaque directive, qui est censé être bloqué ou autorisé, et dans quel scénario. Le reste relève de la précision.

Un socle pragmatique pour WordPress (Apache)

Voici des blocs qu’on rencontre souvent dans des .htaccess WordPress bien tenus. Je les présente comme une boîte à outils, parce que vous n’êtes pas obligé d’appliquer tout. Le plus important est de comprendre ce que chaque bloc vise.

1) Empêcher la liste de répertoires et réduire certains détails

Par défaut, lister un dossier (“directory listing”) est rarement utile sur un site WordPress. Une règle simple consiste à désactiver l’affichage des répertoires et à bloquer l’accès aux fichiers cachés non nécessaires.

Options -Indexes Require all denied

Le point d’attention: certains fichiers cachés peuvent être requis selon des outils d’exploitation ou de déploiement. Sur WordPress standard, c’est généralement OK, mais si vous utilisez un processus de maintenance particulier, testez.

2) Protéger le fichier wp-config.php

wp-config.php contient des identifiants, des clés de sécurité et des paramètres. Même si WordPress protège généralement ce fichier, une redondance côté serveur est une bonne pratique.

Require all denied

Selon votre version d’Apache, Require all denied peut être le bon choix. Si votre hébergement utilise un modèle plus ancien, des syntaxes basées sur order deny,allow peuvent exister, mais je ne les reproduis pas ici pour éviter d’orienter vers une configuration incompatible. L’idée, c’est la même: empêcher la lecture.

3) Limiter l’accès à certains fichiers sensibles

On peut restreindre l’accès à des fichiers que des attaquants ciblent régulièrement: sauvegardes, fichiers temporaires, scripts “artisanaux”, etc. Le but n’est pas d’imaginer une liste universelle parfaite, mais de couvrir des cas courants.

Require all denied

Si vous générez des sauvegardes dans le dossier webroot, ce sera bloqué. C’est souvent un bon résultat, mais si votre stratégie de backup repose sur la présence de fichiers dans ces répertoires, il faut déplacer ou adapter.

Sécuriser l’exécution dans wp-content : le point où beaucoup se trompent

Un scénario fréquent: un attaquant réussit à injecter ou déposer un fichier malveillant dans un répertoire accessible web. Si, ensuite, le serveur exécute du PHP dans ce répertoire, l’impact grimpe.

Dans WordPress, le chemin le plus logique concerne wp-content/uploads, car les médias sont censés être des images, des PDFs, des fichiers vidéo. Sur Apache, le blocage de l’exécution PHP dans uploads est généralement une bonne idée, avec une condition: ne pas bloquer des cas où des plugins peuvent s’appuyer sur du PHP dans d’autres sous-répertoires.

Un modèle très courant:

Require all denied

Mais appliqué globalement, c’est dangereux. À la place, vous pouvez cibler uploads uniquement, en évitant d’impacter d’autres dossiers.

Selon la manière dont votre serveur gère la réécriture et les handlers, une approche plus ciblée ressemble à ceci:

Require all denied

Cependant, le chemin exact dépend de votre installation et de votre environnement d’hébergement. Et surtout, dans un .htaccess, le bloc n’est pas toujours traité de la même façon que dans un vhost. C’est pour ça que, dans beaucoup de .htaccess WordPress, on préfère un ciblage par chemins relatifs ou des règles conçues pour l’environnement.

Dans la pratique, si vous n’êtes pas sûr du comportement de votre hébergeur, commencez petit: bloquez uniquement des fichiers, pas des répertoires entiers, ou testez d’abord en copiant la logique sur un environnement de staging.

xmlrpc.php : réduire la surface sans casser l’usage

xmlrpc.php est un endpoint qui sert à des intégrations et à des méthodes de communication. Il est aussi très souvent ciblé dans des attaques liées à la découverte de comptes et à des tentatives de connexion.

Vous pouvez le restreindre, soit en le bloquant totalement, soit en le limitant à certaines IP. La première option est efficace mais peut casser des outils de publication. La seconde demande que vous connaissiez les IP sources autorisées (par exemple votre proxy, vos serveurs de CI, votre réseau d’administration).

Une règle “bloquante” simple:

Require all denied

Si vous choisissez une restriction par IP, il faut adapter à votre infra. Par exemple, autoriser un sous-réseau interne et refuser le reste.

Ici, je fais un point “terrain”: sur des sites qui utilisent des clients mobiles ou des connecteurs spécifiques, désactiver xmlrpc.php peut déclencher des erreurs de synchronisation. Avant de le supprimer, testez avec un exemple réel, celui que vous utilisez déjà, et pas avec un cas théorique.

wp-admin et la couche d’authentification : attention aux effets de bord

Restreindre wp-admin est tentant, parce que c’est là que vivent les actions d’administration. Mais il faut distinguer deux choses:

    Vous voulez éviter les tentatives automatiques sur des écrans d’administration. Vous devez garantir que vos accès légitimes continuent de fonctionner.

Dans beaucoup de contextes, une protection par .htaccess repose sur une authentification HTTP (basic auth, digest, ou autre). Sur WordPress, cela crée une double barrière, et c’est parfois un bon compromis, surtout si votre hébergeur ne propose pas d’autre contrôle.

Mais pour rester concret: si vous utilisez déjà un plugin de sécurité ou un reverse proxy qui filtre avant Apache, ajouter une authentification peut rendre le débogage pénible. Les erreurs HTTP se mélangent, et certaines connexions (par exemple des robots de monitoring, https://gardewp.fr/securite-wordpress/ des API internes) nécessitent des ajustements.

Je conseille généralement d’approcher wp-admin de façon graduelle: d’abord ajouter des règles de filtrage basées sur des critères simples (fichiers et endpoints), puis seulement ensuite, si c’est pertinent, ajouter une couche d’accès contrôlé.

Ne cassez pas les permaliens : préserver la réécriture WordPress

WordPress repose sur la réécriture d’URL. Votre .htaccess contient souvent un bloc mod_rewrite du type “si le fichier n’existe pas, rediriger vers index.php”. Si vous ajoutez des règles trop agressives ou si vous les placez au mauvais endroit, vous pouvez casser la navigation.

image

Un bloc typique de base (les lignes exactes peuvent varier selon votre version et votre configuration) ressemble à:

RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %REQUEST_FILENAME !-f RewriteCond %REQUEST_FILENAME !-d RewriteRule . /index.php [L]

Le conseil pratique: placez les règles de sécurité après le bloc WordPress de permaliens si elles ne sont pas censées interférer avec la réécriture, ou avant si elles ciblent des chemins clairs et que vous avez testé. Je préfère un ordre “lisible”: d’abord la partie WordPress (réécriture), ensuite les protections qui ne doivent pas modifier les routes.

Testez ensuite trois scénarios: page d’accueil, une page en permalien (post ou page), et une action back-office simple (connexion, accès au tableau de bord, chargement d’un média dans la médiathèque).

Exemple de montage: .htaccess “raisonnable” à adapter

Voici un exemple de fichier cohérent, pensé pour rester “raisonnable”. Il ne prétend pas couvrir tous les cas, il illustre des patterns.

Options -Indexes Require all denied Require all denied Require all denied # Optionnel selon vos besoins # # Require all denied # RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %REQUEST_FILENAME !-f RewriteCond %REQUEST_FILENAME !-d RewriteRule . /index.php [L]

Notez que j’ai laissé xmlrpc.php en commentaire, justement parce que c’est le genre de décision qui doit être prise en connaissance de vos usages.

Si vous ajoutez ensuite des règles d’exécution PHP dans uploads, faites-le avec prudence et testez sur un environnement de préproduction quand c’est possible.

Ce qu’on gagne, ce qu’on perd : arbitrages réalistes

Les règles .htaccess ont un mérite: elles sont exécutées tôt, avant WordPress. Résultat, certaines requêtes “malveillantes” sont stoppées sans consommer de ressources PHP.

Mais il y a des coûts. Bloquer trop large peut:

    empêcher l’accès à des fichiers utiles pour le déploiement ou la maintenance, compliquer les logs et le support (les erreurs 403 deviennent fréquentes), casser des plugins qui s’attendent à certains chemins.

Je me méfie particulièrement des solutions qui interdisent “tout ce qui ressemble à PHP” dans des répertoires trop larges. Sur WordPress, beaucoup de choses passent par wp-admin et par des routes qui doivent être traitées. Une règle qui “marche” sur un site propre peut se retourner contre vous dès que vous activez un plugin de commerce, de réservation, ou un module de formules.

Le bon équilibre, c’est la granularité: cibler les fichiers sensibles, éviter les interdictions globales, et limiter les restrictions aux endpoints réellement exposés.

Valider après chaque modification : une discipline qui évite la panique

Quand un .htaccess casse un site, c’est parfois immédiat. D’autres fois, vous ne voyez le problème qu’au chargement d’une fonctionnalité précise. C’est pour cela que la validation doit couvrir le front et le back, pas seulement “le chargement d’une page”.

Voici une checklist courte, que j’utilise pour éviter les retours en arrière:

    Sauvegarder le .htaccess précédent avant chaque série de changements Tester au moins une URL en permalien et une page d’administration Vérifier le chargement des médias (médiathèque) après les règles sur uploads Contrôler les réponses HTTP avec une navigation privée (pour éviter le cache navigateur) Refaire un test de connexion si vous avez touché à wp-admin ou à xmlrpc.php

Cela paraît “bureaucratique”, mais c’est ce qui vous évite de passer une heure à chercher un plugin suspect alors que la cause est juste une directive mal placée.

Deux pièges fréquents à éviter

1) Mélanger les syntaxes sans comprendre la version d’Apache

Votre hébergement peut utiliser une logique de contrôle d’accès basée sur Require. D’autres environnements utilisent des directives Order et Allow. Mélanger les deux peut donner des comportements inattendus, parfois silencieux.

La règle de bon sens: copiez des exemples qui utilisent la même logique que votre .htaccess actuel, ou vérifiez le comportement via un test simple (par exemple tenter d’accéder à wp-config.php et observer le statut HTTP).

2) Empiler des règles provenant de plugins

Beaucoup de plugins de sécurité ajoutent leur propre bloc dans .htaccess. Si vous ajoutez en plus des règles manuelles, vous pouvez créer des doublons, voire des contradictions.

Je recommande de lire le fichier complet avant d’ajouter. Cherchez les sections BEGIN/END ou les marqueurs de plugin. Quand c’est possible, regroupez les objectifs: certains plugins gèrent déjà la sécurité de xmlrpc.php ou de certaines URL, et vous n’avez pas besoin de refaire la même chose.

Comment rendre votre configuration durable

Un .htaccess sécurisé, ce n’est pas seulement un fichier “plus dur”. C’est aussi un fichier maintenable.

Je vous conseille de:

    documenter chaque bloc par une phrase courte dans un commentaire, garder les règles de sécurité centrées sur des objectifs clairs (fichiers sensibles, répertoire des médias, endpoints), éviter les règles “magiques” copiées-collées qui n’ont pas de raison d’être sur votre site, surveiller vos logs erreurs Apache quand vous appliquez des restrictions 403 ou des redirections.

Si votre hébergement fournit un accès aux logs, regardez la fréquence des erreurs après mise en place. Une augmentation des 403 peut être attendue, mais une hausse brutale sur des routes normales indique souvent une règle trop large.

Exemple de décisions “à prendre” avant de bloquer

Pour terminer, la partie la plus importante n’est pas technique, elle est décisionnelle. Avant de bloquer xmlrpc.php ou de restreindre wp-admin, posez-vous une question simple: “Qui a besoin de cet accès, depuis où, et à quelle fréquence ?”

Quand vous répondez, vous gagnez en précision.

Voici les points à adapter dans votre cas, selon votre réalité:

    Si vous bloquez xmlrpc.php, confirmez que vos outils de publication ne l’utilisent pas Si vous restreignez wp-admin, listez vos IP d’administration (ou votre méthode d’accès) Si vous bloquez l’exécution PHP dans uploads, testez la médiathèque et l’upload Si vous bloquez des extensions de fichiers, vérifiez vos habitudes de backup et de déploiement Si vous ajoutez des règles de fichiers cachés, contrôlez les besoins de vos outils de maintenance

Un dernier mot sur la méthode, pas sur le bricolage

Le fichier .htaccess n’est pas un “bouton sécurité”. C’est un mécanisme d’arbitrage à grande vitesse. Quand il est bien configuré, il stoppe avant WordPress, donc avant la charge PHP et parfois avant une partie de la logique applicative.

Quand il est mal configuré, il casse des fonctionnalités sans expliquer clairement pourquoi, et vous finissez par soupçonner le mauvais composant.

Le bon rythme consiste à avancer par petites étapes, à tester chaque fois, et à considérer .htaccess comme une couche de défense spécialisée. Ajoutez des protections qui ont un sens sur votre architecture, et laissez le reste aux bonnes pratiques côté WordPress: mises à jour, mots de passe solides, limitation des tentatives, durcissement via des rôles cohérents et sauvegardes testées.

Si vous voulez, décrivez votre cas (hébergeur, version Apache, présence d’un cache ou d’un reverse proxy, et si vous utilisez multilingue ou des plugins spécifiques). Je peux vous proposer une variante de .htaccess plus proche de votre environnement, avec l’ordre des blocs pour éviter les conflits.