Sécuriser WordPress contre les attaques

WordPress possède en effet des failles de sécurité. Comme tout système est faillible, notre bon vieil ami l’est aussi. C’est pourquoi la règle de base est de toujours le garder à jour. Par ailleurs, certaines failles ne dépendent pas du système mais plutôt que ce que vous en faites. Les plugins représentes une menace potentielle, la configuration de votre server ou encore parce que vous n’avez pas suivis le Codex WordPress concernant la sécurité.

Nous allons voir les règles de base à mettre en place pour sécuriser votre WordPress. Nous avons fait les frais de ‘petits malins’ il y a quelque temps et vous jugerez d’après le contenu de cet article que nous en avons retiré une certaine expérience.

Protéger WordPress contre quoi ?

Tout d’abord, pour la petite histoire, votre site peu intéresser des personnes peu scrupuleuses pour certaines raisons qui peuvent aller du simple challenge, au vol de données en passant par la revendication de parti politique. Cela passe par plusieurs étapes qui sont en général :

  • Exploitation d’une faille connue dans le système
  • Exploitation d’une faille de l’un des modules utilisés
  • Upload d’un fichier corrompu (Shell PHP, Mailer, etc.)
  • Modifications des accès administrateur à vos sites
  • Récupération des emails de vos clients
  • Envoi d’un faux mail Paypal à vos clients
  • Rediriger vos sites vers un de leurs sites
  • Modifier vos articles en y insérant du noscript, iframe ou display :none ;
  • Etc.

Les Shells

Un shell un fichier que les personnes mal intentionnées vont tenter de mettre sur votre serveur pour y avoir accès. Ils peuvent à partir de ce fichier lancer n’importe quelle commande comme si ils étaient connectés directement au serveur. Il peut être codé dans plusieurs langages mais en général c’est en PHP et en C que vous les trouverez :

securiser wordpress
proteger wordpress

Les Mailers

Les mailers sont de petits scripts permettant d’envoyer des emails. Ils sont soit destinés au hacker pour vérifier la mise en place d’un hack, à envoyer des mails à une liste envoyé par le hacker en paramètre de celui-ci (pour ne pas les envoyer de ses propres serveurs) ou à destination des personnes se trouvant dans votre base de données afin de leur envoyer un mail les invitant à mettre à jour leur compte Paypal. Ils sont quant à eux développés en PHP :

securiser wordpress

proteger wordpress

Voici pour la partie visible de l’iceberg parce qu’après, ces scripts peuvent être encodés et zippés à la volé :

Règles de base

Voici ce que WordPress invite à faire :

  • Mettre à jour WordPress
  • Utiliser des mots de passe puissants (majuscules, minuscules, chiffres, caractères aléatoires)
  • Mettre à jour votre serveur
  • Le réseau doit être sûr (éviter les cyber café et autres)
  • Utiliser SFTP au lieu de FTP dans la mesure du possible (transfert de fichier par SSH)
  • Vérifier les permissions d’accès aux fichiers (755 pour les dossiers et 644 pour les fichiers)
  • Utiliser des bases de données différents pour vos différents sites
  • Protéger l’administration du site au moyen d’un htpasswd par exemple (attention à admin-ajax.php)
  • Protéger le dossier wp-includes au moyen d’un fichier htaccess
  • Empêcher l’accès au fichier wp-config.php (cf ci-dessous)
  • Utiliser un préfixe de base de donnée différent que celui par défaut
  • Utiliser un compte administrateur ayant un autre identifiant que ‘admin’
  • Cacher votre version de WordPress avec la fonction remove_action(‘wp_head’, ‘wp_generator’); à placer dans votre functions.php
  • Faire des backups
  • Activer les logs

Le premier point est particulièrement important car il permettra de luter contre un bon nombre de failles du système qui sont découvertes presque tous les jours :

Vous pouvez aussi :

  • Utiliser une url personnalisée pour vous connecter au site (cf le plugin Stealth Login)
  • Limiter le nombre de tentatives de connexion (cf le plugin Login LockDown)
  • Vous connecter à l’admin de façon sécurisée en SSL (mettre le code suivant en haut du wp-config.php : define(’FORCE_SSL_ADMIN’, true);)
  • Protéger l’admin par un 2ème mot de passe (cf plugin AskApache Password Protect)
  • Supprimer les messages d’erreur lors des tentatives de connexion (ajouter le code suivant en haut de functions.php : add_filter(‘login_errors’,create_function(‘$a’, « return null; »));)
  • Installer un antivirus si ce n’est pas encore fait / le mettre à jour
  • Laisser votre par-feu Windows activé

Le fichier htaccess

Heureusement qu’il est là celui là. Outre les redirections, l’url rewriting, la mise en cache des fichiers ou la modification de variable de l’environnement du serveur, il permet de lutter contre les attaques menées contre votre site. Voici une liste de code à placer dans votre htaccess pour se protéger contre ces attaques :

Pour empêcher l’accès aux fichiers protégés du serveur, c’est à dire htaccess, htpasswd et tous les autres fichiers qui commencent par un point :

RedirectMatch 403 /\..*$

Pour bloquer les scripts qui seraient contenu dans le dossier wp-includes (code fournit par WP) :

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]

Pour bloquer les requêtes trace, delete, debug et track envoyé à votre site :

RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|DELETE|TRACK|DEBUG) [NC]
RewriteRule ^(.*)$ - [F,L]

Ensemble de règles contre des exploits connus et des plugins contenant des failles :

# Adminer MySQL management tool data populate
RewriteCond %{REQUEST_URI} ^/wp-content/plugins/adminer/ [NC] 
RewriteRule . - [S=11] # Comment Spam Pack MU Plugin - CAPTCHA images not displaying 
RewriteCond %{REQUEST_URI} ^/wp-content/mu-plugins/custom-anti-spam/ [NC] 
RewriteRule . - [S=10] # Peters Custom Anti-Spam display CAPTCHA Image 
RewriteCond %{REQUEST_URI} ^/wp-content/plugins/peters-custom-anti-spam-image/ [NC] 
RewriteRule . - [S=9] # Status Updater plugin fb connect 
RewriteCond %{REQUEST_URI} ^/wp-content/plugins/fb-status-updater/ [NC] 
RewriteRule . - [S=8] # Stream Video Player - Adding FLV Videos Blocked 
RewriteCond %{REQUEST_URI} ^/wp-content/plugins/stream-video-player/ [NC] 
RewriteRule . - [S=7] # XCloner 404 or 403 error when updating settings 
RewriteCond %{REQUEST_URI} ^/wp-content/plugins/xcloner-backup-and-restore/ [NC] 
RewriteRule . - [S=6] # BuddyPress Logout Redirect 
RewriteCond %{QUERY_STRING} action=logout&redirect_to=http%3A%2F%2F(.*) [NC] 
RewriteRule . - [S=5] # redirect_to= 
RewriteCond %{QUERY_STRING} redirect_to=(.*) [NC] 
RewriteRule . - [S=4] # Login Plugins Password Reset And Redirect 1 
RewriteCond %{QUERY_STRING} action=resetpass&key=(.*) [NC] 
RewriteRule . - [S=3] # Login Plugins Password Reset And Redirect 2 
RewriteCond %{QUERY_STRING} action=rp&key=(.*) [NC] 
RewriteRule . - [S=2]

Code qui empêche les shells de fonctionner sur votre serveur et qui bloque les attaques automatiques lancées contre votre site :

RewriteCond %{HTTP_USER_AGENT} (libwww-perl|wget|python|nikto|curl|scan|java|winhttp|clshttp|loader) [NC,OR] 
RewriteCond %{HTTP_USER_AGENT} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR] 
RewriteCond %{HTTP_USER_AGENT} (;|<|>|'|"|\)|\(|%0A|%0D|%22|%27|%28|%3C|%3E|%00).*(libwww-perl|wget|python|nikto|curl|scan|java|winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner) [NC,OR] 
RewriteCond %{THE_REQUEST} \?\ HTTP/ [NC,OR] 
RewriteCond %{THE_REQUEST} \/\*\ HTTP/ [NC,OR] 
RewriteCond %{THE_REQUEST} etc/passwd [NC,OR] 
RewriteCond %{THE_REQUEST} cgi-bin [NC,OR] 
RewriteCond %{THE_REQUEST} (\r|\n|%0A|%0D) [NC,OR] 
RewriteCond %{REQUEST_URI} owssvr\.dll [NC,OR] 
RewriteCond %{HTTP_REFERER} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR] 
RewriteCond %{HTTP_REFERER} \.opendirviewer\. [NC,OR] 
RewriteCond %{HTTP_REFERER} users\.skynet\.be.* [NC,OR] 
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR] 
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR] 
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC,OR] 
RewriteCond %{QUERY_STRING} \=PHP[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} [NC,OR] 
RewriteCond %{QUERY_STRING} \.\./\.\. [OR] 
RewriteCond %{QUERY_STRING} ftp\: [NC,OR] 
RewriteCond %{QUERY_STRING} http\: [NC,OR] 
RewriteCond %{QUERY_STRING} https\: [NC,OR] 
RewriteCond %{QUERY_STRING} \=\|w\| [NC,OR] 
RewriteCond %{QUERY_STRING} ^(.*)/self/(.*)$ [NC,OR] 
RewriteCond %{QUERY_STRING} ^(.*)cPath=http://(.*)$ [NC,OR] 
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR] 
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR] 
RewriteCond %{QUERY_STRING} (\<|%3C).*iframe.*(\>|%3E) [NC,OR] 
RewriteCond %{QUERY_STRING} (<|%3C)([^i]*i)+frame.*(>|%3E) [NC,OR] 
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR] 
RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*\([^)]*\) [NC,OR] 
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR] 
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2}) [OR] 
RewriteCond %{QUERY_STRING} ^.*(\[|\]|\(|\)|<|>).* [NC,OR] 
RewriteCond %{QUERY_STRING} (NULL|OUTFILE|LOAD_FILE) [OR] 
RewriteCond %{QUERY_STRING} (\./|\../|\.../)+(motd|etc|bin) [NC,OR] 
RewriteCond %{QUERY_STRING} (localhost|loopback|127\.0\.0\.1) [NC,OR] 
RewriteCond %{QUERY_STRING} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR] 
RewriteCond %{QUERY_STRING} concat[^\(]*\( [NC,OR] 
RewriteCond %{QUERY_STRING} union([^s]*s)+elect [NC,OR] 
RewriteCond %{QUERY_STRING} union([^a]*a)+ll([^s]*s)+elect [NC,OR] 
RewriteCond %{QUERY_STRING} (;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|order|script|set|md5|benchmark|encode) [NC,OR] 
RewriteCond %{QUERY_STRING} (sp_executesql) [NC] RewriteRule ^(.*)$ - [F,L] 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L]

Pour empêche l’accès aux fichiers qui peuvent donner des informations aux hackers (wp-config.php, bb-config.php, php.ini, php5.ini, readme.html), il faut y inclure :

<FilesMatch "^(wp-config\.php|php\.ini|php5\.ini|readme\.html|bb-config\.php)">
    Order allow,deny
    Deny from all
    allow from xxx.xxx.xxx.xxx
</FilesMatch>

Modifiez toutefois l’ip pour n’autoriser que la votre.

Téléchargez notre fichier htaccess.

Diverses protections

Pour mettre en place une deuxième couche de protection pour l’administration du site, au moyen d’un htaccess et d’un htpasswd crypté sans buger le module Ajax de WordPress, vous pouvez suivre le tuto suivant : https://kuttler.eu/en/post/htaccess-protect-wordpress-admin/

Pour vérifier qu’aucunes iframe, aucuns noscript et aucuns display:none; ne se cache dans votre article, utilisez la fonction SQL suivante (modifiez le nom de la table si vous n’avez pas utilisé le préfixe de base) :

SELECT * FROM wp_posts WHERE post_content LIKE '%<iframe%'
UNION
SELECT * FROM wp_posts WHERE post_content LIKE '%<noscript%'
UNION
SELECT * FROM wp_posts WHERE post_content LIKE '%display:%'

Security Scan permet notamment de voir si les droits d’accès aux fichiers sont les bons :

Si vous avez un accès SSH à votre serveur, vous pouvez lancer ces bouts de code depuis le dossier dans lequel se trouvent tous vos sites. Ils servent à rechercher des chaines de caractères à l’intérieur de fichiers qui sont dans les shells, mailers, etc :

grep -rH "nasser" *
grep -rH "Starting calls" *
grep -rH "c999sh_surl" *
grep -iR 'c99' *
grep -iR 'r57' * find / -name \*.php -type f -print0 | xargs -0
grep c99
grep -RPn "(passthru|shell_exec|system|base64_decode)" *
grep -rH "paypal.groupe" *
grep -rH "morocco genes" *
grep -rH "Linux Kernel" *
grep -rH "gzinflate(" *
grep -rH "allah" *
grep -rH "ZXZhbChiYXNlNjRfZGVjb2RlKCJhV1lvYVhOelpY" *
grep -rH "eval(base64_decode" *
grep -rH "$a = ‘m’.’d5′" *
grep -rH "$y = ‘base’.’6′" *

Vous pouvez aussi utiliser cet outils pour vérifier si votre site comporte une faille ou si il est déjà infecté : https://sitecheck.sucuri.net/

Supprimer des onglets de l'admin de WordPress
Javascript : accélérer le chargement d'un site internet

15 Comments on “Sécuriser WordPress contre les attaques”

  1. Merci beaucoup pour ce tuto c’est la première fois que je tombe sur un tuto si complet pour sécuriser WP, je t’avoue que ca va bien me servir, je me suis fait hacké la dernière fois ca m’a suffit.

    C’est toi qui a codé toutes le fonctions ?

  2. Merci aussi pour ce tuto. Il est ultra complet mais il faut un certain niveau de maitrise. En tous cas, c’est super pratique.

    Même question que pour Mathieu, tu as tout codé toi-même ? Gros niveau

    Marie

  3. Bonjour,

    les screenshots des scripts comme les shells ou les mailers sont des scripts réels trouvés sur des serveurs infectés. C’est en effet du développement très lourd mais les personnes utilisant ce genre de scripts n’en sont pas les auteurs, se sont simplement des personnes exploitants des failles connues des CMS et utilisant les outils de référence pour pénétrer dans un système.

    Quant au reste, c’est une compilation de certains script trouvé dans différents modules payant de protection de WordPress.

    Les fonctions de recherches récursives sur le serveur au moyen de la fonction grep est quelque chose que nous utilisons de temps en temps.

    Le fichiers htaccess téléchargeable est par contre un fichier que nous utilisons sur certains de nos sites, compilé par nos soins, mais à éditer : https://www.lije-creative.com/wp-content/uploads/2012/01/htaccess.zip

  4. Bonjour,

    Merci beaucoup pour ces astuces. Tout a été ajouté avec succès et ces modifs n’ont visiblement pas provoqué de bugs.

    Merci encore.

  5. Sacrée longueur de ton htaccess !
    Est-ce qu’on peut simplement copier/coller ton code pour être tranquille ou alors ce n’est qu’un exemple ?
    Cette question car je ne comprends pas 10% des lignes :-
    Est-ce adapté à tous les sites ou simplement certains CMS comme WordPress ?

    1. Salut,
      La grosse partie est uniquement pour Worpress. Par contre, tu peux copier coller le code en bas de l’article dans n’importe quelle installation. Attention cependant, certains hébergeurs peuvent générer une Erreur 500. C’est souvent le cas avec les fichiers htaccess.

      RewriteCond %{HTTP_USER_AGENT} (libwww-perl|wget|python|nikto|curl|scan|java|winhttp|clshttp|loader)....
      1. Ok, merci Jérôme, je prendrai le temps de tester ça à tête reposée pour ne créer aucune erreur.

  6. Bonjour Jérôme,

    merci pour ces quelques points essentiels.

    J’ai une petite question, concernant l’un des derniers bout de code qui « empêche l’accès aux fichiers qui peuvent donner des informations aux hackers », de quelle adresse ip tu parles ? (je suis un bleu de chez bleu, ne rie pas si ma question est idiote ;)
    L’adresse ip par laquelle j’accède moi au tableau de bord (celle de la maison et du bureau) ou l’adresse du serveur de mon site (qui est toujours la même) ?

    merci de ta réponse,
    Ludovic

    1. Bonjour,
      Non c’est une bonne question ;)
      Tu dois mettre ici toutes les adresses ip par lesquelles tu accèdes à l’admin (boulot, maison, etc.).
      Il faudra mettre à jour le fichier par ftp si tu changes d’ip, naturellement.

  7. Bonjour

    Je suis très intéressé par votre fichier htacces. Cependant, il ne fonctionne pas en l’état sur mon blog et je pense pour 2 raisons :
    1) Mon wordpress n’est pas a la racine, mais dans un dossier (dossier « blog »)
    2) L’adresse de mon site (exemple http://www.monsite.fr) est gérée en multi-domaine, ce qui veux dire que l’adresse est redirigée vers une autre (exemple http://www.truc.fr) qui est l’adresse principale de mon hébergement.

    Que faut’il modifier dans le fichier htaccess pour que tout fonctionne ?

    Je suppose qu’il faut remplacer tous les indes.php par blog/index.php. par contre pour le multi domaine ???

    Merci de votre réponse.

    1. Votre cas étant très spécifique, il faut tester les codes les uns après les autres.
      Du moment que le fichier htaccess est placé à la racine de votre blog WordPress, il devrait fonctionner.
      Si c’est une erreur 500, cela provient probablement de l’hébergement. Certaines directives ne passent pas partout.

  8. C’est vraiment costaud l’article mais pour être un bon gardien faut aussi être bon voleur () j’ai déjà installer pas mal de truc mais dite moi si j’installe le plugin wp security j’ai pas besoin de mettre les autres bout de code non ? et j’ai un hébergement mutualisé je suis protéger à priori d’attaque de ce genre sur serveur car il sont puissamment protégé par l’hébergeur j’imagine vous préconisez quoi pour le mutu.

    Il faut remplacer ne par (de ) à cette phrase

    Code qui empêche les shells ne fonctionner sur votre serveur et qui bloque les attaques automatiques lancées contre votre site :

    Merci pour ton article

    1. C’est corrigé.
      Cela dit, non. Ces codes ne sont que des exemples d’attaques qui peuvent être perpétrées sur vos sites.
      WP Security devrait vous protéger de tout cela effectivement. C’était plus dans une optique de nettoyage post-attaque.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *