La raison de cette naissance est simple, le forum se remplissait de spam de jour en jour depuis plus d'un mois, et il y a deux semaines, ce fut le tour des commentaires de mon site... puis ceux de la galerie... jour après jour, des dizaines de messages contenant des liens innommables à surveiller et rapidement effacer...

J'ai donc cherché à droite et à gauche un script qui ferais l'affaire, quelque chose de facile à adapter à la fois à mon site sous DotClear[1] et à mon forum sous phpBB[2], et en conclusion.... et bien j'ai rien trouvé de concluant ;)

Donc le plus simple était encore de faire un truc à ma sauce, un captcha[3] à base d'image pour commencer, du classique quoi :). J'avais déjà travaillé un peu dessus l'été dernier pour le fun, et j'avais quelques idées pour la sécurité côté transmission du code dans l'image pour la vérification...

Le problème de beaucoup d'anti-bots avec image est qu'il n'y a même pas besoin d'avoir recours à un OCR pour casser le code en le reconnaissant dans l'image. La majorité des anti-bots transmettent le code de l'image pour le reconnaitre ensuite d'une des façons suivantes :

  • dans le code html (très très mauvais anti-bot :) )
  • dans le JavaScript (sécurité faible)
  • dans un cookie (sécurité moyenne)
  • dans une session (sécurité correcte)
  • dans une bdd (sécurité max mais lourd)

On peut facilement discuter du classement que je fais, et même au delà des avantages et inconvénients de telle ou telle technologie, il y a le problème de la transmission des infos. Il faut bien informer le serveur par l'url (GET), ou par en-tête de requête (POST), ou par cookie de l'indice permettant de comparer ou d'accéder au comparateur du code saisi par le visiteur. Et c'est dans la transmission de cette infos qu'il y a le plus souvent une faille...

Un autre faille classique est de ne pas utiliser du aléatoire, et donc soit utiliser des codes récurant avec la même image correspondant à tel code, ou bien d'utiliser une seule police de caractère pour la génération des caractères, voire même utiliser des images pour chaque caractères afin de composer l'image finale...

Bref autant d'erreur dont j'avais conscience tout en devant mettre rapidement quelque chose au point...

Ma solution concernant la sécurité est de reprendre le principe du couple de clé publique/privé utilisé dans le hachage de mot de passe. La clé publique, permettant de récupérer côté serveur la clé privée, se trouve tout simplement en clair dans le code html côté client, dans un champ input caché (type=hidden). La clé privé côté client se trouve dans l'image, c'est la chaine de caractère que doit lire puis saisir le visiteur. En saisissant le code, le visiteur propose ainsi une clé privée au serveur. Le serveur compare alors la clé privée saisie avec celle qu'il a en stock grâce à la clé publique du formulaire qui sert de référence.

C'est tout simple, il suffisait d'y penser... plusieurs systèmes sont basés sur quelque chose de semblable sans avoir réellement cette approche... et puis du coup on utilise ni base de donnée, ni cookie, ni javascript, ni session pour fonctionner avec ce que je propose. Les couples publique/privé sont enregistrés dans un fichier, l'accès à un fichier étant beaucoup plus rapide qu'à un serveur de BDD. Et pour éviter que des bots tentent de se constituer une liste de couple qu'ils auraient reconnus, il suffit de générer une liste de 1000 ou 10000 couples à l'installation. A terme on pourrais même envisager une génération automatique d'une nouvelle liste tous les mois... c'est tellement facile à faire, pourquoi s'en priver :)

Les clés publiques font actuellement 64 caractères de long, chaque caractère pouvant avoir 60 états différents, ce qui nous donne 64^60[4] possibilités de clés publiques différentes... autant dire qu'on est tranquille de ce côté :)

Pour augmenter encore la sécurité, le fichier des couples de clés est naturellement inaccessible au client grâce à un fichier htaccess. Sans ça, le principe perdrait tout son intérêt...

Côté génération d'image, je me suis contenté de jongler entre trois polices de caractères qui restent visibles sans trop se tordre les yeux :p et une génération de grille aléatoire superposé à l'image... ceci reste largement lisible je pense pour mes visiteurs, et suffisamment illisible pour la majorité des bots actuels... en tout cas ça a forcé au silence les bots qui s'agrippaient à moi depuis quelque temps, et aucun nouveau spam depuis le début de la mise en place, soit le début de la semaine ne s'est montré...

Ca fait du bien de souffler un peu :)

De toute façon je ne compte pas en rester là, car je veux diffuser ce travail afin de ne pas être le seul à en profiter... et ce sera ma contribution côté PHP, espérant combler ainsi un manque dans le domaine. Je ne vous donne rien pour l'instant, car ayant codé ça dans l'urgence, c'est un vrai torchon... mais dès que j'ai le temps de faire un peu de ménage dedans[5] je le met à disposition sous GNU-GPL v2 c'est promis !!!

La roadmap[6] est déjà tracé dans ma tête, je la détaillerais un autre jour en fonction de vos retours surtout. Ce que je peux déjà vous dire aujourd'hui c'est que je veux améliorer le script pour qu'il s'adapte facilement à n'importe quel script existant, augmenter la sécurité, et avoir un haut niveau d'accessibilité à terme...

Bref toute ma réflexion continuelle sur les anti-bots, je vais la concentrer sur mon PHPAntiBot afin de le faire le mieux possible et qu'il rende le plus de services possibles !!!

Bon je ne vous file pas d'imprime écran, PHPAntiBot étant en place tout en bas de la page que vous lisez actuellement :) Et pour voir plusieurs exemples, faites F5 :)

MAJ du 03 mai 2007 : PAB v0.1 est disponible depuis un moment en téléchargement. Voir l'article annonçant la sortie : "PAB libre jusqu'au bout"

Notes

[1] http://www.dotclear.net/

[2] http://www.phpbb-fr.com/

[3] Pour savoir ce qu'est un captcha, lisez mon article : Captcha ?!? Heu................

[4] Lire 64 exposant 60 bien sûr

[5] Les vacances arrivent heureusement :)

[6] On peut dire aussi : plan de route...