Après avoir optimisé le blog j’ai décidé de sécuriser WordPress. On trouve pas mal de guides sur ce thème sur internet mais peu d’entre eux recensent toutes les manipulations à effectuer. On est donc parti pour un mémo assez long détaillant comment sécuriser WordPress (efficacement) et sa configuration web / mysql.
Si vous hébergez votre blog sur un serveur dédié ou sur un VPS je vous conseille de ne pas seulement sécuriser WordPress mais aussi de déployer HTTPS et de le sécuriser.
Sécuriser WordPress : Installation du CMS
La sécurisation de WordPress commence dès son installation. Lors de ce processus vous devrez renseigner :
- le nom de votre base de données
- un utilisateur MySQL
- un mot de passe de connexion à MySQL
- l’adresse de votre base de donnée
- le préfixe des tables WordPress
Si vous étiez tentés d’utiliser les identifiants de l’utilisateur root NE LE FAITES ABSOLUMENT PAS. Préférez créer un utilisateur mysql dédié à WordPress.
Pour le nom de la base de données, le nom d’utilisateur MySQL et le mot de passe de connexion MySQL utilisez des identifiants générés aléatoirement. Le générateur de mots de passe LastPass est particulièrement utile pour cela.
Dans notre exemple nous utiliserons :
- R2a6jPv9FS7L3gH03q comme base de données
- 9g792V0GPkamKHuVT6 comme nom d’utilisateur
- Ps19Oamp40VRrUqG4878st comme mot de passe
Création d’une base de donnée et ajout d’un utilisateur MySQL
Via SSH
Connectez vous à votre instance MySQL via la commande suivante
mysql -u root -p
Indiquez le mot de passe de l’utilisateur root, puis créez la base de données R2a6jPv9FS7L3gH03q
CREATE DATABASE R2a6jPv9FS7L3gH03q;
Créez l’utilisateur 9g792V0GPkamKHuVT6 ayant Ps19Oamp40VRrUqG4878st comme mot de passe
CREATE USER 9g792V0GPkamKHuVT6@localhost IDENTIFIED BY 'Ps19Oamp40VRrUqG4878st';
Il faut maintenant accorder tous les privilèges à l’utilisateur 9g792V0GPkamKHuVT6 sur la base de données R2a6jPv9FS7L3gH03q
GRANT ALL PRIVILEGES ON R2a6jPv9FS7L3gH03q.* TO 9g792V0GPkamKHuVT6@localhost;
Rechargez les priviléges
FLUSH PRIVILEGES;
Vous pouvez maintenant quitter l’invite de commande MySQL
exit;
Via phpMyAdmin
Si vous n’avez pas d’accès SSH vous allez devoir utiliser phpMyAdmin.
Connectez vous à phpMyAdmin, créez la base de données R2a6jPv9FS7L3gH03q, créez l’utilisateur 9g792V0GPkamKHuVT6 ayant pour mot de passe Ps19Oamp40VRrUqG4878st
Vous pouvez maintenant vous connectez à votre site afin de terminer l’installation de WordPress.
Utilisez les identifiants crées précédemment. N’oubliez par de remplacer le préfixe des tables WordPress (wp_ par défaut) par des caractères aléatoires par exemple : Hyudzo487_
Modifiez le préfixe des tables sur un site WordPress existant
Vous avez déjà installé WordPress et vous n’avez pas changé le préfixe des tables. Sachez qu’il est toujours possible de les modifier.
Avant de vous lancer dans la modification du préfixe des tables existantes, effectuez une sauvegarde complète de votre base de données.
Pour cette opération je vous conseille d’utiliser adminer plutot que phpMyAdmin
Connectez vous à adminer et sélectionnez votre base de données. Cliquez sur « Exporter »
Un nouvel onglet va s’ouvrir dans votre navigateur avec tout le contenu de votre base de données. Copiez et collez ce code dans un fichier. Rechercher toutes les occurrences wp_ et remplacez les par le préfixe de votre choix. Sauvegardez ce fichier.
Vous pouvez maintenant vous reconnecter sur adminer, sélectionnez de nouveau votre base de données mais cette fois cliquez sur importer.
L’importation terminée éditez le fichier wp-config.php et rechercher la ligne suivante
$table_prefix = 'wp_';
Modifiez wp_ par le préfixe de votre choix.
Videz le cache de votre navigateur et connectez vous à l’interface d’administration de votre blog. Si tout fonctionne, vous pouvez supprimer les anciennes tables wp_
Création du compte administrateur
Une fois l’installation terminée vous allez devoir créer un administrateur. Je vous conseille d’utiliser un identifiant extrêmement difficile à deviner, par exemple : 0iz29k4u4RoOOC66Mq
Puis choisissez un mot de passe d’au moins 12 caractères contenant des majuscules, des minuscules, des chiffres et des caractères spéciaux.
Si vous avez déjà terminé votre installation de WordPress vous pouvez modifier l’identifiant de votre utilisateur via une requête SQL (remplacez Hyudzo487_ par votre préfixe de tables).
UPDATE Hyudzo487_users SET user_login = 'nouvel-identifiant' WHERE user_login = 'ancien-identifiant';
Sécuriser WordPress : les bases
Sauvegarder votre site régulièrement
Avant toute chose, commencez par mettre en place une sauvegarde quotidienne de votre site et de sa base de données, j’ai d’ailleurs récemment publié un article à ce sujet, une mauvaise manipulation est si vite arrivée. Si votre site n’est pas hébergé sur un VPS ou un serveur dédié effectuer ces sauvegardes via des plugins (UpdraftPlus Backup and Restoration semble être un bon choix).
Mettre à jour WordPress
Chaque mise à jour de WordPress comble des failles de sécurité, si vous n’effectuez pas ces MAJ vous augmentez considérablement le risque de voir votre blog se faire pirater. Il est tout aussi important de mettre à jours les plugins que vous avez installés.
Masquer le numéro de version de votre site WordPress
Par défaut il est extrêmement simple de connaitre la version de WordPress installée sur un site : elle apparaît dans les sources du site, dans les sources du flux RSS et dans le fichier README.html.
Commencez donc par supprimer le fichier README.html. Maintenant pour masquer la version de WordPress installée sur votre serveur ajoutez dans le fichier functions.php
de votre thème le code suivant :
remove_action('wp_head', 'wp_generator'); function remove_wp_version_rss() { return''; } add_filter('the_generator','remove_wp_version_rss');
Testez ensuite votre site sur HackerTarget
Sécuriser WordPress : wp-config.php
Le fichier wp-config.php est surement le fichier le plus important pour votre site. Il contient des informations confidentielles telles que :
- le nom de la base de données utilisée par WordPress
- l’utilisateur associé à cette base de données
- le mot de passe de connexion à cette base de données
- les clés de sécurité utilisées pour chiffrer vos cookies
Permissions wp-config
Il est donc absolument indispensable que personne ne puisse accéder à ce fichier : cela signifie des permissions 400 ou 440 (oui oui vous avez bien lu !). Vous pouvez retrouver cette information dans la documentation officielle de WordPress). Dans un terminal lancez la commande suivante
chmod 400 wp-config.php
Déplacer wp-config
Je vous conseille aussi de déplacer le fichier wp-config, en effet celui-ci peut être « remonter d’un niveau » c’est à dire le sortir de la racine de votre serveur web. Cette manipulation est parfaitement intégrée à WordPress et ne nécessite absolument aucune modification de fichier. Si votre fichier wp-config.php se trouve dans /var/www/www.votre-domaine.tld il vous suffit de lancer les commandes suivantes
cd /var/www/www.votre-domaine.tld mv wp-config.php ../
Il existe une autre technique vous permettant de stocker wp-config.php là ou vous le désirez. Dans notre exemple wp-config.php se trouve dans /var/www/domop239023pdxsze, créons alors un fichier wp-config.php (permissions 400) à la racine de notre site et collons le code suivant
<?php if ( !defined('ABSPATH') ) define('ABSPATH', dirname(__FILE__) . '/'); require_once('/var/www/domop239023pdxsze/wp-config.php'); ?>
Bloquer l’accès au fichier wp-config.php
Si vous utilisez apache, créez un fichier .htaccess dans le répertoire que wp-config.php et collez le code suivant
<Files wp-config.php> order allow,deny deny from all </Files>
Puis attribuez les permissions 644 à ce fichier
chmod 644 .htaccess
Si vous utilisez NGinx, modifiez votre vhost et ajoutez les lignes de configuration suivantes
location = /wp-config.php { deny all; }
Modifier les clés de sécurité WordPress
Lorsque WordPress s’installe il génère des clés de sécurité utilisées pour chiffrer les cookies du site et les configurent dans le fichier wp-config.php. Voici à quoi ces clés ressemblent :
define('AUTH_KEY', 'v ?aiH!*0nH+udHcHm@%?`(*#zX&fv3|^W*& ^v`x~Y;%vu<FAfgPtE{1}&0|@~t'); define('SECURE_AUTH_KEY', '$~DvQx-HeaON+wy2^d(p!mu3O|[=+ O|:Mh4+fC^~Ok9|~foP*+c+Hvc!&rNaPj`'); define('LOGGED_IN_KEY', 'd&$~>MU/8%Lq1~}dyK.H> 9enH%ZDWV};L5a(B(Ex}eA{[QqgCwJaDC=<<zBjOa<'); define('NONCE_KEY', '@J_e(<,GL$ mc H+dgzb=c,b0eBl[,x16JPQ?V+4w*,rD;@TXdk@+&5:+5`XB~CU'); define('AUTH_SALT', 'X-5s]([%-1l_5-*qB^-.76j7jA;<P.%xK7~py*n/+w^i}-c{AG+:47~/j|U4+f/Y'); define('SECURE_AUTH_SALT', 'F,`?3%-]|Kd,BXFgx;a;mY)iYRgKq~=P0^L#/%g(*x%bh!~`B=jNiDigN +E;% #'); define('LOGGED_IN_SALT', 'KLm<a4LS+wh(plZ/%f6%?}-S%rCi5#l!+5U YkLL;Ej MM4 ;(}7O)^($<PIVz`h'); define('NONCE_SALT', 'rT+h^JE.({D_:QLH2g<^(WC]2wm=9+&l*^wKv_odt!.+7`(KZWGo5Abb<*f)c9zW');
Je vous conseille donc d’en générer de nouvelles via l’API WordPress
Sécuriser WordPress : Attention à vos plugins et thèmes
Les plugins
Les plugins sous WordPress vous permettent d’ajouter de nombreuses fonctionnalités à votre site mais attention ils peuvent aussi être source de nombreux ennuis (When a WordPress plugin goes bad).
Cette partie du guide se limitera donc à quelques conseils
- plus vous utilisez de plugins plus vous risquez de compromettre la sécurité de votre serveur
- plus vous utilisez de plugins plus vous risquez de ralentir le chargement de votre site
- si un plugin devient inutile désactivez ET supprimez le
- mettez à jour vos plugins régulièrement
Les thèmes
Les thèmes WordPress peuvent eux aussi contenir du code malicieux. Ce sont les thèmes gratuits qui sont le plus souvent touchés et en particulier les thèmes nulled (thèmes piratés)
Pour savoir si un thème contient du code malicieux potentiel ouvrez un terminal et lancez la commande suivante
grep -inHR base64_decode * | cut -d':' -f1,2
Vous pouvez aussi tester votre thème avec le plugin Theme Authenticity Checker
Sécuriser WordPress : Utilisateurs
User-id
Par défaut WordPress attribue au premier utilisateur crée l’user-id 1. Cela peut faciliter les attaques brute-force sur votre site. En effet, si un petit malin accède à l’url suivante
http://www.votre-domaine.tld/?author=1
Il sera redirigé vers
http://www.votre-domaine.tld/author/votre-idenfiant
Votre identifiant en poche il pourra tenter une attaque brute-force (nous verrons comment prévenir ce type d’attaque un peu plus tard)
Pour modifier l’user-id lancez les requêtes SQL suivantes (remplacez Hyudzo487_ par votre préfixe de tables et remplacez 1024 par le nombre de votre choix)
UPDATE Hyudzo487_users SET ID = 1024 WHERE ID = 1;UPDATE
Hyudzo487_usermeta
SET
user_id = 1024
WHERE
user_id = 1;
Compte utilisateur
Dans notre cas notre identifiant n’est pas beau à voir. (0iz29k4u4RoOOC66Mq). Connectez vous à l’interface d’administration de votre site et renseignez un pseudonyme enfin choisissez ce pseudonyme comme « Nom à afficher publiquement ».
Masquer les erreurs de connexion
Lorsqu’une tentative de connexion échoue WordPress affiche par défaut des informations que je vous conseille de masquer (je vous rappelle que dans notre exemple notre identifiant de connexion est 0iz29k4u4RoOOC66Mq)
Si une personne tente de se connecter avec l’identifiant admin, WordPress affichera l’erreur suivante :
Si une personne tente de se connecter avec l’identifiant 0iz29k4u4RoOOC66Mq tout en indiquant un mauvais mot de passe, WordPress affichera l’erreur suivante :
Pour éviter que ces informations utiles apparaissent ajoutez dans le fichier functions.php
de votre thème le code suivant :
add_filter('login_errors', create_function('$no_login_error', "return 'Ooops';"));
Désormais idenfiant correct ou non, le seul message d’erreur indiqué sera
Mettre en place une authentification double facteur
Si vous ne connaissez pas le principe de l’authentification double facteur faites un tour ici.
Il existe de nombreux plugins permettant de mettre en place une authentification double facteur afin de mieux sécuriser WordPress. De mon coté je vous conseille de choisir entre Two Factor Authentication et Authy Two Factor Authentification
Sécuriser WordPress : Empêcher les attaques brute-force
Limiter le nombre de tentatives de connexion
Par défaut WordPress ne limite pas le nombre de tentatives de connexion à votre panel d’administration. Vous pouveez remédier à cela via l’installation d’un plugin.
Si fail2ban est installé sur votre serveur privilégiez WP fail2ban sinon tournez vous vers Login LockDown
Restriction d’IPs
Une méthode encore plus restrictive et donc beaucoup plus efficace vous permet de restreindre les IPs pouvant se connecter à WordPress. Si vous ne permettez pas à d’autres utilisateurs de s’inscrire sur votre site et de de s’y connecter c’est la méthode que je vous conseille.
Sous Apache2
Si vous utilisez apache2 comme serveur http, créez un .htaccess à la racine de votre site, et collez-y le code suivant (remplacez xx.xxx.xx.xx par les différentes IP que vous pourriez utiliser)
<Files wp-login.php> order deny,allow Deny from all allow from xx.xxx.xx.xx allow from xx.xxx.xx.xx </Files>
Créez ensuite un fichier .htacess dans le répertoire wp-admin et collez le code suivant
order deny,allow allow from x.x.x.x deny from all
Sous NGinx
NGinx ne permet pas l’utilisation de fichiers .htacess la configuration suivante devra etre ajouté directement dans le bloc serveur de votre virtualhost
location ~ ^/(wp-admin|wp-login\.php) { allow xx.xxx.xx.xx; allow xx.xxx.xx.xx; deny all; }
Sécuriser WordPress : Bloquer WPScan
Si vous êtes arrivés jusqu’ici c’est que vous souhaitiez réellement sécuriser WordPress et vous avez bien fait puisque j’ai gardé le meilleur pour la fin.
WPScan est un utilitaire permettant de scanner un site sous WordPress et afin d’y détecter des vulnérabilités. Il permet d’afficher :
- le contenu du fichier robots.txt
- la version de WordPress utilisée sur un site même si celle-ci n’est pas affichée dans le code ni dans le flux RSS et que le fichier README.html a été supprimé.
- la version des thèmes et plugins installés sur un site puis indique si des vulnérabilités ont été découvertes
- la liste des utilisateurs et donne l’user-id et identifiants qui leurs correspondent
Exemple de scan réalisé par WPScan
[+] URL: https://www.noobunbox.net// [+] Started: Sun Mar 20 02:00:29 2016 [+] robots.txt available under: 'https://www.noobunbox.net//robots.txt' [+] Interesting entry from robots.txt: https://www.noobunbox.net//wp-admin/ [+] Interesting header: SERVER: nginx [+] XML-RPC Interface available under: https://www.noobunbox.net//xmlrpc.php [+] WordPress version 4.4.2 identified from advanced fingerprinting [+] Enumerating plugins from passive detection ... | 1 plugin found: [+] Name: contact-form-7 | Latest version: 4.4 | Location: https://www.noobunbox.net//wp-content/plugins/contact-form-7/
Si quelqu’un tente de scanner votre site sans mettre le nez dans les options de WPScan celui-ci utilisera l’user agent WPScan v2.9 (http://wpscan.org) par défaut. Certains webmasters ont donc choisis de le bloquer. Dans ce cas là voici ce qu’il se passe lors d’une tentative de scan :
_______________________________________________________________ WordPress Security Scanner by the WPScan Team Version 2.9 Sponsored by Sucuri - https://sucuri.net @_WPScan_, @ethicalhack3r, @erwan_lr, pvdl, @_FireFart_ _______________________________________________________________ [!] The target is responding with a 403, this might be due to a WAF or a plugin. You should try to supply a valid user-agent via the --user-agent option or use the --random-agent option
Bloquer l’user-agent par défaut de WPScan ne vous protège absolument pas. Il suffit de re-scanner ce site en demandant à WPScan d’utiliser un autre user-agent.
Comment alors se protéger efficacement contre cet outil ?
Kacper Szurek a développé un petit plugin permettant d’empêcher tout scan de votre site (sans code malicieux hein !). Il vous suffit de télécharger le plugin antywpscan et de l’installer sur WordPress. Une fois le plugin activé voilà ce qu’affichera une tentative de scan de votre installation :
_______________________________________________________________ WordPress Security Scanner by the WPScan Team Version 2.9 Sponsored by Sucuri - https://sucuri.net @_WPScan_, @ethicalhack3r, @erwan_lr, pvdl, @_FireFart_ _______________________________________________________________ [!] The remote website is up, but does not seem to be running WordPress.
Sources
Bonjour.
À la partie « Déplacer wp-config », j’ai déplacé le fichier dans le répertoire parent de mon répertoire serveur (/srv/http/).
Question idiote, WordPress est donc capable si il ne trouve pas le fichier à la racine d’aller le chercher dans le dossier parent automatiquement sans modifier la config de WordPress ?
J’ai bon ?
Bonjour Ignace,
Oui tout à fait, WordPress est capable d’aller chercher le fichier wp-config.php dans le répertoire parent sans aucune modification.
Si ton répertoire contenant tes fichiers WordPress est le suivant /srv/http/www.domain.tld alors tu peux tranquillement déplacer le fichier de configuration vers /srv/http/
En fait, ça ne fonctionne pas. mon WordPress est installé non pas dans /srv/http/www.domain.tld mais directement dans /srv/http.
J’ai essayé de migrer la base de données vers un nom de base de données, nom utilisateur et mot de passe perso comme indiqué et de changer le préfixe des tables.
Résultat : mon site fonctionnait super mais une fois connecté, je n’avais plus accès à l’interface d’administration ou à ma page de profil.
J’ai du louper quelque chose.
En tout cas, antiwpscan marche super.
Merci pour toutes ces infos super.
Content que ce post ait pu t’aider.
Cela doit être du au fait que /srv/ ne peut pas être lu par ton serveur web.
Ce que tu peux faire :
– modifier la configuration de ton serveur web pour que la racine de ton domaine pointe vers /srv/http/www.domain.tld.
– créer un répertoire http://www.domain.tld, déplacer tous tes fichiers WordPress vers ce dossier sauf wp-config.php
Bon courage 🙂
Concernant ton problème de connexion. Est ce que tu avais des erreurs d’affichées ?
Vérifies bien que les nouveaux identifiants soient bien reportés dans le fichier de configuration. De même pour le nouveau préfixe
Quelle réactivité ! Quand j’allais sur « https://ignace72.eu/wp-admin/ », j’avais comme réponse exacte : Désolé, vous n’avez pas l’autorisation d’accéder à cette page. J’ai pris ma sauvegarde et j’ai tout remit comme c’était. Je réessaierais quand je serais remit de mes émotions. Tu parles des identifiants de base de données ? J’ai fais du copier coller. Bon je suis pas tout nu quand même, /wp-admin/, wp-login.php et wp-config.php sont totalement interdit sauf pour moi (127.0.0.1) , wp-config.php est en chmod 400. Mon modem routeur interdit le ftp et le ssh, je n’ai pas de serveur ftp d’installé. J’ai aussi l’extension Block Bad Queries… Lire la suite »
Effectivement c’est déjà pas mal.
Ton probleme peut venir d’une erreur de droits, vérifie bien que l’utilisateur du serveur web, habituellement www-data ait bien les droits sur tous les fichiers présents.
Le problème se résout en lançant
chown -R www-data:www-data /srv/http/
Si tu as peur de te tromper, tu peux t’entraîner sur une machine virtuelle avant de le faire sur ton serveur.
Je pense aussi que c’est un truc comme ça. J’ai fait l’erreur de me lancer la dedans le soir, et de faire en même temps le changement de nom utilisateur et mot de passe de la base de données et le changement de préfixe. Je viens de voir qu’il y a des tables dans la base WP qui ont un préfixe « srm_ », je sais pas d’ou ça vient. Peut-être un truc d’une extension. J’avais fait un chown -R http:http /srv/http (je tourne avec Nginx sur ArchLinux) donc les permissions doivent être bonne puisque juste en restaurant la base de données… Lire la suite »
Ahahah je vois ca.
Oui le mieux ca reste quand meme de faire les choses les unes apres les autres. Au moins si ca plante tu sais d’ou ca vient.
Bonne chance
Bon, j’ai trouvé d’ou ça vient le problème d’accès à l’interface d’administration :
C’est quand je change le préfixe wp_ par mon préfixe de la mort qui pue.
Pour être précis, je n’ai plus accès à l’administration ni à l’affichage du profil.
Il n’y a pas eu d’erreurs quand au préfixe car le site fonctionne très bien (j’imagine que sinon il me dirait que les tables n’existe pas).
Je recherche le pourquoi du comment sur gogole.
J’ai trouvé la solution, j’ai pas tout compris mais c’est là (j’ai pas encore essayé) :
https://wpchannel.com/modifier-prefixe-base-donnees-wordpress-apres-installation/
Bonjour.
Il est peut-être bon de signaler que antywpscan est parfaitement compatible avec WordPress 4.6 qui vient juste de sortir.
Aussi pour ceux qui ne savent pas comment l’installer, il faut juste copier le fichier dans le répertoire /wp-content/plugins/ et de l’activer dans le panneau d’administration des extensions.
Je dis ça car je me suis posé la question.
Une fois installé, le liens « À propos de WordPress » donne comme version de WordPress la « 0001 » mais si on va dans le panneau de mise à jour, il y a bien indiqué la « 4.6 ».
Ignace,
Tu as bien fait. Sinon a noter que la partie : Masquer le numéro de version de votre site WordPress suffit a empêcher un scan de retrouver la version de ton WordPress, puisque tu supprimes l’affichage de la version de WP dans le flux RSS ainsi que le fichier README et licence.
antywpscan reste quand meme très utile, voir ici la liste de ses fonctions : http://security.szurek.pl/prevent-wpscan-from-scanning.html
Ben j’ai fait les deux, on est jamais trop prudent.
Bonjour.
Il y a un défaut à antywpscan.
Il bloque tout dépôt de commentaire sur le site.
Bonjour Ignace
Tu n’as pas ajouté d’autres plugins ? Je n’ai jamais eu ce genre de problème
Des plugins j’en ai beaucoup (28) mais quand je désactive tous les plugins sauf antywpscan, les commentaire ne passe plus.
Ok,
Merci pour ton retour ça reste bon à savoir 🙂