Le CSRF exploite un automatisme du navigateur : à chaque requête vers un site, il joint les cookies de ce site, y compris le cookie de session. Une page externe peut donc déclencher une requête vers votre site, et le serveur la reçoit avec les identifiants de la personne connectée. Rien ne la distingue d’un clic volontaire, sauf si le site vérifie qu’elle vient bien de ses propres formulaires. Le MITRE la répertorie sous l’identifiant CWE-352 ; on la note aussi XSRF.
Comment fonctionne une attaque CSRF
L’attaquant prépare une page qui contient une requête vers le site visé : une image invisible dont l’adresse déclenche une action, ou un formulaire caché soumis automatiquement par JavaScript. Il lui reste à attirer la victime sur cette page, par un lien dans un e-mail, un commentaire ou un message. Si elle est connectée au site visé au même moment, la requête part avec sa session.

Comme le souligne l’OWASP, l’attaquant ne voit pas la réponse du serveur. Le CSRF vise donc les requêtes qui changent quelque chose : modifier l’adresse e-mail d’un compte, changer un réglage, créer un utilisateur, supprimer un contenu. Sur l’administration d’un site WordPress, ces actions suffisent souvent à en prendre le contrôle.
Le rôle des cookies SameSite
L’attribut SameSite des cookies limite leur envoi depuis un autre site. Avec Strict, le cookie n’accompagne que les requêtes venues du même site ; avec Lax, il est aussi envoyé lors d’une navigation de premier niveau avec une méthode sûre, comme un simple lien en GET. MDN précise que certains navigateurs appliquent Lax par défaut quand l’attribut est absent. C’est une protection utile, mais partielle : une action déclenchée par un lien GET passe encore, et tous les navigateurs ne se comportent pas de la même façon. Elle s’ajoute donc aux jetons anti-CSRF, sans les remplacer.
Pour WordPress : nonces et contrôle des droits
WordPress protège ses formulaires et liens d’action avec des nonces : des jetons liés à l’utilisateur, à sa session et à l’action demandée, qu’un site tiers ne peut pas deviner. Leur durée de vie est de 24 heures par défaut, découpée en deux périodes de 12 heures. Une extension qui ajoute ses propres actions doit les utiliser à son tour :
// Dans le formulaire
wp_nonce_field( 'monext_enregistrer', 'monext_nonce' );
// Au traitement
check_admin_referer( 'monext_enregistrer', 'monext_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Accès refusé' );
}
wp_nonce_field()etwp_nonce_url()ajoutent le jeton à un formulaire ou à une adresse ;check_admin_referer()le vérifie dans l’administration,check_ajax_referer()dans une requête AJAX,wp_verify_nonce()ailleurs ;current_user_can()reste obligatoire : la documentation de WordPress rappelle qu’un nonce ne sert ni à l’authentification ni au contrôle d’accès.
Comment s’en protéger en tant que propriétaire
Les oublis de nonce restent courants dans les extensions : le CSRF figure parmi les catégories de failles régulièrement publiées, comme le montrent les chiffres sur les failles d’extensions WordPress. Côté propriétaire, les réflexes sont simples : mettre à jour, éviter de naviguer sur des liens inconnus pendant une session d’administration, se déconnecter après une intervention, et ne pas multiplier les comptes administrateurs. Ni WP Masquerade ni un réglage du Tableau de bord ne corrigent un nonce manquant dans une extension : seule sa mise à jour le fait.
Erreurs fréquentes
- Vérifier le nonce sans vérifier les droits : un abonné connecté qui récupère un nonce valide, affiché dans une page qui lui est accessible, peut appeler une action réservée aux administrateurs. C’est la porte ouverte aux failles de type IDOR ou de contrôle d’accès.
- Modifier des données sur une simple requête GET, qui passe même avec des cookies
SameSite=Lax. - Oublier qu’une faille XSS annule la protection : un script exécuté dans la page lit les nonces qu’elle contient.
- Confondre CSRF et clickjacking : ce dernier fait cliquer la victime sur votre vraie page, affichée dans un cadre invisible, ce qu’un nonce n’empêche pas.