Un AntiSpam efficace vu en détail

24 octobre 2007 par Julien C. dans Mes astuces

François m’a demandé hier une methode simple d’antispam pour protéger des formulaires. Autant en faire un billet pour l’expliquer.

Le captcha

De nos jours, une des méthodes les plus employées pour mettre à mal les robots spammeurs fous est le captcha, qui consiste à donner une information que seul un humain peut comprendre afin qu’il la reproduise dans un champ, et ainsi, valider le formulaire. De principe, le robot spammeur ne comprend pas cette information et il ne pourra jamais valider son spam.

Voici un exemple de mise en place sur smart-extranet.fr

captcha.jpg

Bien entendu, les spammeurs usent de tout les moyens pour contrer cette protection (tel un hacker s’acharnerait sur un iPhone), afin de décrypter cette information.
Le captcha utilisé dans cet exemple est cryptographp pour ceux que ça tente

L’astuce

Voici une astuce connue qui va vous faire oublier les captchas.
Un robot spammeur, quand il trouve un formulaire, se doit de remplir tous les champs. Cela permet d’être sûr de ne pas être bloqué par les champs obligatoires.
Il arrive à détecter là où il faut mettre un nom, un email, du texte. Bref, le robot spammeur est intelligent.
Mais il suffit de le duper pour mettre à mal toute son énergie à nous polluer.

Si un robot spammeur remplit tous les champs, c’est qu’il parse le code html pour les détecter.
Or nous, humain, c’est le navigateur qui parse le code html et il nous donne un rendu beaucoup plus friendly.
Si dans le code html, on décide de mettre un champ caché via CSS, le robot spammeur lui, le verra, l’humain non.

Au contraire du captcha, on ne tente pas de bloquer le robot mais plutôt l’humain, à la différence que dans notre cas, c’est celui qui est bloqué qui gagne.

Explications : Lors de la validation du formulaire, si le champ caché est renseigné, cela signifie que c’est un robot. Si le champ est vide, c’est un humain.

Voyons un exemple de mise en place par le code :


<form method="post" action="" id="form">
<p style="display:none;">
<label for="txt_pseudo">Ne pas remplir ce champ :</label><br />
<input type="text" size="40" name="txt_pseudo" />
</p>
<p>
<label for="txt_nom">Votre nom :</label><br />
<input type="text" size="40" name="txt_nom" />
</p>
<p>
<label for="txt_email">Votre email :</label><br />
<input type="text" size="40" name="txt_email"/>
</p>
<p>
<label for="txt_msg">Votre message :</label><br />
<textarea name="txt_msg" rows="5" cols="30"></textarea>
</p>
<input type="submit" value="Envoyer" name="btn_env" />
</form>

J’ai placé en début de formulaire un champ texte avec son label, le tout dans une balise p, qui, par CSS, n’est pas affiché dans le navigateur.
Pour des raisons d’accessibilité, je précise bien que ce champ n’est pas à remplir. Ainsi, dans le cas d’un navigateur gérant mal le CSS (donc il fera un rendu du champ caché) ou d’un synthétiseur vocal, l’utilisateur sera prévenu qu’il faut laisser ce champ vide.

Côté PHP, un simple IF fera l’affaire pour tester le champ


$antirobot = htmlspecialchars(isset($_POST["txt_pseudo"])?$_POST["txt_pseudo"]:"erreur");
if(strlen($antirobot) > 0)
{
$msg_err = "Robot détecté";
}
else
{
//on valide le formulaire
}

Et vous voilà protéger ! Cette méthode fonctionne à 100% d’après mes souvenirs.

Avez-vous apprécié Un AntiSpam efficace vu en détail? Suivre les billets RSS.
Social Bookmarking
Add to: Digg Add to: Del.icio.us Add to: Technorati Add to: StumbleUpon Add to: Reddit Add to: Slashdot Add to: Netscape Add to: Furl Add to: Newsvine Add to: Yahoo Add to: Google Add to: Blinklist Add to: Spurl Add to: Diigo Add to: Ma.Gnolia

12 Réponses pour “Un AntiSpam efficace vu en détail”

  1. Deux techniques efficaces pour le site de Mr tout le monde qui veut échapper aux robots arpenteurs
    Préférez la seconde puisqu’elle est plus ergonomique. Les utilisateurs auront plus de facilités à utiliser vos formulaires et donc ils seront plus satisfaits de leur expérience.

    Pour ce qui est des sites de grande envergure qui peuvent attirer les foudres de spammers il n’y a que des captcha très complexes qui fonctionnent. En effet, grâce aux progrès dans le domaine de l’OCR (reconnaissance de caractères) la plupart des captchas tombent via des robots dédiés. Il va sans dire que la petite technique du champ à ne pas remplir ne résiste pas longtemps.

    Duael
  2. Merci l’info et pour ce bout de code!

    fr@nçois
  3. @Dual : Merci de ton point de vue, plutôt d’accord

    @François : De rien :) Tu me feras un petit retour sur la mise en place, voir si tu as eu des difficultés.

    Julien C.
  4. @Duael et pas @Dual, désolé !

    Julien C.
  5. J’avoue que ton astuce est bien pensée, et toute simple à mettre en place !

    J’ai personnellement opté pour une autre solution, un peu plus embêtante à mettre sur pieds, mais je l’espère toute aussi efficace (pour l’instant elle l’est en tout cas !). C’est assez simple dans le principe : je rajoute un champ de vérification, où l’utilisateur doit rentrer le premier et dernier caractère de son message, en respectant la casse. ET après j’ai juste une petite vérif à faire niveau php. Je ne pense pas qu’un robot arrive à passer outre ce genre de système non plus. =)

    delphiki
  6. Intéressant … et très tordu :)

    Julien C.
  7. Pas mal pensé delphiki mais c’est chiant quand tu as un long message.

    Le captcha idéal saurait totalement faire la différence entre un humain et un bot tout en restant invisible pour l’utilisateur …
    IA comportementale ?
    Une chose est sûre, si on parvient à créer ce captcha, on parviendra à créer le bot qui la trompera ;)

    Une petite technique simple également consiste à utiliser JS pour ajouter une valeur au champ juste avant sa validation. Comme les robots n’interprètent pas le JS ça fait un bon barrage. Par contre on met de côté tous les utilisateurs qui l’ont désactivé.

    Duael
  8. Oui, j’avoue avoir des idées un peu (trop) tordues des fois. ;)

    delphiki
  9. Salut,

    sur le sujet on m’a aussi fait part d’une solution assez intelligente et invisible pour l’utilisateur.

    Il s’agit en fait de calculer le temps nécessaire à la validation du formulaire en enregistrant la date de génération de la page (time() en PHP) et en le soustrayant à la date de validation.

    Un utilisateur normal mettra au minimum quelques secondes pour poster un message (excepté dans le cas d’un copier coller très rapide). Un robot le fera très rapidement.

    Il suffit donc de définir un laps de temps permettant de différencier un humain d’un robot. Si on poste plus rapidement que prévu on peut penser que c’est un robot et demander une confirmation via un captcha plus traditionnel (idéalement généré à la volée via de l’Ajax pour plus d’ergonomie).

    Je l’ai pas testé moi même mais ça m’a paru assez intelligent!

    ++

    ptitlu
  10. Hello,
    cacher un champ via CSS est à mon humble avis une mauvaise idée, parce que tous les navigateurs ne rendent pas un parsing “friendly” comme le dit l’article … Et certaines personnes (notamment des déficients visuels ou des aveugles) utilisent d’autres logiciels pour lire les pages Web … et ils tomberont dans le panneau …
    J’ai personnellement opté pour la question et réponse… mais le coup de la première et dernière lettre n’est pas idiot non plus.

    Matthieu
  11. “Pour des raisons d’accessibilité, je précise bien que ce champ n’est pas à remplir. Ainsi, dans le cas d’un navigateur gérant mal le CSS (donc il fera un rendu du champ caché) ou d’un synthétiseur vocal, l’utilisateur sera prévenu qu’il faut laisser ce champ vide.”

    j’ajoute une idée : effectivement c’est ce que je sous entendais, mais ça implique d’alourdir un peu le formulaire.

    Matthieu
  12. Merci Matthieu pour tes commentaires.
    En effet, ça alourdit un peu le formulaire, c’est un détail qui peut être pris en compte. Mais par contre, niveau résultat, ça marche très bien !
    @ plus
    Merci

    Julien C.

Participer !

XHTML: Vous pouvez utiliser ces tags : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>