Dans cet article tu vas voir comment sécuriser ton site Wordpress avec le fichier .htaccess (qui vient de "hypertext access"). En effet, il est important de prendre du temps d'appliquer quelques règles simples de sécurité pour être sûr que ton site ne soit pas compromis.
Voici quelques règles de sécurité qui tu pourras appliquer à ton site internet. Pour cela tu devras t'assurer tout d'abord, que ton hébergeur te permette de modifier le fichier .htaccess
Ce fichier de configuration n'existe que sur Apache, donc pas la peine de le chercher sur Nginx ou LiteSpeed par exemple.
Avant tout, pense à effectuer un backup de ton site WordPress et de ta BDD, avant de modifier quoi que ce soit. Et si tu as un site de développement teste dessus, avant de faire ces modifications sur ton site en production. Enfin, à chaque modification, vérifie bien que tout ton site fonctionne bien, avant de mettre en place de nouvelles règles.
Il existe sur internet des générateurs de fichier htaccess.
Le fichier .htaccess permet de configurer ton serveur Web Apache. Il te servira à affiner des développements supplémentaires non prévus par certaines plateformes, à renforcer certains paramètres de sécurité sur certaines zones de son site, et à optimiser certains aspects de ton hébergement (organisation personnelle) ou de ton site internet.
Afin d’avoir une vue plus synthétique, j’ai regroupé dans 5 pouvoirs du fichier htaccess. Ces exemples sont prêts à l'emploi, mais restent à personnaliser selon ta configuration.
MaxClients < nombre-de-connexions>
# SetEnv TZ Continent/Pays
SetEnv TZ France/Paris
# PHP Memory Limit php_value memory_limit 256M
Les accents peuvent poser des problèmes si aucun codage de caractère n'existe. Pour cela, tu dois spécifier au fichier .htaccess, quel codage doit être utilisé pour chaque document type. Avec la directive suivante tu utiliseras le codage UTF-8 pour tous les documents (html, css, php, etc.) :
# Définir le codage de caractères
AddDefaultCharset utf-8
Si seuls quelques types de documents doivent être définis par codage, utilise cette directive :
# Définir le codage de caractères pour certains fichiers
AddDefaultCharset utf-8 .css .htm .html .xhtml .php
un des usages du fichier .htaccess est de rédiger des pages , que cela soit sur ton même site, ou sur un autre. Tout d'abord : rediriger une vieille page vers une nouvelle sur le même site internet :
RewriteEngine on
Redirect 301 /old.html /new.html
RewriteEngine on
Redirect 301 /old.html http://autresite/new.html
RewriteEngine on
Redirect 301 /docs/ http://new.example.com/docs/
RewriteOptions inherit
RewriteEngine On
RewriteRule ^(.*)$ https://page.html [R=301,L]
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
ewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^www.(.*)$ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www.(.*)$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteEngine on
rewritecond %{http_host} ^www.norfipc.com [nc]
rewriterule ^(.*)$ http://norfipc.com/$1 [r=301,nc]
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^www.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
RewriteEngine On RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://www.votredomaine.fr/$1 [R,L]
Devant une erreur d'accès à ton site internet, tes usagers recevront une page d'erreur prédéterminée codée . L'idéal est de créer ta propre page d'erreur personnalisée (avec ta charte graphique) avec une explication détaillée dans chaque cas d'erreur, la page d'erreur 404 est fondamentale.
ErrorDocument 404 / introuvable404.html
#Pour les autres types d'erreurs :
ErrorDocument 403/ nonautorise500.html
ErrorDocument 500 / erreur500.html
Remplacer la page dénommée maintenance.html par la page que sur laquelle tu souhaites rediriger le visiteur avec l’adresse IP voulue ( note la redirection 302 pour éviter l’indexation de cette page temporaire).
<FilesMatch "^.*(error_log|wp-config.php|php.ini|.[hH][tT][aApP].*)$">
Order deny,allow
Deny from all
</FilesMatch>
#htaccess file<files .htaccess>order allow,denydeny from all</files>
La façon la plus sûre de protéger l'accès à un répertoire complet de ton serveur, pour que l'on puisse y accéder seulement avec un login et un mot-de-passe, est d'utiliser la directive "AuthConfig".
Pour cela, 2 actions seront nécessaires :
AuthType Basic
AuthName "Ce repertoire est protégé"
AuthUserFile /chemin/.htpasswd
Require valid-user
Le Hotlinking permet à une tierce personne d’utiliser l’adresse d’un fichier publié sur ton site Internet, le plus souvent une image, et de l’afficher sur un autre site sans l’enregistrer sur son propre serveur. Cela entraîne une augmentation du volume de données sur ton site (le site d’origine), sans que tu ne puisses rien faire. La solution est de bloquer ces liens grâce à la directive suivante :
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http:// www.ton-domaine/.*$ [NC] [OR]
RewriteCond %{HTTP_REFERER} !^http://www.ton-domaine/.*$ [NC] [OR]
RewriteRule .*.(gif|GIF|jpg|JPG|bmp|BMP|wav|mp3|wmv|avi|mpeg)$ - [F]
Tu peux également autoriser Google Images, certains bots ou réseaux sociaux, en mettant cette directive :
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?norfipc.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?google.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?bing.com [NC]
#Permettre l'accès par URL
RewriteCond %{HTTP_REFERER} !^$
#Permettre l'accès des moteurs de recherche
RewriteCond %{HTTP_REFERER} !google. [NC]
RewriteCond %{HTTP_REFERER} !search?q=cache [NC]
RewriteCond %{HTTP_REFERER} !msn. [NC]
RewriteCond %{HTTP_REFERER} !yahoo. [NC]
#Permettre l'accès de robots
RewriteCond %{HTTP_USER_AGENT} !googlebot [NC]
RewriteCond %{HTTP_USER_AGENT} !msnbot [NC]
#Permittre l'accès de réseaux sociaux
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?pinterest.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?tumblr.com [NC]
RewriteRule .(jpg|jpeg|png|gif)$ - [NC,F,L]
Par défaut, le fichier index d’un répertoire est index.html, index.htm ou index.php. Si tu veux que ce soit un autre fichier, rajoute cette ligne :
DirectoryIndex about.html
Par exemple, si tu veux utiliser la page accueil.html comme page d’index, utilise la ligne suivante :
DirectoryIndex accueil.html
# Block WordPress xmlrpc.php requests
<Files xmlrpc.php>
order deny,allow
deny from all
allow from xxx.xxx.xxx.xxx
</Files>
C'est quand un hacker essaye de trouver les identifiants de connexion des utilisateurs d'un système (nom d'utilisateur à la fin d'une URL WordPress ou dans l'URL d'une page d'archive. avec le nom d'utilisateur il aura déjà 50% de chance de se connecter à ton site, il ne lui restera plus qu'à trouver ton mot-de-passe.
Pour cela, un hacker tentera d’entrer un certain nombre de noms d’utilisateurs et observera le comportement de l’application pour déterminer si un identifiant est valide ou non ( temps de réponse différents, message d’erreur différent et plus généralement toute différence au niveau réponse HTTP).
Le hacker pourra par exemple essayer de trouver des adresses email ou des personnes liées à sa cible sur des moteurs de recherche ou sur les réseaux sociaux. Donc attention de bien avoir un identifiant qui ne soit pas de type "admin", "mon nom", "mon adresse mail",etc.
Formulaire de connexion : Par exemple, en essayant de se connecter à WordPress, on aura le message "mot de passe incorrect", ce qui veut dire que l'identifiant tapé est bien existant, mais que son mot-de-passe ne l'est pas. Pour corriger cette vulnérabilité sur un formulaire de connexion (WordPress ou autre), il faut simplement faire en sorte que le message d’erreur renvoyé par l’application soit le même, quelle que soit la source du problème (nom d’utilisateur ou mot de passe).
Réinitialisation du mot-de-passe : Le problème se pose également sur la réinitialisation du mot-de-passe de connexion, pour cela il faut retourner un message du style « Si votre compte existe bien, un lien de réinitialisation de mot de passe vous sera envoyé dans quelques instants", que le compte existe ou pas. Cependant, si l’application envoie l’email de réinitialisation directement lorsque l’utilisateur valide son formulaire, un temps de latence plus grand sera observé si l’adresse email existe (si elle n’existe pas, cet envoi n’aura pas lieu). La solution est de faire en sorte que les emails ne soient pas envoyés directement lors du clic sur le bouton mais soit mis en attente et envoyés par un autre processus qui tournerait par exemple en tache planifiée toutes les X minutes.
Formulaire de création de compte : Comme pour le formulaire de récupération du mot-de-passe, il arrive souvent que les applications web informent les utilisateurs lorsqu’un identifiant est déjà existant, avec un message du genre "l'adresse email existe déjà". Sinon, tu auras plutôt un message du genre "votre compte a été créé, vous allez recevoir un email de confirmation dans quelques instants".
Les énumérations d'utilisateurs de connexion restent une trop grande source d’information pour de potentiels attaquants.
Pour les archives d'auteur, fais le test en mettant ton "URL/?author=1". Surprise, ça te mettra sûrement le nom "Admin" en plus. Voilà la moitié du travail du hacker est effectuée.
RewriteCond %{REQUEST_URI} !^/wp-admin [NC]
RewriteCond %{QUERY_STRING} author=d
RewriteRule ^ /? [L,R=301]
Ce code doit être placé après la ligne "RewriteEngine On"
et avant la ligne "RewriteBase /"
.
Cela fera une redirection 301 et redirigera vers la page d'accueil.
Une fois la directive ServerSignature à Off, le serveur n’affiche plus aucune information sur les pages d’erreur.
Aujourd'hui la majorité des plugins et thèmes n'ont pas besoin d'accès direct aux fichiers PHP dans leurs répertoires. La première partie du code fera que quand un hacker tente d'accéder à "monsite/wp-content/plugins, il aura une erreur 404 de page non-trouvée. Ce code est uniquement pour les fichiers PHP, par pour les autres fichiers statiques.
# Restraint l'accès aux fichiers PHP des répertoires de plugins et de thèmes
RewriteRule wp-content/plugins/(.*.php)$ - [R=404,L]
RewriteRule wp-content/themes/(.*.php)$ - [R=404,L]
# Si tu as besoin d'exclure cretains plugins à cette règle, colle ce code juste avant
# la règle précédente et remplace avec tes fichiers de plugins ou répertoires à exclure
RewriteCond %{REQUEST_URI} !^/wp-content/plugins/file/to/exclude.php
RewriteCond %{REQUEST_URI} !^/wp-content/plugins/directory/to/exclude/
Ce code doit être placé après la ligne "RewriteEngine On"
et avant la ligne "RewriteBase /"
.
Typiquement, tu as besoin que le répertoire d'uploads ait les accès en écriture pour le serveur web, pour y uploader des images et du contenu pour les mettre dans tes pages. Cependant, tu as besoin d'empêcher que des fichiers PHP soit ajoutés dans ton répertoire d'uploads. Par défaut, quand tu créé du contenu à travers le WP Admin Dashboard, WordPress a déjà une option de sécurité qui ne va permettre l'upload de fichiers PHP à travers le WP Admin Dashboard. Mais si tu as un thème ou un plugin mal écrit, un hacker pourra profiter de cette faille pour y injecter des fichiers PHP dans ton répertoire wp-content/uploads.
Créé un fichier ".htaccess" dans le répertoire "wp-content/" de ton site (et non dans le fichier .htaccess à la racine de ton site) et ajoutes-y cette règle qui va interdire l'upload de fichier PHP dans ton dossier /wp-content :
# Desactiver l'upload de fichier PHP dans /wp-content
<Files "*.php">
Order Deny,Allow
Deny from All
</Files>
Tu peux également n'accepter que certains types d'extensions avec ce genre de code :
# Desactiver l'upload de fichier avec
des extensions autre que Order deny,allow Deny from all <Files ~ ".(xml|css|js|jpe?g|png|gif
|pdf|docx|rtf|odf|zip|rar)$"> Allow from all </Files>
Par défaut, les serveurs Apache permettent l'exploration des fichiers et des répertoires. Pour éviter cela, il suffit d'ajouter ce bout de code dans ton fichier .htaccess
# disable directory browsing Options All -Indexes
Le dossier /wp-includes/ de WordPress contient les fichiers essentiels au bon fonctionnement de WordPress.
# Bloquer l'accès à /wp-includes/ <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^wp-admin/includes/ - [F,L] RewriteRule !^wp-includes/ - [S=3] RewriteRule ^wp-includes/[^/]+.php$ - [F,L] RewriteRule ^wp-includes/js/tinymce/langs/.+.php - [F,L] RewriteRule ^wp-includes/theme-compat/ - [F,L] </IfModule>
Le fichier wp-config.php contient des données essentielles pour ton site WordPress (nom de base de données, login utilisateurs, …). Il faudra donc protéger ce fichier via le bout de code suivant à placer dans le fichier .htaccess
# Restreindre l'accès au fichier wp-config.php <files wp-config.php> order allow,deny deny from all </files>
Il faut que tu évites les bots d'attaquer le wp-admin de ton site.
ErrorDocument 401 monsite.fr/index.php?error=404
ErrorDocument 403 monsite.fr/index.php?error=404
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{HTTP_REFERER} !^http://(.*)?monsite.fr [NC]
RewriteCond %{REQUEST_URI} ^(.*)?wp-login.php(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$
RewriteRule ^(.*)$ - [F]
</IfModule>
Tu dois penser à supprimer les fichiers d'installation de WordPress, après installation ils ne te serviront plus.
readme.html
/wp-admin/install.php
wp-config-sample.php
Les hackers qui essayent d’infecter ton site internet WordPress vont tenter de changer les variables GLOBALS et REQUEST. Cela sert à éviter les injections SQL que peuvent réaliser un hacker sur ton site, pour y installer un malware.
# Prevenir l'injection de script malicieuxOptions +FollowSymLinks RewriteEngine On RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR] RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR] RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2}) RewriteRule ^(.*)$ index.php [F,L]
Cela sert à éviter les scripts ou les injections malicieuses de JavaScript
#Ce code demande au navigateur de n'utiliser que des codes
#qui viennent de ton site WordPress :
header('Access-Control-Allow-Headers:X-WP-Nonce');
header('Content-Security-Policy: default-src self');
#Code pour éviter qu'un hacker n'utilise tout ton code pour
#le copier sur un site et se faire passer pour toi:
header('X-Frame-Options: SAMEORIGIN');
#Code pour prévenir du cross-site-attack (XSS attacks)
header('X-XSS-Protection: 1; mode=block');
header('X-Content-Type-Options: nosniff');
#Force le navigateur à n'utiliser que le HTTPS:
header('Strict-Transport-Security:max-age=31536000; includeSubdomains; preload');
# Code qui protège et sécurise tes cookies : demande au navigateur de croire
# uniquement les cookies envoyés par ton serveur
@ini_set('session.cookie_httponly', true);
@ini_set('session.cookie_secure', true);
@ini_set('session.use_only_cookies', true);
Si tu remarques que des personnes essayent de se connecter à ton site pour te hacker ou des bots, tu peux les bloquer grâce à leur adresse IP.
# Bloquer des adresses IP # Remplacer IP_ADDRESS_* avec l'adresse que vous voulez
# Pour bloquer uniquement une IP
Deny from 192.168.1.7
# Pour bloquer toutes les IP en 192.168
Deny from 192.168
# Pour bloquer un domaine
Deny from [email protected]
# Si tu souhaites bloquer tout le monde, sauf une IP
order deny,allow
deny from all
Allow from 192.168.1.7