Sécuriser WordPress doit être la première préoccupation après l’installation d’un site sur un hébergement. Cet article présente des directives à ajouter au fichier .htaccess pour protéger son site.
Ne croyez pas que votre site n’intéresse pas les pirates de l’Internet. Leurs attaques sont systématiques, et ils exploitent toutes les failles qu’ils peuvent trouver. En prenant le contrôle de votre site, ils peuvent modifier l’affichage de certaines pages, l’utiliser pour envoyer des spams ou créer des liens pour améliorer leur référencement. Bilan, votre site risque d’être bloqué par votre hébergeur ou banni par les moteurs de recherche en plus de faire de vous le complice involontaire d’escrocs, mafieux et autres terroristes. Autant tout faire pour éviter ce type de conséquences.
À noter : le codex WordPress consacre une page à la façon de sécuriser un site WordPress (en anglais).
Haut de pageGénéralités sur le fichier .htaccess
Un article de présentation du fichier .htaccess est disponible dans la documentation Apache. Retenez notamment que :
- si vous avez accès à la configuration du serveur (ce qui n’est généralement pas le cas sur un hébergement mutualisé), il vaut mieux insérer les directives dans un fichier de configuration d’Apache,
- les directives contenues dans un fichier .htaccess situé dans un répertoire s’appliquent à ce répertoire mais aussi aux répertoires de niveau inférieur.
Où se situe le fichier htaccess ?
Le fichier .htaccess se situe notamment dans le répertoire racine du site. Dans ce cas, les directives s’appliquent à l’ensemble du site. Il est possible d’avoir aussi des fichiers .htaccess dans certains sous-répertoires afin que les directives ne s’appliquent qu’à une partie du site.

Créer, modifier et transférer le fichier .htaccess
Si vous avez personnalisé des permaliens, WordPress a inséré des directives dans un fichier .htaccess qu’il a éventuellement créé.
Le fichier .htaccess est un fichier texte qui peut être créé et modifié avec un éditeur de texte (pas un traitement de texte comme Microsoft Word qui va inclure du formatage incompréhensible par Apache). Le codage UTF8 sans BOM, celui utilisé pour les fichiers WordPress, convient aussi pour le fichier .htaccess.

Pour transférer un fichier .htaccess vers un hébergement, vous pouvez utiliser un client FTP comme FileZilla :

À noter :
- si vous n’êtes pas familier des directives du fichier « .htaccess », je vous conseille de lire d’abord l’article Redirections d’adresses HTTP pour WordPress,
- si en testant des modifications celles-ci ne semblent ne pas fonctionner, penser à forcer le rechargement de la page testée en tapant en même temps sur les touches CTRL et F5 . Sinon, il se peut que l’affichage s’effectue depuis le cache mémoire de votre navigateur, sans solliciter Apache,
- certaines erreurs peuvent conduire au blocage brutal du serveur Apache; personne ne pourra accéder au site tant que l’erreur n’aura pas été corrigée ! Soyez donc très prudent, testez si possible en local vos modifications avant de les reporter sur le site de production :
Sécuriser WordPress – Une erreur dans htaccess peut rendre le serveur inutilisable
Protéger fichiers et répertoires
Ne pas afficher le contenu des répertoires
Par défaut, si l’adresse internet correspond à un répertoire, Apache affiche la liste des fichiers qu’il contient. Par exemple, « https://dfarnier.fr/mon/contenu/plugins » permet d’afficher la liste des extensions (plugins) installées sur le site WordPress. C’est fournir des informations utiles pour qui voudrait pirater le site, et c’est totalement inutile à qui veut le consulter. Le code ci-dessous permet d’empêcher cet affichage du contenu des répertoires :
Voici désormais ce qui s’affichera en réponse à une requête http correspondant à l’adresse d’un répertoire :

Ne pas afficher wp-config.php
Le fichier « wp-config.php » contient des informations sensibles, à commencer par les codes de connexion à la base de données. Les directives ci-dessous interdisent son accès depuis internet :
À partir de ce moment, toute personne saisissant l’url du fichier « wp-config.php » dans la barre d’adresse de son navigateur se verra retourné un message du type :

Cette protection devient particulièrement efficace si le site est situé dans le répertoire qui représente la racine Internet pour Apache. Ce répertoire est souvent appelé « www ». En plaçant le site dans ce répertoire et le fichier wp-config.php un niveau au-dessus, on est assuré qu’Apache n’affichera jamais le contenu du fichier wp-config.php sur Internet.

Attention : ne laissez pas traîner non plus d’anciennes versions du wp-config.php dont vous avez modifié le nom. Regardez cet extrait d’une attaque réelle où le pirate recherche différentes variantes :

Protéger des fichiers sensibles
Protéger les fichiers « techniques »
Voici des directives qui permettent d’empêcher la lecture des fichiers « .htaccess », « .htpasswd » (pour les mots de passe), « .ini » et « .log » depuis Internet :
Protéger les fichiers de programmes
Les répertoires « includes » et « wp-admin/includes » contiennent des fichiers de programme de WordPress. Il n’y a pas de raison que ces fichiers soient lus via Internet.
Voici des directives à insérer dans le fichier .htaccess situé à la racine du site :
- [F] est un drapeau Apache qui veut dire Interdit (Forbidden ). Quand la requête HTTP s’adresse à un fichier correspondant à la « RewriteRule », Apache renvoie l’erreur « 403 »,
- [S=3] permet de ne pas traiter les 3 directives suivantes si le fichier demandé n’est pas situé dans le répertoire « wp-includes » situé à la racine.
Autoriser la lecture du fichier wp- tinymce.php
« Tinymce » est l’éditeur qui permet de rédiger les articles et pages. Son bon fonctionnement nécessite que le fichier wp-tinymce.php soit accessible depuis Internet. Les directives suivantes sont à insérer dans un fichier .htaccess situé dans le répertoire wp-includes :

On remarque le fonctionnement en cascade des fichiers .htaccess :
- celui situé à la racine du site interdit la lecture via Internet des fichiers « .php » dans tous ses sous-répertoires,
- mais comme celui situé dans le sous-répertoire « wp-includes » autorise la lecture du fichier « wp-tinymce.php », ce fichier situé dans un sous-répertoire de « wp-includes » pourra être lu.
Bannir des adresses dangereuses
Vous avez détecté une adresse IP correspondant à une tentative d’accès malintentionnée. Vous souhaitez l’empêcher d’accéder à votre site avant qu’elle ne réussisse une intrusion. Utilisez le code suivant, en modifiant les adresses IP :
Il est aussi possible :
- de bloquer des plages d’adresses. Par exemple, pour bloquer les adresses commençant par « 123.45.67 », ajouter la ligne : deny from 123.45.67,
- de bloquer plusieurs adresses en les indiquant sur la même ligne séparées par un caractère blanc ( exemple : deny from 123.45.67.89 98.76.54.32),
- de bloquer des domaines. Par exemple, pour bloquer le domaine »domaine.tld », ajouter la ligne : deny from domaine.tld (exemple : deny from dfarnier.fr).
La documentation Apache indique que : « Les directives Allow
, Deny
, et Order
fournies par le module mod_access_compat
sont obsolètes, et sont appelées à disparaître dans les versions futures. Il est donc déconseillé de les utiliser, et de se fier aux tutoriels qui recommandent leur utilisation. »
Il faut se méfier de cette recommandation, car la version d’Apache installée sur un hébergement n’est pas forcément à jour. Voici un code qui doit fonctionner quelle que soit la version d’Apache que vous utilisez :
Quelques explications :
IfModule authz_core_module>…. IfModule>
- les directives situées entre IfModule et /IfModule ne seront exécutées que si le module authz_core_module est installé (la version d’Apache doit être au moins la 2.3)
<RequireAll> … RequireAll>
- les directives contenues entre RequireAll et /RequireAll devront toutes être vérifiées pour qu’Apache continue à analyser le fichier .htaccess. Si une directive n’est pas vérifiée, Apache refusera l’accès
Require all granted
- indique que, par défaut, toutes les requêtes http sont acceptées
Require not ip 123.45.67.89
- les requêtes http provenant de l’adresse IP « 123.45.67.89 » sont rejetées ( autrement dit, l’accès au site est refusé),
- vous pouvez ajouter autant de lignes « Require not » que nécessaire,
- vous pouvez mettre plusieurs adresses IP sur la même directive en les séparant par des caractères blancs ( exemple : Require not ip 123.45.67.89 98.76.54.32),
- il est aussi possible de filtrer en fonction du nome de domaine (voir des exemples dans la documentation Apache)
Comment repérer les adresses à bannir ?
Les accès douteux peuvent être identifiés dans le fichier journal ( ou fichier log ) qui retrace toutes les demandes d’accès (requêtes HTTP). Pour l’hébergement que j’utilise, ce sont les logs « web » :

Une fois le fichier log ouvert, rechercher la chaîne « 404 » (blanc + 4 + 0 + 4 + blanc) qui permet de retrouver les demandes d’accès à des pages non trouvées par le serveur HTTP. On trouve par exemple ceci :

- le 404 trouvé se situe après l’indication du protocole utilisé (HTTP/1.1); il s’agit du code HTTP indiquant que la page demandée n’a pas été trouvée par le serveur HTTP,
- l’adresse demandée et non trouvée est « wp-content/plugins/wysija-newsletters/readme.txt »
- l’adresse IP du demandeur est « 185.13.38.146 »
Ce n’est pas parce qu’une adresse n’est pas trouvée qu’il faut immédiatement bannir l’adresse IP du demandeur. Mais en cherchant « wysija-newsletters/readme.txt » dans un moteur de recherche, on découvre qu’il s’agit d’une vulnérabilité connue du plugin « mailpoet » dont l’ancien nom était « wysija ».
Comme je n’utilise pas cette extension pour mon site, une telle requête n’a pas de raison d’être. Je préfère bannir l’IP car, si cette attaque ne peut pas aboutir, l’assaillant peut lancer d’autres attaques qui pourraient finir par lui permettre de pénétrer mon site.
Il est utile de rechercher régulièrement dans vos logs les requêtes ayant abouti à une réponse « 404 ».
Certaines peuvent correspondre à des adresses de votre site qui ont disparues (suite à un renommage d’article par exemple). Dans ce cas, il faut envisager de mettre en place une redirection permanente.
D’autres erreurs 404 correspondront à des tentatives d’intrusion dans votre site pour lesquelles vous bannirez les adresses IP.
Limiter l’accès à l’administration du site
Le code suivant permet de réserver l’accès à l’administration via Internet à un nombre limité d’adresses IP; il doit être placé dans un fichier .htaccess situé dans le répertoire « wp-admin » :
Avertissement : ceci ne peut être utile que si les utilisateurs devant accéder à l’administration (administrateurs, rédacteurs..) :
- sont en nombre limité,
- ont des adresses IP qui sont fixes ou ne changent pas souvent,
- n’ont pas besoin d’accéder à l’administration lorsqu’ils sont en déplacement.
Dans le cas contraire, vous allez devoir modifier en permanence le fichier .htaccess, ce qui représente chaque fois un risque faire tomber votre site.
Attention : le fichier « admin-ajax.php » qui se trouve dans le répertoire « wp-admin » doit être accessible dès lors qu’un thème ou une extension utilise le fonctionnement en ajax (Asynchronous JavaScript and XML). Voici un code qui permet d’autoriser explicitement l’accès au fichier « admin-ajax.php » (à placer dans le fichier .htaccess situé dans le répertoire wp-admin) :
Haut de pageBloquer l’exécution des programmes php dans uploads
Le répertoire « uploads » est utilisé pour le chargement des fichiers médias. Il peut représenter une porte d’entrée permettant à un pirate de télécharger des fichiers de programmes sur votre site puis de les exécuter.
Il n’y a aucune raison dans le fonctionnement de WordPress de vouloir exécuter un fichier php situé dans le répertoire « uploads ». Voici comment l’empêcher.
Le fichier « uploads » se trouve dans le répertoire « wp-content, » au même niveau que les fichiers de thèmes et d’extensions (plugins); dans l’exemple ci-dessous, pour améliorer la sécurité, nous avons remplacé le répertoire « wp-content » par le répertoire « contenu » :

Dans le répertoire « uploads » créer un fichier « .htaccess » :

Ajouter les directives suivantes dans le fichier « .htaccess » :
Haut de page
Pile poil ce que je cherchais, merci, je rajoute dans mes favoris!!!