Si vous avez un site en prod sous WordPress avec un formulaire sous contact form 7, vous avez probablement dû remarquer que les spammeurs se donnent à coeur joie.
Pour moi la mésaventure a commencé lorsque mon hébergeur a décidé de me bloquer mes scripts d’emails, car beaucoup trop de spammeurs s’amusaient à spammer mes formulaires de contact.
Les solutions que j’ai testées
Avec plus de 5 millions d’installations active contact form 7 devait bien avoir des addons ou autres anti-spam d’une efficacité à toutes épreuves, me suis-je dit 😅.
Mais après avoir installer le fameux recaptcha (super moche) et l’incontournable akismet, j’ai baissé ma garde, à ce moment-là vous vous en doutez… mon hébergeur a re bloqué mes scripts emails 😡.
À la recherche d’un réel anti-spam
J’ai donc retroussé mes manches et pris réellement le problème en considération ! J’ai cherché sur le web des solutions à ce problème mais rien de bien convaincant.
Je me suis mis à surveiller les logs sur l’hébergeur afin de voir si mes formulaires étaient utilisés.
Oui oui j’ai bien dit les logs, vu que mon hébergeur me bloquait les mails, je devais donc voir l’activité du côté des logs pour savoir si les formulaires étaient envoyés, en bonus j’avais les Ips des expéditeurs donc je voyais vite quand c’était des spammeurs.
Dans ma page de logs je faisais un cmd + F (sur Mac) pour rechercher dans la page et je tapais “POST /wp-json/contact-form-7” car c’était le début de l’URL qu’appelait Contact Form 7 pour valider le formulaire.
Déboguer et ne perdez plus vos emails avec Contact Form Advanced Database
Mais j’ai vite constaté que cela ne suffisait pas pour débugger la situation j’ai donc installé un plugin très cool nommé Contact Form Advanced Database qui permet de stocker en base de donner les emails des formulaires de CF7 et de les consulter en back office directement, ce qui m’a permis aussi de ne pas rater les vrais emails que je recevais.
À présent j’avais de quoi analyser ce qui se passait concrètement sur mes formulaires.
Bloquer les spammeurs avec “1+5=?”
J’ai donc essayé tout un tas de solutions trouvées sur le web ici et là après plusieurs tentatives j’ai fini par creuser une piste, celle d’un quiz avec le shortcode de CF7 en fin de formulaire pour filtrer les robots.
J’ai mis donc une question simple “1+5=?”, je me suis dit c’est bon les scripts des spammeurs ne passeront jamais ça ! 😎
J’étais vraiment optimiste et là je vois dans mon back office, sans pression… les spammeurs continuaient à m’enchainer de mails 😡. Je me suis dit peut-être qu’ils ont adapté le script j’ai donc tenté une multitude de quizz de calcul mis aléatoirement, mais ils passaient encore😢.
Un robot ou un humain fort en math 🤔?
Pour valider mon hypothèse que ce n’était pas des humains derrière j’ai décidé de cacher le champ du quiz en le mettant dans une div que j’allais non pas mettre en display:none;
mais plutôt de la cacher d’une manière moins conventionnel en me disant que le script pourrais prendre ça pour un honeypot* (car j’avais essayé cette méthode avant, mais sans succès), voici le code que j’ai utilisé pour cacher ma div :
[quiz quiz-math "1+1=?|2" "1+2=?|3" "1+3=?|4"]
Si vous comprenez le CSS vous avez vu que j’ai envoyé le champ dans le néant en dehors de la partie visible de la page web, à partir de cet instant aucun humain ne pouvait envoyer avec succès un message dans mon formulaire, le piège était en place.
Mon ultime plan anti-spams !
Solution 1: Un quiz caché que le script peut résoudre
[quiz quiz-math "1+1=?|" "1+2=?|" "1+3=?|" "1+4=?|" "1+5=?|" "1+6=?|" "1+7=?|" "1+8=?|" "1+9=?|" "2+1=?|" "2+2=?|" "2+3=?|" "2+4=?|" "2+5=?|" "2+6=?|" "2+7=?|" "2+8=?|" "2+9=?|" "3+1=?|" "3+2=?|" "3+3=?|" "3+4=?|" "3+5=?|" "3+6=?|" "3+7=?|" "3+8=?|" "3+9=?|" "4+1=?|" "4+2=?|" "4+3=?|" "4+4=?|" "4+5=?|" "4+6=?|" "4+7=?|" "4+8=?|" "4+9=?|" "5+1=?|" "5+2=?|" "5+3=?|" "5+4=?|" "5+5=?|" "5+6=?|" "5+7=?|" "5+8=?|" "5+9=?|" "6+1=?|" "6+2=?|" "6+3=?|" "6+4=?|" "6+5=?|" "6+6=?|" "6+7=?|" "6+8=?|" "6+9=?|" "7+1=?|" "7+2=?|" "7+3=?|" "7+4=?|" "7+5=?|" "7+6=?|" "7+7=?|" "7+8=?|" "7+9=?|" "8+1=?|" "8+2=?|" "8+3=?|" "8+4=?|" "8+5=?|" "8+6=?|" "8+7=?|" "8+8=?|" "8+9=?|" "9+1=?|" "9+2=?|" "9+3=?|" "9+4=?|" "9+5=?|" "9+6=?|" "9+7=?|" "9+8=?|" "9+9=?|"]
J’ai repris mon idée de champs perdus dans le néant mais ce coup si j’allais modifier son usage afin qu’il trompe le bot, je lui donnerais des calculs à résoudre mais en mettant en réponse correct un champ vide.
Solution 2: Un calcul en toutes lettres et en français
[quiz quiz-two
"un + un font ? (écrire le résultat en chiffre)|2" "un + deux font ? (écrire le résultat en chiffre)|3" "un + trois font ? (écrire le résultat en chiffre)|4" "un + quatre font ? (écrire le résultat en chiffre)|5" "un + cinq font ? (écrire le résultat en chiffre)|6" "un + six font ? (écrire le résultat en chiffre)|7" "un + sept font ? (écrire le résultat en chiffre)|8" "un + huit font ? (écrire le résultat en chiffre)|9" "un + neuf font ? (écrire le résultat en chiffre)|10" "deux + un font ? (écrire le résultat en chiffre)|3" "deux + deux font ? (écrire le résultat en chiffre)|4" "deux + trois font ? (écrire le résultat en chiffre)|5" "deux + quatre font ? (écrire le résultat en chiffre)|6" "deux + cinq font ? (écrire le résultat en chiffre)|7" "deux + six font ? (écrire le résultat en chiffre)|8" "deux + sept font ? (écrire le résultat en chiffre)|9" "deux plus huit font ? (écrire le résultat en chiffre)|10" "deux plus neuf font ? (écrire le résultat en chiffre)|11" "trois plus un font ? (écrire le résultat en chiffre)|4" "trois plus deux font ? (écrire le résultat en chiffre)|5" "trois plus trois font ? (écrire le résultat en chiffre)|6" "trois plus quatre font ? (écrire le résultat en chiffre)|7" "trois plus cinq font ? (écrire le résultat en chiffre)|8" "trois plus six font ? (écrire le résultat en chiffre)|9" "trois plus sept font ? (écrire le résultat en chiffre)|10" "trois plus huit font ? (écrire le résultat en chiffre)|11" "trois plus neuf font ? (écrire le résultat en chiffre)|12" "quatre plus un font ? (écrire le résultat en chiffre)|5" "quatre plus deux font ? (écrire le résultat en chiffre)|6" "quatre plus trois font ? (écrire le résultat en chiffre)|7" "quatre plus quatre font ? (écrire le résultat en chiffre)|8" "quatre plus cinq font ? (écrire le résultat en chiffre)|9" "quatre plus six font ? (écrire le résultat en chiffre)|10" "quatre plus sept font ? (écrire le résultat en chiffre)|11" "quatre additionné à huit fait ? (écrire le résultat en chiffre)|12" "quatre additionné à neuf fait ? (écrire le résultat en chiffre)|13" "cinq additionné à un fait ? (écrire le résultat en chiffre)|6" "cinq additionné à deux fait ? (écrire le résultat en chiffre)|7" "cinq additionné à trois fait ? (écrire le résultat en chiffre)|8" "cinq additionné à quatre fait ? (écrire le résultat en chiffre)|9" "cinq additionné à cinq fait ? (écrire le résultat en chiffre)|10" "cinq additionné à six fait ? (écrire le résultat en chiffre)|11" "cinq additionné à sept fait ? (écrire le résultat en chiffre)|12" "cinq additionné à huit fait ? (écrire le résultat en chiffre)|13" "cinq additionné à neuf fait ? (écrire le résultat en chiffre)|14" "six additionné à un fait ? (écrire le résultat en chiffre)|7" "six additionné à deux fait ? (écrire le résultat en chiffre)|8" "six additionné à trois fait ? (écrire le résultat en chiffre)|9" "six additionné à quatre fait ? (écrire le résultat en chiffre)|10" "six additionné à cinq fait ? (écrire le résultat en chiffre)|11" "six additionné à six fait ? (écrire le résultat en chiffre)|12" "six additionné à sept fait ? (écrire le résultat en chiffre)|13" "six + huit font ? (écrire le résultat en chiffre)|14" "six + neuf font ? (écrire le résultat en chiffre)|15" "sept + un font ? (écrire le résultat en chiffre)|8" "sept + deux font ? (écrire le résultat en chiffre)|9" "sept + trois font ? (écrire le résultat en chiffre)|10" "sept + quatre font ? (écrire le résultat en chiffre)|11" "sept + cinq font ? (écrire le résultat en chiffre)|12" "sept + six font ? (écrire le résultat en chiffre)|13" "sept + sept font ? (écrire le résultat en chiffre)|14" "sept + huit font ? (écrire le résultat en chiffre)|15" "sept + neuf font ? (écrire le résultat en chiffre)|16" "huit + un font ? (écrire le résultat en chiffre)|9" "huit + deux font ? (écrire le résultat en chiffre)|10" "huit + trois font ? (écrire le résultat en chiffre)|11" "huit + quatre font ? (écrire le résultat en chiffre)|12" "huit + cinq font ? (écrire le résultat en chiffre)|13" "huit + six font ? (écrire le résultat en chiffre)|14" "huit + sept font ? (écrire le résultat en chiffre)|15" "huit + huit font ? (écrire le résultat en chiffre)|16" "huit + neuf font ? (écrire le résultat en chiffre)|17" "neuf + un font ? (écrire le résultat en chiffre)|10" "neuf + deux font ? (écrire le résultat en chiffre)|11" "neuf + trois font ? (écrire le résultat en chiffre)|12" "neuf + quatre font ? (écrire le résultat en chiffre)|13" "neuf + cinq font ? (écrire le résultat en chiffre)|14" "neuf + six font ? (écrire le résultat en chiffre)|15" "neuf + sept font ? (écrire le résultat en chiffre)|16" "neuf + huit font ? (écrire le résultat en chiffre)|17" "neuf + neuf font ? (écrire le résultat en chiffre)|18"
]
Puis pour renforcer encore cette sécurité j’ai mis un champ où il faudra faire un vrai calcul mais je l’ai mis en toutes lettres (exemple “deux plus deux font ?”), je me suis dit avant que les scripts russes se mettent aux additions écrites en français j’ai de la marge !
Conclusion
Les spams sont pour une écrasante majorité des scripts plus ou moins sophistiqués, je ne suis pas pour personnellement gâcher l’expérience utilisateur pour bloquer les spams, c’est ce qui m’a mené à avoir cette réflexion.
Je vous conseillerais donc si vous aussi vous utilisez contact form 7 à mettre en place l’un des deux codes que je vous ai fournis plus haut où même les deux si comme moi vous voulez vraiment être sûr de votre coup.
*honeypot est une méthode anti-spam qui consiste à cacher un champ qui doit rester vide, si celui-ci est rempli le formulaire ne s’envoie pas, l’intérêt étant que le robot ne fasse pas la différence entre un élément en display:none;
et un élément visible par l’utilisateur.