Sécuriser WordPress : comment protéger un blog ?

22 mars 2016 Sécurité 18 Commentaires

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

 

 

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 ».

Sécuriser WordPress

 

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 :

ERREUR : Nom d’utilisateur invalide. Vous avez perdu votre mot de passe ?

 

Si une personne tente de se connecter avec l’identifiant 0iz29k4u4RoOOC66Mq tout en indiquant un mauvais mot de passe, WordPress affichera l’erreur suivante :

ERREUR : Le mot de passe que vous avez saisi pour cet utilisateur 0iz29k4u4RoOOC66Mq est incorrect. Vous avez perdu votre mot de passe ?

 

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

Ooops

 

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