Sécuriser son blog WordPress #3

Date: 25/01/2011 | Catégories: Blog,Open-source,Planet-libre,Reseau,Systeme,Web | Tags: ,,

WordPress n'a pas forcement bonne presse au niveau de la sécurité. Le coeur PHP du moteur WordPress est pourtant surveillé de très près et les corrections des failles sont assez rapides (voir par  exemple la publication de la version 3.0.4).

Par contre les plugins, qui sont un avantage indéniable de WordPress par rapport aux autres CMS, sont également un talon d’Achille... En effet, WordPress dispose d'une base de plugins impressionnante (plus de 12.700 au moment de l'écriture de ce billet) dont les développeurs sont plus ou moins sensibilisés à la problématique de la sécurité... Ajouter des plugins à votre blog, c'est multiplier les risques au niveau de la sécurité.

Dans ce billet, nous allons voir comment installer puis configurer WordPress pour compliquer la tache des personnes voulant attaquer votre blog.

Je vous rappelle que cet article est découpé en plusieurs billets (vous êtes en train de lire le #3):

Cette série de billets a été co-écrite avec Jérémie Marguerie étudiant à EPITA (merci à lui !).

Partir sur de bonnes bases

Nous allons détailler l'installation, la configuration initiale puis la gestion des mises à jours de WordPress.

    Installation de WordPress

    Personnellement j'utilise sur mon serveur deux versions de WordPress en parallèle.

    La première est celle du blog "de production" (celui que vous êtes en train de lire) utilise la version stable SVN (c'est à dire la 3.0.4 au jour d'aujourd'hui). J'utilise la commande suivante pour effectuer l'installation (dans le répertoire racine de mon serveur Web: /var/www/blog):

    svn co http://core.svn.wordpress.org/branches/3.0/

    La seconde, dite "de validation" me sert pour tester mon blog (thème et plugins) sur les futures versions de WordPress (3.1 par exemple). Elle n'est pas publique, seul les administrateurs peuvent y accéder. Pour installer cette version de WordPress, j'utilise la commande suivante dans un deuxième répertoire de mon serveur Web (/var/www/blogfutur):

    svn co http://core.svn.wordpress.org/trunk/

    Avant de suivre la fameuse installation en 5 minutes de WordPress, je vous conseille de changer le préfixe des tables MySQL en éditant la ligne suivante dans votre fichier de configuration wp-config.php et en remplacant wp_ par une chaine aléatoire (par exemple apvbty_):

    $table_prefix  = 'apvbty_';

    Attention, cette manipulation est à faire seulement sur un nouveau blog. En effet, si vous avez déjà une base de donnée SQL existante il faut d'abord changer le nom du préfixe des tables dans MySQL (voir hack en fin de billet) sous peine de ne plus pouvoir accéder à vos données.

    Une fois l'installation de WordPress finalisée, nous allons commencer par fixer les droits au niveau des fichiers dans ces répertoires. En partant sur l'hypothèse ou votre serveur Web tourne sous l'utilisateur www-data et dans le répertoire /var/www/blog, j'utilise les commandes suivantes:

    chown -R www-data:www-data /var/www/blog

    find /var/www/blog -type d -exec chmod 755 {} ;

    find /var/www/blog -type f -exec chmod 644 {} ;

    chmod 640 /var/www/blog/wp-config.php

    find /var/www/blog/wp-content/themes -type d -exec chmod 775 {} ;

    find /var/www/blog/wp-content/themes -type f -exec chmod 664 {} ;

    Pour vous simplifier la vie, je vous conseille de mettre ces commandes dans un script shell afin de pourvoir rapidement les appliquer sur votre arborescence.

    Mise à jour de WordPress

    Comme nous l'avons vu, les développeurs de WordPress sont assez réactifs sur la correction des failles de sécurité. Encore faut-il que vous pensiez à mettre à jour votre instance de WordPress...

    J'utilise un script shell pour mettre à jour WordPress à partir de SVN:

    #!/bin/bash

    # Simple script pour mettre a jour WordPress

    # Test que le script est lance en root

    if [ $EUID -ne 0 ]; then

    echo "Le script doit être lancé en root: # sudo $0" 1>&2

    exit 1

    fi

    WPPATH="/var/www/blog"

    echo "1) Mise a jour de WordPress"

    cd $WPPATH 2>&1 /dev/null

    CURRENTVERSION=`svn info | grep "Revision: " | awk '{ print $2 }'`

    svn update

    rm $WPPATH/wp-admin/install.php

    cd - 2>&1 /dev/null

    echo "2) Verification des droits des fichiers"

    chown -R www-data:www-data $WPPATH

    find $WPPATH -type d -exec chmod 755 {} ;

    find $WPPATH -type f -exec chmod 644 {} ;

    chmod 640 $WPPATH/wp-config.php

    find $WPPATH/wp-content/themes -type d -exec chmod 775 {} ;

    find $WPPATH/wp-content/themes -type f -exec chmod 664 {} ;

    echo "3) Fin de la mise a jour"

    echo "En cas de pb: svn update -r$CURRENTVERSION"

    Il est possible de lancer ce script toutes les nuits (par exemple par crontab) pour éviter de se retrouver avec un blog hacké quand vous partez en congés...

    Le .htaccess

    Ce fichier qui doit se trouver à la racine de votre site Web, contient des entrées utiles à la sécurité de votre site. Le mien commence par:

    # MAIN

    RewriteEngine On

    ServerSignature Off

    Options All -Indexes

    Options +FollowSymLinks


    # SVN protect

    RewriteRule ^(.*/)?.svn/ - [F,L]


    # Secure .htaccess

    <Files .htaccess>

    Order Allow,Deny

    Deny from all

    </Files>


    # Secure wp-config.php

    <Files wp-config.php>

    Order Deny,Allow

    Deny from all

    </Files>


    # FILTER REQUEST

    <IfModule mod_rewrite.c>

    RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-f

    RewriteCond %{REQUEST_FILENAME} !-d

    RewriteRule . /index.php [L]

    </IfModule>

    Certains plugins ajoutent pas mal de chose dans ce fichier (notamment W3 Total Cache, le plugin d'optimisation des performances que j'ai abordé dans ce billet).

    Un peu de bon sens...

    Vous avez donc entre les mains une installation toute propre et sécurisée de WordPress, c'est normalement à partir de ce moment là que les choses se gâtent...

    On commence par l'erreur de base: ne pas utiliser un mot de passe "strong" pour le compte admin. Encore mieux, créer un nouveau compte administrateur et supprimer le compte admin par défaut.

    L'installation des plugins apportent également son lot de failles de sécurité. C'est là qu'il faut se faire violence et n'installer que les plugins indispensables au bon fonctionnement de votre blog. Il faut également veiller à mettre à jour régulièrement vos plugins (l'interface d'administration de WordPress permet de faire cela très simplement).

    Enfin vos thèmes peuvent également fragiliser votre blog en insérant des codes PHP ou JS. Si vous avez les compétences il faut faire un audit de votre thème ou au minimum utiliser des thèmes connus et validés.

    Des plugins pour la sécurité

    Parmis ces plugins, j'en utile trois dédiés à la sécurisation:

    • Secure WordPress permet d'automatiser certaines actions pour sécuriser votre blog.

    • WordPress File Monitor: Surveille les fichiers du moteur WordPress et vous alerte (par mail et/ou directement dans l'interface d'administration de WordPress) en cas de modification.
    • On peut également citer WordPress Security Scan qui permet de faire un audit de votre blog en testant notamment les droits de vos fichiers, les mots de passes, la base de données...

    Quelques hacks en bonus

    Compliquer la tache des attaques par force brute en supprimant l'indicateur ("mauvais mot de passe") lors d'une tentative de connexion à l'interface d'administration. Il faut juste ajouter la ligne suivante à votre fichier functions.php (thème):

    add_filter('login_errors', create_function('$a', "return null;"));

    Si vous avez une base de données MySQL existante avec le préfixe par défaut (wp_) et que vous souhaitez le changer, il est possible de faire celà directement à la main par une requête MySQL ou alors plus simplement en utilisant le plugin WP-Security-Scan.

    Tester votre WordPress

    Pour tester la sécurité de votre blog, rien ne vaut une simulation d'attaque. Pour celà vous pouvez utiliser le logiciel libre Nikto.

    On commence par installer Nikto sur un PC client sous Ubuntu (qui va simuler l'attaque):

    sudo aptitude install nikto

    Puis on lance le test (remplacer URL par l'URL de votre blog WordPress):

    nikto -h URL

    Le rapport devrait ensuite s'afficher.

    Sources:

    • Pingback: Tweets that mention Sécuriser son blog WordPress #3 -- Topsy.com()

    • http://blog.cheramy.name guidtz

      Hello,
      encore un excellent article.
      A propos des mises à jour de plugins et du coeur, n’existe t’il pas un module nagios qui permettrait de remonter ces alertes ?
      Il en existe par exemple un pour Drupal qui permet de remonter -en autre – les infos de mise à jour.

      Cela peut être très pratique quand tu héberge des dizaines de sites wordpress.

      Slts

      • http://www.nicolargo.com NicoLargo

        C’est tout à fait possible, un petit mélange de NRPE et de script shell et le tour est joué !

        Une bonne idée de prochain article…

        • http://blog.cheramy.name guidtz

          Ce serait effectivement très intéressant et je prends tout de suite :-)

          Tu sais si il existe déjà des scripts shell qui permettraient de savoir si un module/le core de WordPress est à jour ? Ce serait déjà une possibilité pour remonter par mail l’info à un admin … mais par nagios ce serait plus mieux :-)

          Slts

    • http://blog.lyrixx.info Greg

      Pourquoi donner un accès en lecture aux autres utilisateurs ? Chez moi c’est du 770 (dossier) et 660 (fichiers)

    • http://blogmotion.fr/ Mr Xhark

      Quelque chose d’un peu plus radical pour wp-config.php :

      # protection 404 wp-config.php

      RewriteEngine On
      RewriteBase /
      RewriteRule ^(.*)wp-config(.*)\.php$ [R=404,L]

      Qui renvoie une erreur 404 plutôt que forbidden, un poil plus dissuasif.

      Pour la protection des fichiers .htaccess normalement Apache le fait de base me semble-t-il ?

    • http://www.flood.fr forum flood

      Ah c’est super nikto ! Merci pour l’article :)

    • Pingback: Mise à jour vers Wordpress 3.1()

    • zorgh

      Ne faut-il pas lire dans le script shell :

      CURRENTVERSION=`svn info | grep “Révision :” | awk ‘{ print $3 }’`

      au lieu de :

      CURRENTVERSION=`svn info | grep “Revision: ” | awk ‘{ print $2 }’`

      • http://www.nicolargo.com NicoLargo

        Heu non, en tout cas pas chez moi (Ubuntu 10.04 LTS version FR).

        $ svn info | grep “Revision:” | awk ‘{ print $3 }’
        vide…
        $ svn info | grep “Revision:” | awk ‘{ print $2 }’
        17487

    • zorgh

      Il faudrait peut-être donc préciser dans le billet que selon la distrib., le binaire ne retourne pas la même syntaxe.

      # cat /etc/debian_version
      5.0.8

      # dpkg -l | grep svn
      ii libsvn1 1.5.1dfsg1-5 Shared libraries used by Subversion

      # svn info | grep “Révision :” | awk ‘{ print $3 }’
      17488

      Cdt

    • Pingback: Quelques conseils pour sécuriser WordPress | Wordpress | Locita()

    • zorgh

      Un avis Nico : j’ai mis à jour wordpress vers 3.1.1 avec :

      svn sw http://core.svn.wordpress.org/tags/3.1.1/ .
      puis un upgrade de la base avec :
      wp-admin/upgrade.php

      Source : http://codex.wordpress.org/Installing/Updating_WordPress_with_Subversion#Converting_a_.22Traditional.22_WordPress_Blog_to_a_Subversion_Checkout

      Or d’un côté j’ai “Vous utilisez WordPress 3.1.1.” et de l’autre j’ai “Mettre à jour vers la version 3.1.1″.

      http://i.imgur.com/aPW2t.jpg

      svn info | grep “Révision :” | awk ‘{ print $3 }’
      17609

      Qu’en penses-tu ?

      En te remerciant.

    • zorgh

      J’ai ajouté la variable $wp_local_package =’fr_FR'; sous wp-includes/version.php pour passer le test et upgrader manuellement wp-content/languages/*

      Pas très automatisé tout cela ! :-)

    • Pingback: Sécuriser Wordpress, Cpanel et WHM.()

    • Pingback: Sécuriser son blog WordPress #3 | Wordpress | Scoop.it()

    • Pingback: Sécuriser son blog WordPress #3 | Logicamp | Scoop.it()

    • Pingback: Sécuriser son blog WordPress #3 | SeCurité infos et web | Scoop.it()

    • Pingback: Wordpress | Pearltrees()

    • Pingback: Hongi Installation et configuration de wordpress | Hongi()

    • Pingback: Sécuriser WordPress by désordre()

    • Pingback: Sécuriser mon site Wordpress? Les règles de base !| SEO DECOLLAGE IMMEDIAT |()

    • Pingback: Sécuriser son blog WordPress » josDBlog()

    • Kevin Falcoz

      Pour les développeurs de plugins WordPress, vous pouvez aussi tester la sécurité de vos développements sur la plateforme suivante: http://0pc0defr.fr/wp-check/ qui vous généreras un rapport listant les vulnérabilités potentielles qui auront été détectés lors de l’analyse statique de votre code.

    • David le terrible

      Bonjour, merci pour ces informations. Pour ceux qui ont l’erreur suivante avec la commande find :

      find: Paramètre manquant pour « -exec »

      Il suffit de rajouter un backslash avant le point-virgule à la fin, par exemple :

      find /var/www/blog -type d -exec chmod 755 ‘{}’ ;

      Et généralement il est préférable de rajouter des apostrophes ” ‘ “entre les accolades (pour éviter les problèmes d’interprétation).