Anti CSRF ou Comment se prémunir de la faille CSRF sous WordPress

banner_anti-csrf[1]
Anti CSRF

A vos souhaits !

Anti CSRF ? Ha, la faille CSRF !... Vous connaissez sous WordPress ? Il s'agit (en gros) du fait qu'une personne mal intentionnée puisse utiliser le compte d'une personne ayant des droits pour réaliser des actions qu'elle n'aurait pas le droit de faire. (c'est bon, respirez ...)

Démo rapide de Anti CSRF

Imaginons que dans un plugin WordPress se trouvent des liens de ce genre :

http://www.example.com/wp-admin/admin.php?bawac_force_nonce=0c52045c54030652570651540851&page=le-plugin&action=delete&id=123

Ce lien supprime par exemple une entrée d'options du plugin en question. WordPress étant bien fait, une personne n'ayant pas les droits ne pourra pas accéder à cette page car la page "admin.php" refusera, ici pas de faille.

Si un admin (ou autre personne ayant les droits d'utiliser ce lien) utilise/clic sur ce lien, l'action sera elle, bien faite.

Même chose pour les formulaires :

Activer le plugin :  Entrez votre ID machin :  

Ici au clic sur "Sauver", le plugin sera activé ou non, selon la coche, et un ID sera sauvegardé. Même chose que précédemment, seul une personne ayant les droits d'accès à cette page pourra valider ce formulaire et personne d'autre.

Alors où est le problème ?

Il ne se voit pas à premier abord, mais il est bien là ! Et si moi, vile utilisateur de votre site, vous envoie ce lien caché dans un bit.ly ? Et bien, VOUS, l'admin, exécuterez cette action, car VOUS en avez les droits, mais VOUS n'en aviez pas la volonté ! Trop tard ...

Pour le formulaire, il vous envoi un lien vers une page qui contient le même formulaire attendu par le plugin, avec "action=http://www.example.com/wp-admin/admin.php?bawac_force_nonce=0c52045c54030652570651540851&page=le-plugin", et cette page envoie de façon discrète (je ne vais pas citer les solutions, mais il en existe plusieurs), même chose, VOUS, l'admin, exécuterez cette action, car VOUS en avez les droits, mais VOUS n'en aviez pas la volonté ! Trop tard aussi ...

C'est grave docteur ?

Euh, parfois, j'avoue que ce n'est pas très grave, si l'action ne fait que modifier un titre de widget, ou désactive le plugin, ce n'est pas très grave, juste ennuyeux à force. Là où ça devient grave c'est si la CSRF est couplé à une XSS (80% des cas), le combo permet de faire des choses énormes, comme le vol des cookies de l'admin, la modifications de contenu du site, la redirection de votre site vers des sites de virus (merci le SEO) ... J'en passe !

Mais pourquoi ! Comment !?

Doucement, je vais quand même donner des solutions, on est pas là pour papoter !

Le tout est de s'assurer que l'action a été réalisée non pas juste par un compte ayant les droits mais aussi réellement par la personne elle même et volontairement.

Pour cela il faut utiliser ce qu'on apelle un "jeton de sécurité" ou "security token". On dit aussi un "nonce" qui signifie "number once" (number used once) qui veut dire "chiffre utilisé une seule fois".

WordPress là aussi est bien fait et a tout ce qu'il faut pour les gérer, les créer, les vérifier, dans le codex : WordPress Nonces

Encore faut-il les utiliser et suivre les recommandations WordPress (qui découlent de recommandations PHP qui découlent de recommandations d'experts en sécurité ...)

Sachez que 40% des plugins, toutes provenances confondues (repository officiel, sites persos, offres premium) contiennent une faille CSRF, oui 40% c'est beaucoup.

Anti CSRF en action

Anti CSRF en action

Comment s'en prémunir (sous WordPress) avec Anti CSRF

Je ne vais pas copier/coller le codex, je vous laisse le lire, mais comme on vous a toujours appris à ne pas modifier les plugins car vous perdriez les modifs lors des prochaines mises à jour, vous ne devez pas ajouter vous même les nonces sur les plugins dont vous aurez détecté la faille.

Donc en plus de prévenir l'auteur (sur la page Support du plugin ,ou par mail à l'auteur, ou contactez moi) vous ne pouvez plus l'utiliser ? SI ! C'est là où j'interviens (genre je suis un sauveur de l'humanité à la sauce WordPress) en mettant mon grain de sel (dans la sauce...) avec ce plugin que je vous propose : Anti CSRF.

Anti CSRF va ajouter dans TOUS les formulaires créés par des plugins, un nonce de plus, et aussi chaque lien pouvant appartenir à un plugin se voit ajouter un nonce. Vous remarquerez que vos liens sur les pages d'options des plugins ont le paramètre "bawac_force_nonce" en plus.

Anti CSRF va vérifier que son propre nonce est valide et réaliser l'action ou la bloquer. Le plugin fonctionne aussi sur les requêtes ajax en injectant avant l'envoie son propre nonce (le même).

Anti CSRF bloque une URL

Anti CSRF bloque une URL

J'ai testé ce plugin sur plusieurs plugins vulnérable et  comme attendu, la faille est bouchée !! Merci Anti CSRF !

Oui mais, je suis dev, comment m'en prémunir  ?

Ha, vous voulez tout de même savoir comment on utilise les nonces WordPress, allez je fais un effort, voici quelques exemples :

Comment créer un nonce correct :

Pour WordPress un nonce est une chaîne de caractère de 10 de long qui est en fait un morceau du hash de votre user ID, du tick time des 12 heures en cours, d'une action et du mot "nonce". L'action par défaut est "-1", vous pouvez la remplacer par ce que vous voulez, je préconise d'utiliser une action "à la WP" comme ceci :

$action-$object_$uniq_id

Ici on pourrait dire "delete-item_123", un nonce doit autant que possible être unique pour chaque lien/formulaire/page. Il est impossible de deviner, recréer un nonce pour un autre utilisateur mais un nonce non unique peut être exploité d'une autre façon (ceci est un autre sujet). Evitez d'utiliser __FILE__, vous aurez un jour des problèmes si le nonce passe d'une page à une autre et ce n'est ni parlant ni clair ni simple à maintenir.

Quelques fonctions et pour qui/quand :

Ajouter un nonce dans une url : wp_nonce_url()
vérifier un nonce venant d'une url : wp_verify_nonce()
Ajouter un nonce dans un formulaire : wp_nonce_field()
Vérifier un nonce venant d'un formulaire : check_admin_referer()
Créer un nonce pour créer soit meme son URL ou son champ ou dans une variable JS (pour Ajax) : wp_create_nonce()
Vérifier un nonce venant d'ajax : check_ajax_referer()

Et Anti CSRF alors !

Oui quand même, cet article est là pour mettre en avant le plugin. Alors pourquoi installer ce plugin ? QUOI ! Vous vous posez encore la question ! Tout simplement que le plugin bouche la faille des plugins mal construits, provocants une faille CSRF. Aucune page d'option, installer, activer, terminé. Toute installation de WordPress qui installe des plugins se DOIT de se protéger de ce type d'attaques ... 40% des plugins ...
Au fait, le plugin en fonctionne "que" dans l'administration.

Share!

Laisser un commentaire

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

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>