Sécuriser WordPress

Trucs et Astuces

Vous trouverez ici quelques astuces de sécurité basique, faisant appel au bon sens, et à quelques lignes de code permettant de combler certaines lacunes des installations WordPress, à inclure dans les fichiers .htaccess (directives serveur Apache) et functions.php (de votre thème WordPress).
Ces modifications ont été trouvées sur différents sites et je fais une simple compilation de ces différentes astuces…

Pour récupérer les différents codes, cliquez sur le bouton de chaque partie de code source.

Maintenir votre système à jour

Mettre à jour son installation WordPress régulièrement n’est malheureusement pas un réflexe pour tout le monde, y compris chez les professionnels du web.
C’est pourtant le seul moyen de supprimer les failles, publiques ou non, exploitées par les hackeurs.

Mais la plupart du temps, je le fais dès que je vois une notification, en particulier pour les plugins, Y COMPRIS LES PLUGINS INACTIFS, dont le code peut être exécuté, et donc les failles exploitées.

Effectuer des sauvegardes régulières

Puisque la sécurité d’un système n’est jamais garantie à 100%, la sauvegarde régulière reste la seule pratique vous assurant de ne pas perdre du contenu. A stocker dans plusieurs endroits (disque externe, cloud, clé USB…) pour réduire les risques.

Renseigner les clés de sécurité et le salage

Les secret keys du fichier config.php (situé à la racine de votre site) sont des clés de « hash » utilisées par WordPress pour crypter les mots de passe en base de données et les informations contenues dans ses cookies, incluant identifiant et mot de passe de l’utilisateur.

Le « sel », constitué du même nombre de clés supplémentaires (de suffixe _SALT), a été ajouté pour complexifier encore le décryptage des hash générés.

Exemple de clés de sécurité :

define('AUTH_KEY',   'IpoDOU`aD_S84pZU/XLH{$KK;Of`3&%KW}CN+zpa?q@@qwG2p+:%0]!lIGU^bqI%');
define('SECURE_AUTH_KEY',  '|N)lX@0F51hn=m#SQU@-$)+MRB/E)?SV`s]H4/eZD[1F;<S#:=xFP?,j]d!C -X');
define('LOGGED_IN_KEY', 'x#}*(5Z5sMod]j+Gsm4|%A#3Yvo?mG{t-hyw0^OTwTEb{|BW:idoo:,Q||#z&VLM');
define('NONCE_KEY', 'AeL2k^t.)xx<a0$F.?2a8<NiBIOg# ~txf/b/7Q5|>gd361LypKeKrRnm[s8+z1^');
define('AUTH_SALT', 'Li6>tO.|QOj-Zh@bh+W+T5G{)SsP8JYctzqzD.co<&4mIFfi6O>%2>&`!@U@o<)d');
define('SECURE_AUTH_SALT', 'q!8xhD+<^iHi?q&|^%<l4]^[CC2!c|-t}Oavt=36T(&^D2x@z-,Muxk4|:^bR,km');
define('LOGGED_IN_SALT', '-6>$e%vyOdXOKmtm>V&b+yge3|p,Z:~>W{OZ`]z,[V-7b@W5m3jsz_^9pqlE.:4(');
define('NONCE_SALT','$S4vca%tO{$-:*]O87iGy;!Qz|Fio0-y/+%Q6+K%|&$otviT>nBLav+p~Qp/6hU8');

Ces clés doivent être renseignées dans le fichier config.php, car sinon WordPress en génère automatiquement, mais les stocke en base de données, donc au même endroit que les mots de passe, ce qui facilite le déchiffrage de ces derniers.

Si ce n’est pas le cas, utilisez ce générateur de clés fourni par WordPress et copiez le résultat dans votre fichier.

Vous devrez obligatoirement les changer au moindre soupçon d’intrusion, tout comme votre mot de passe.

Empêcher que l’on découvre l’identifiant d’un auteur

Masquer les pages de profil des auteurs

En saisissant dans la barre d’adresse de votre navigateur le nom de domaine de votre site suivi de « ?author=1 », il y a des chances que vous soyez redirigé vers une page votresite.ext/author/<user>/, où <user> représente le login administrateur. Et si ça ne marche pas pour la valeur 1, ça marchera pour une autre, donc un script très élémentaire permettra à quiconque de trouver les identifiants sensibles de votre site.

Des infos qu’on aimerait cacher… Pour cela, on ignore complètement la requête et on renvoie une erreur en ajoutant ces lignes dans le fichier .htaccess situé à la racine de vote site :

    # Masquage des pages d'auteur
    <IfModule mod_rewrite.c>
     RewriteCond %{QUERY_STRING} ^author=([0-9]*)
     RewriteRule .* - [F]
    </IfModule>

Supprimer les logins des auteurs dans les commentaires

Cette fois, c’est directement dans le code HTML des commentaires d’un article que le login de l’administrateur est dévoilé en cas de réponse de ce dernier !

Insérez donc ceci dans le fichier functions.php de vote thème pour masquer les logins des auteurs :

    // Suppression du login de l'auteur dans les commentaires
    function remove_comment_author_class( $classes ) {
     foreach( $classes as $key => $class )
      if(strstr($class, 'comment-author-' ))
       unset( $classes[$key] );
     return $classes;
    }
    add_filter( 'comment_class' , 'remove_comment_author_class' );

Protéger l’accès aux dossiers et aux fichiers sensibles

Certains fichiers de votre installation WordPress contiennent des données très confidentielles qu’il faut absolument protéger.

Ajoutez ces lignes dans votre fichier .htaccess :

    # Désactivation de l'affichage du contenu des répertoires
    Options -Indexes
    # Protection du fichier wp-config.php
    <files wp-config.php>
     Order allow,deny
     Deny from all
    </files>
    # Protection des fichiers .htaccess et .htpasswds
    <Files ~ "^.*\.([Hh][Tt][AaPp])">
     Order allow,deny
     Deny from all
    </Files>

Supprimer les informations d’erreur de connexion

Lorsqu’on commet une erreur de saisie sur le formulaire de connexion WordPress, un message indique, selon le champs erroné, que l’identifiant n’existe pas ou que le mot de passe ne correspond pas à l’identifiant.

C’est peut-être commode pour nous, mais c’est surtout très pratique pour un pirate, qui pourrait dans un premier temps lancer une attaque permettant de trouver les logins du site, puis pour chacun de craquer leur mot de passe.

Supprimons donc ces messages à l’aide du fichier functions.php :

    // Suppression des infos d'erreur de login
    function remove_login_error_msg() {
     return 'Et alors, on farfouille...?';
    }
    add_filter( 'login_errors', 'remove_login_error_msg' );

Désactiver XML-RPC

On peut désactiver complètement XML-RPC (et supprimer les informations associées dans les entêtes de page) via ces quelques lignes dans le fichier functions.php :

    // Désactivation XMLRPC
    add_filter( 'xmlrpc_enabled', '__return_false' );
    remove_action('wp_head', 'rsd_link');
    add_filter('bloginfo_url', function($output, $property){
        return ($property == 'pingback_url') ? null : $output;
    }, 11, 2);
    add_filter( 'wp_headers', function($headers) {
        unset( $headers['X-Pingback'] );
      return $headers;
    });

Il est aussi possible de protéger des attaques en force brute le fichier xmlrpc.php situé dans le dossier racine de WordPress avec une directive Apache dans le fichier .htaccess :

    # Protection du fichier xmlrpc.php
    <Files xmlrpc.php>
     Order allow,deny
     Deny from all
    </Files>

Masquer les numéros de version

Pourquoi faciliter la tâche des pirates en leur fournissant des informations sur le système, et donc en leur indiquant quelles failles ils pourront exploiter ?

Les entêtes de page et le flux RSS

Protégeons donc leur accès une fois pour toutes via une directive dans le fichier .htaccess :

WordPress insère en effet dans ses entêtes de page (la balise <head>) quelques éléments inutiles pour le fonctionnement de votre site, mais exploitables par d’éventuels bots/hackers, en particulier des numéros de version, de WordPress et des fichiers CSS ou JS inclus.

Pour supprimer ces numéros de version des entêtes (et au passage du flux RSS), insérez ces quelques lignes de PHP dans le fichier functions.php de votre thème enfant :

     // Suppression de la version de WordPress
    remove_action('wp_head', 'wp_generator');
    // Suppression version flux RSS
    function remove_version_wp() {
     return '';
    }
    add_filter(‘the_generator’, ‘remove_version_wp’);
    // Suppression des versions des fichiers css/js inclus
    function remove_ver_css_js( $src ) {
     if ( strpos( $src, 'ver=' . get_bloginfo( 'version' ) ) )
      $src = remove_query_arg( 'ver', $src );
     return $src;
    }
    add_filter( 'style_loader_src', 'remove_ver_css_js', 9999 );
    add_filter( 'script_loader_src', 'remove_ver_css_js', 9999 );

Les fichiers readme, licence, changelog…

Ces fichiers, situés à la racine de votre site ou de vos thèmes/plugins, contiennent eux aussi des informations exploitables. Les effacer manuellement n’est pas la bonne solution, puisqu’il seront recréés à chaque mise à jour de votre CMS.

    # Protection des fichiers de version
    <FilesMatch "^(readme.html|readme.txt|README.txt|README.md|changelog.txt|license.txt|LICENCE.txt|LICENCE)">
     Order allow,deny
     Deny from all
    </FilesMatch>

Les informations de version du serveur

Sur certaines pages d’erreur renvoyées par les serveurs, on peut trouver des informations de version sur les logiciels et modules utilisés.

Voici comment indiquer à Apache de ne pas les afficher dans le fichier .htaccess :

    # Masquage des informations du serveur
    ServerSignature Off

Récapitulatif des codes à ajouter

Fichier function.php
    /******************************************/
    /*            SECURITE WORDPRESS          */
    /******************************************/
    // Suppression du login de l'auteur dans les commentaires
    function remove_comment_author_class( $classes ) {
     foreach( $classes as $key => $class )
      if(strstr($class, 'comment-author-' ))
       unset( $classes[$key] );
     return $classes;
    }
    add_filter( 'comment_class' , 'remove_comment_author_class' );
    // Désactivation des infos d'erreur de login
    function remove_login_error_msg() {
     return 'Et alors...?';
    }
    add_filter( 'login_errors', 'remove_login_error_msg' );
    // Désactivation XMLRPC
    add_filter( 'xmlrpc_enabled', '__return_false' );
    remove_action('wp_head', 'rsd_link');
    add_filter('bloginfo_url', function($output, $property){
        return ($property == 'pingback_url') ? null : $output;
    }, 11, 2);
    add_filter( 'wp_headers', function($headers) {
        unset( $headers['X-Pingback'] );
      return $headers;
    });
    // Suppression de la version de WordPress
    remove_action('wp_head', 'wp_generator');
    // Suppression version dans flux RSS
    function remove_version_wp() {
     return '';
    }
    add_filter(‘the_generator’, ‘remove_version_wp’);
    // Suppression des versions des fichiers css/js inclus
    function remove_ver_css_js( $src ) {
     if ( strpos( $src, 'ver=' . get_bloginfo( 'version' ) ) )
      $src = remove_query_arg( 'ver', $src );
     return $src;
    }
    add_filter( 'style_loader_src', 'remove_ver_css_js', 9999 );
    add_filter( 'script_loader_src', 'remove_ver_css_js', 9999 );
Fichier .htaccess

Dans ce fichier, en plus des bouts de code ci-dessus, il se peut que vous deviez activer l’option FollowSymLinks, indispensable au fonctionnement du module mod_rewrite et de la personnalisation des permaliens WordPress (si ce n’est pas fait dans la configuration serveur de votre hébergement).

    /******************************************/
    /*            SECURITE WORDPRESS          */
    /******************************************/
# Activation du suivi des liens symboliques
Options +FollowSymLinks
# Désactivation de l'affichage du contenu des répertoires
Options -Indexes
# Masquage des informations du serveur
ServerSignature Off
# Protection du fichier wp-config.php
<files wp-config.php>
 Order allow,deny
 Deny from all
</files>
# Protection des fichiers .htaccess et .htpasswds
<Files ~ "^.*\.([Hh][Tt][AaPp])">
 Order allow,deny
 Deny from all
</Files>
# Masquage des pages d'auteur
<IfModule mod_rewrite.c>
 RewriteCond %{QUERY_STRING} ^author=([0-9]*)
 RewriteRule .* - [F]
</IfModule>
# Protection du fichier xmlrpc.php
<Files xmlrpc.php>
 Order allow,deny
 Deny from all
</Files>
# Protection des fichiers de version
<FilesMatch "^(readme.html|readme.txt|README.txt|README.md|changelog.txt|license.txt|LICENCE.txt|LICENCE)">
 Order allow,deny
 Deny from all
</FilesMatch>


Découvrez comment Réussir sur Instagram ?