Dossier WordPress – Améliorer la sécurité de WordPress avec quelques hooks

Cet article a 462 jours. Il commence à dater, lisez-le donc en gardant son âge en tête ! Merci

Dossier Sécurité WordPress - Partie 3/4 Une fois les plugins de sécurité installés, il peut parfois subsister certains indices ci et là qui peuvent fournir des informations supplémentaires sur votre installation WordPress.
Bien entendu, c’est informations ne sont pas des failles en elles-mêmes, mais il peut être intéressant de les cacher.

Voici donc quelques hooks – c’est morceaux de code qui vous donnent accès à la modification de portions de fonctions WordPress – afin de modifier certaines actions, sans toucher au cœur du gestionnaire de contenu. Cela vous permettra de bénéficier des mises à jour de WordPress sans aucun problème.
La plupart de ces codes sont à placer dans le fichier functions.php de votre thème WordPress.

Supprimer le message d’erreur à la connexion

Lorsque vous vous connectez à l’interface d’administration de WordPress et que vous commettez une erreur, un message d’information apparait.
Celui-ci est suffisamment explicite pour vous dire que votre mot de passe n’est pas le bon, ce qui signifie que votre login est bon, ou inversement. (vous me suivez ? :p)
Bref, pour supprimer cette information bien inutile – ou du moins trop utile à la mauvaise intention, et pas suffisamment à la bonne – il vous suffit d’utiliser ce code.

if ( !function_exists("remove_login_error_messages")) {
    function remove_login_error_messages($val){
        $val = __('Same player plays again');
		return $val;
    }
}
add_filter('login_errors','remove_login_error_messages');

Si vous souhaitez retirer complètement le message (et ça semble conseillé), retirez la troisième ligne et remplacez return $val; par return null;.

Supprimer la version de WordPress

WordPress, grâce à la fonction wp_head() présente dans votre thème, affiche la meta suivante : <meta name="generator" value="WordPress x.x.x"/>
Dans le fichier functions.php de votre thème WordPress, ajoutez ce code pour supprimer cette meta inutile :

remove_action('wp_head', 'wp_generator');

Le plugin WP Security Scan se propose de le faire pour vous, si vous n’êtes pas très code. (peut-être l’avez-vous déjà installé)

Il est également possible de retirer cette information du flux RSS :

if (!function_exists('juiz_no_generator')){
	function juiz_no_generator() { return ''; }
}
add_filter('the_generator', 'juiz_no_generator');

En plus de cette meta, le numéro de version de WordPress, mais aussi des plugins installés sont affichés en bout de chemin des fichiers CSS et JS sous cette forme : style.css?ver=3.3.1
C’est également une information qui peut être retirée en entrant ce code dans le fichier functions.php :

if( !function_exists("delete_script_version")) {
    function delete_script_version( $src ){
        $parts = explode( '?', $src );
        return $parts[0];
    }
}
add_filter( 'script_loader_src', 'delete_script_version', 15, 1 );
add_filter( 'style_loader_src', 'delete_script_version', 15, 1 );

Source

Désactiver les éditeurs de thèmes et plugins

WordPress offre la possibilité par défaut d’éditer les fichiers des thèmes et plugins depuis l’interface d’administration.
Je n’ai jamais encore trouvé l’intérêt de ces éditeurs, et leur activation par défaut est un risque si certains utilisateurs non prévenus viennent y mettre les pieds.
Désactivez simplement cette fonction grâce à ce morceau de code à placer dans le fichier wp-config.php se trouvant à la racine de votre installation WordPress&nsbp;:

define( 'DISALLOW_FILE_EDIT', true );

C’est tout.
Merci à alex pour la suggestion.
Source

Créer un plugin pour bloquer les requêtes suspectes

Les injections SQL peuvent se faire en exploitant une faille dans un formulaire, que la méthode soit en POST ou en GET, ou directement dans une URL.
Aussi, pour prévenir ces injections, il est possible de filtrer la requête en recherchant des mots clefs extraits de requêtes SQL.
Nous allons créer un plugin. Pour ce faire, rendez-vous dans le dossier wp-content/plugins/ et créer le nouveau dossier « blockbadqueries » dans lequel vous glisserez le fichier blockbadqueries.php dont voici le contenu :

<?php
/*
Plugin Name: Block Some Bad Queries
Plugin URI: http://www.creativejuiz.fr/blog/wordpress/dossier-ameliorer-securite-wordpress-hooks
Description: Protect WordPress Against some malicious URL requests
Author URI: http://www.creativejuiz.com
Author: Geoffrey Crofte - CreativeJuiz
Version: 1.0.0
Original old version from: http://perishablepress.com/
*/
global $user_ID;
if($user_ID) {
	if(!current_user_can('level_10')) {
		if (strlen($_SERVER['REQUEST_URI']) > 255) {
			@header("HTTP/1.1 414 Request-URI Too Long");
			@header("Status: 414 Request-URI Too Long");
			@header("Connection: Close");
			@exit;
		}
	}
}
if (strpos($_SERVER['REQUEST_URI'], "eval(") ||
strpos($_SERVER['REQUEST_URI'], "CONCAT") ||
strpos($_SERVER['REQUEST_URI'], "UNION+SELECT") ||
strpos($_SERVER['REQUEST_URI'], "base64")) {
	@header("HTTP/1.1 414 Request-URI Too Long");
	@header("Status: 414 Request-URI Too Long");
	@header("Connection: Close");
	@exit;
}
?>

Activez le plugin depuis l’interface de WordPress et le tour et joué.
Ce script vérifie le contenu de la requête, et s’il trouve quelque chose de suspect renvoie une erreur 414 (URL trop longue).

Pour ceux qui auraient davantage d’affinité avec .htaccess, je vous invite à lire la suite qui comporte également une solution alternative (complémentaire ?) à ce plugin. Cette solution a également été proposée par Perishable Press.

22 commentaires sur “Dossier WordPress – Améliorer la sécurité de WordPress avec quelques hooks”

  1. BoiteAWeb dit :
    19 février 2012

    Supprimer le message d’erreur à la connexion se doit de TOUT supprimer. Les scripts de brute-force se basent sur un contenu de la page d’erreur de login différent de la page de départ. Si vous laissez un message lors d’une erreur de login ou pass, cela est suffisant pour le script de BF de faire son travail.
    Je ne peux donc que vous recommandez de mettre « null » au lieu d’un message perso.

    Pour la version de WordPress à cacher, c’est inutile, de 1 par ce que … vous avez la dernière n’est ce pas ? Voilà, j’ai « vu » votre version. Et si vous ne l’êtes pas, je vous lance le défi que je trouve votre numéro de version tout de même ;) « Qui cherche trouve » ;)

    Pour Block Bad Queries, c’est une idée mais ce que je ne saisis pas c’est « pourquoi autoriser le rang 10 à faire des injections SQL ? » et « pourquoi faut-il être connecté pour que le plugin fasse le travail » ? Ce qui signifie que si une CSRF et une SQLi sont présentes, alors la hacker peut les exploiter au travers d’un compte admin ? Et si il n’est pas connecté alors le plugin ne fait pas le boulot ? Ok, donc le plugin ne sert à rien dans ces cas, dommage.

  2. Geoffrey dit :
    20 février 2012

    Ah ouais bien vu.
    Je me suis concentré sur la lecture des requêtes pour comprendre l’utilité de ce mini plugin, jamais sur les conditions à respecter autour…

    Il est bizarre finalement ce script.
    Je le simplifie sur les contrôles, je ne vois pas pourquoi il y a cette limitation effectivement.

    Pour la version de WordPress, je pars juste du principe que moins on donne d’indice plus ça prendra de temps pour trouver la version, même si ce n’est que 5 minutes. Je sais également que certains clients le demande sans savoir eux-mêmes pourquoi, et comme l’éducation des clients n’est pas toujours évidente, ça donne la méthode pour cette manipulation.

    Concernant la force brute et le message je ne savais pas que cela fonctionnait ainsi. Le script n’arrive pas à savoir qu’il est toujours sur la même page ? Il pourrait donc en déduire qu’il n’a pas réussi son accès…

  3. BoiteAWeb dit :
    20 février 2012

    Par forcément, le script de BF lui ne se fait pas rediriger mais attends juste un source et un code HTTP en retour (200 est attendu), certains BF sont supers bons et peuvent faire plein de chose tous seuls, d’autres sont moins bons et ne pas afficher les messages peut les bloquer.

    Tu as raison sur le fait de vouloir faire perdre du temps aux hackers ^^ Cachons nos version
    mais une queestion ne vient à l’esprit : pour quoi tu ne caches pas ton n° de version ? :)

  4. Geoffrey dit :
    20 février 2012

    Ah ah !
    coquinou !

  5. BoiteAWeb dit :
    20 février 2012

    C’était une vraie question, je n’ai pas cherché loin pour la trouver, j’ai perdu moins de 10 secondes chrono en main sans aucun outil ou autre, juste mon navigateur et 1 clic.

  6. Geoffrey dit :
    20 février 2012

    Parce que je ne pensais pas que le Flux RSS transportait cette information.
    Mais je veux bien perfectionner le script :D (Fait !)

  7. BoiteAWeb dit :
    20 février 2012

    Et je la trouve encore en 1 clic ;)
    « Le chat et la souris » :p

  8. Geoffrey dit :
    20 février 2012

    Arf… ok je m’avoue vaincu !

  9. BoiteAWeb dit :
    20 février 2012

    http://www.creativejuiz.fr/blog/readme.html ;) Qui y pense ?
    Comment éviter ça ? Non, pas en le supprimant car à la prochaine mise à jour auto ça revient, mais tout comme le wp-config.php, une protection d’accès via .htaccess
    :]

  10. Geoffrey dit :
    20 février 2012

    Aaah, mais c’est pas un clic ça ! {mauvaise foi}

    Justement je me suis fait avoir par la mise à jour, vu que j’avais supprimé ce fichier.
    Tu as les yeux partout !
    (Thanks ;p)

  11. BoiteAWeb dit :
    20 février 2012

    « Tu as les yeux partout ! »
    Et même un peu plus, c’est mon métier ;)

  12. Mr Xhark dit :
    23 février 2012

    J’ajoute cet excellent billet : http://www.askapache.com/security/mod_rewrite.html

  13. Geoffrey dit :
    29 février 2012

    @BoiteAWeb : tout le monde ne bosse pas avec autant de passion et de précision :)

    @Mr Xhark : merci pour cette ressource, je l’ajoute en fin d’article, elle est vraiment bonne ! ;)

  14. 15 mai 2012

    Je tiens a vous remercier pour les lignes de script car je souhaitais sécuriser la partie login de WP >>> il me reste pluqu’à la customiser !

  15. jojaba dit :
    16 septembre 2012

    Je viens de travailler sur la sécurité d’un forum tournant sous FluxBB et j’ai notamment mis en place un plugin utilisant Bad Behavior : http://bad-behavior.ioerror.us/
    Il y a une explication pour l’installation sur WordPress : http://bad-behavior.ioerror.us/support/installation/wordpress/
    Ça fonctionne bien sur FluxBB et en plus on voit ce qui est bloqué…
    Ce commentaire semble être un peu hors sujet, mais non. Bad Behavior agit sur toute activité sur le site (il ne vérifie pas uniquement les commentaires)…

  16. Geoffrey dit :
    16 septembre 2012

    Hey mais ça a l’air super bien !
    Merci pour cette info Jojaba, je me note ça dans ma TODO list question de faire quelques tests.
    Bon dimanche :)

  17. jojaba dit :
    17 septembre 2012

    Tiens-moi (ou nous) au courant de tes tests ;)

  18. Geoffrey dit :
    17 septembre 2012

    Ouais je vais essayer ^^
    Je vais surtout commencer par trouver le temps :p

  19. undefined42 dit :
    24 mars 2013

    :O pitié pas de suppresion d’erreur avec @….
    jamais! c’est ignorer un problème, le cacher. Pas le résoudre!

    ps : je me demande bien quel probleme peut empecher exit (ça serais cocasse :’) )

  20. Geoffrey dit :
    24 mars 2013

    Hello,
    Il faudra dire ça à perishablepress.com, une partie du code vient de leur expertise. N’étant pas développeur, je suis parti du principe qu’ils avaient une bonne raison de placer ces « @ » dans un contexte tel que celui offert par WordPress. :)
    Merci en tout cas pour ton commentaire pertinent ;)

  21. 24 mars 2013

    Sauf pour « header() » où c’est mieux de le mettre car la seule erreur possible ne vient pas de la fonction elle même mais du fait qu’une autre erreur soit déjà affichée ou (au moins) un caractère imprimé AVANT l’utilisation de cette fonction.
    Donc au lieu de dire « Fatal error: Headers already sent », pas besoin de l’afficher, il suffit de lire l’erreur du dessus.
    Si on regarde le code WordPress, @ est aussi ajouté dans les fonctions car on ne sait pas si les headers ont été sent (on pourrait utiliser headers_sent() oui). A d’autres endroits on ne le mets pas car on est direct dans notre fichier et on SAIT que les headers ne sont pas sent.
    Bref, Jeff de Perishable Press a raison, WordPress a raison, je pense avoir raison ^^
    See you

  22. Geoffrey dit :
    24 mars 2013

    Merci d’avoir confirmé ma pensée Julio :)

Laisser un commentaire

Certains codes HTML ne sont pas échappés automatiquement. Pour afficher du code dans votre commentaire, merci d'échapper vos chevrons en utilisant "&lt;" et "&gt;" en lieu et place de "<"" et ">".

Il est difficile de proposer un support pour tous les articles de ce blog. En ne fournissant pas un moyen de consulter votre code bogué, vous vous assurez de ne pas avoir de réponse adaptée.

 
Le studio web