Stopper le spam dans le forum

© Christian PAULUS. Document créé le 12 août 2010 , mis à jour le 17 août 2010.

Si les faits ne correspondent pas à la théorie, changez les faits. Albert Einstein

Accueil du site > Astuces > SPIP > Stopper le spam dans le forum

Formulaire / SPIP 2.1.1

Une approche simple pour limiter le spam dans les forums sous SPIP : l’ajout d’un contrôle manuel : sorte de captcha au format texte.

Les captcha sont en général des graphiques voulant représenter plus ou moins lisiblement un mot, un code à recopier dans un champ (voir la page Wikipedia consacrée au captcha).

En réalisant la mise à jour de Quesaco en SPIP 2.1.1, j’ai replacé les formulaires de la distribution. Moins d’une heure après la mise à jour, un petit message commençant par un remerciement en anglais, suivi d’une trentaine de liens sur des sites ... découverte de la nature, des choses de la vie. Le grand classique !

Et ce même type de message posté régulièrement, toutes les heures, d’une adresse IP différente, d’un pays différent, avec une adresse mail et une intro différentes.

Première solution, proposée ici : s’assurer que c’est un humain qui poste en demandant une confirmation : le résultat d’une opération.

Ce n’est pas forcément la bonne solution. Est-ce qu’il y en a une ? Vos propositions et remarques seront les bienvenues.

Et pourquoi ne pas utiliser un captcha graphique ?

D’aucuns pensent que la mise en place d’un captcha graphique rend le site inaccessible aux handicapés visuels. C’est souvent vrai, et bien souvent inaccessible aux personnes âgées, aux personnes qui ne sont pas habituées à répondre à une question qui n’a rien à voir avec le présent formulaire. On parle de handicap cognitif, de hors-contexte, ou de ce que vous voulez, mais en tout cas, mettre en place un captcha graphique et le plus sûr moyen de se débarrasser d’une bonne partie de ses visiteurs un tant soit peu méfiants, impatients.

Vous me direz « Oui, mais un captcha-texte est aussi hors-contexte ». Exact ! Mais il ne romps pas la méthode de communication (je commence ma phrase en texte, je ne la termine pas en image). C’est déjà un début.

Le formulaire du forum SPIP

Le formulaire pour le forum est constitué de deux fichiers :

  • formulaires/forum.html
  • formulaires/forum.php

Première étape : recopier ces deux fichiers dans le dossier formulaires des squelettes du site.

Modification de forum.html. Un diff :

25a26
>         <input type='hidden' name='captcha' value="#ENV{captcha}" />
71a73,76
>         <li><p class='explication'>Anti-spam: merci de compl&#233;ter l&#39;op&#233;ration :
>         <span class="captcha-ope">#EVAL{PETIT_CAPTCHA_OPE}&nbsp;</span>
>         <input type="text" class="text" name="captcha" id="captcha"[ value="(#ENV{captcha})"] size="3" />
>         [ (#ENV**{erreurs}|table_valeur{captcha}|oui) <span class="captcha-err">Erreur</span>]</p></li>

Modification de forum.php. Encore un diff :

12a13,15
> define('PETIT_CAPTCHA_OPE', 'un + un = ');
> define('PETIT_CAPTCHA_RES', serialize(array(2, 'deux')));
>
104a108
>                 'captcha' => _request('captcha'),
234a239,243
>
>         if(!in_array(trim(_request('captcha')), unserialize(PETIT_CAPTCHA_RES))){
>                 $erreurs['captcha'] = 'R&#233;sultat erron&#233;';
>         }
>

Les deux fichiers pour les réfractaires du diff (que je comprends) :

Zip - 17.9 ko
forum.php et forum.html dans formulaires

Optimisation ou personnalisation

Deux constantes sont à disposition : PETIT_CAPTCHA_OPE et PETIT_CAPTCHA_RES.

La première indique l’opération à réaliser par le visiteur, la seconde la réponse attendue.

L’opération peut très bien être une question du style « Combien y-a-t-il de couleurs dans l’arc-en-ciel ? ». La réponse est 7. Pour cet exemple, modifier les deux constantes du fichier forum.php :

define('PETIT_CAPTCHA_OPE', 'Combien y-a-t-il de couleurs dans l'arc-en-ciel ?');
define('PETIT_CAPTCHA_RES', serialize(array(7)));

Un traceur pour debug et optimisation

Dans la version du 17/08/2010 du script joint se trouve un traceur. Il permet d’exporter les données du formulaire (_GET et _POST, dans le sens ou la fonction SPIP _request() cherche les données postées dans cet ordre), dans les 3 étapes CVT, dans un fichier /tmp/formulaire_post.log. Attention, le fichier n’est pas purgé. Si vous activez le trace de cette fonciton, ne pas oublier de faire le ménage de temps en temps. Quand un disque dur sature, c’est la panne assurée.

Historique d’un spam

Le filtre ci-dessus a été mis en place. Le résultat en a été radical. Mais ne doutons pas de la volonté du vilain.

Il y a probablement d’autres spammeurs, qui eux, sont arrêtés par le champ ’nobot’. C’est à vérifier. C’est pour cette raison que je n’ai pas voulu modifier le comportement de ce champ et ajouter un autre pour la fonctionnalité illustrée ici.

Histoire de mieux comprendre la stratégie adoptée par ce spammeur, voici l’historique des interventions :

  • 12 août 2010 à 15h33min : mise en place du filtre “(2 + 2 =)”. Le ’=’ fait partie du filtre afin d’éviter un simple eval().
  • 13 août 2010 à 19h56min : retour d’un spam. Construction très proche des précédents, mais visiblement pas le même créateur. Ceux reçus il y a quelques jours commençaient tous par une phrase compréhensible (« Congrats to all of you », « That’s so awesome ! So very happy for you ! », etc) suivi d’une trentaine de liens. Dans celui reçu ce jour, le contenu du message commence par un assemblage aléatoire de lettres du style « zdwzkzxlmgyq » suivi seulement de trois liens. Visiblement, un humain qui va mettre en place son automate. Car deux heures plus tard, c’est toujours le plus grand calme.
  • 14 août 2010 à 20h57min : retour en masse, une quinzaine reçus en quelques heures, du style du dernier reçu (début aléatoire). Les derniers envois étaient espacés au quart d’heure.
  • 15 août 2010 à 8h17min : modification du filtre pour “(3 + 3 =)” histoire de stopper l’hémorragie. Visiblement ça fonctionne.
  • 15 août 2010 à 10h05min : le retour. Toujours le même. 2 spams simultanés. Idem 1 heure plus tard. Et encore une heure plus tard au lieu de 1 toutes les 10 minutes. Modification de stratégie ou stratégie de post aléatoire ? Peut-être simplement temps-machine ? En tous cas, ça veut dire qu’il interprête la question. A priori.
  • 15 août 2010 à 12h57min modification du filtre pour “un + un = (en chiffre) ”, et du résultat attendu.
  • 17 août 2010 à 16h18min. Sans crier victoire, le calme semble revenu. Un seul post reçu hier, probablement humain. Et là, ça nécessite d’autres mesures (nombre d’URL dans le texte, ratio texte/URL, à voir). Le filtre est maintenant simplifié, la réponse attendue est soit un chiffre, soit un texte.
  • 17 août 2010 à 18h38min. Correction des exemples ci-dessus et des fichiers mis à disposition. Le précédent exemple est disponible en bas de page, documents joints.
  • A suivre...

A lire (si besoin) :

Documents joints

Plussoyez !

Répondre à cet article

  • Stopper le spam dans le forum 12 août 2010 15:34, par squirrel

    Merci pour cette exemple simple et pédagogique !

    je propose que tu installe le plugin nospam ! http://plugins.spip.net/NOSPAM

    L’avantage, c’est qu’il applique toutes les manières de bloquer nos amis les spammeurs, il filtre par ip succecive, par jeton, ou par nombre de commentaires publié trop rapidement, ...ect

    Sinon, il y a une autre technique très simple aussi, elle consiste à ajouter un champs invisible que le client ne doit pas remplir puisqu’il ne le voit pas ! Par contre le robot spammeur lui le détecte et le rempli comme un gros béta ! Et donc on est pas spammé. J’utilise cette technique sur mon formulaire de contact en page index ! Je n’est jamais reçu de spam :)

    L’avantage c’est qu’on n’embête pas le visiteur avec un CAPTCHA !

    squirrel
    http://cedricsolignac.free.fr/

    Répondre à ce message

    • Stopper le spam dans le forum 12 août 2010 16:27, par Christian PAULUS

      Sinon, il y a une autre technique très simple aussi, elle consiste à ajouter un champs invisible que le client ne doit pas remplir puisqu’il ne le voit pas !

      C’est ce que fait (ou doit faire) le champ (input) nobot (consulter le fichier forum.html pour info). Mais certains amis spammeurs semblent avoir trouvé la faille.

      J’avais regardé le plugin NOSPAM avant d’ajouter ces lignes aux formulaires. Le fait de filtrer par adresse IP ne me paraît pas déterminant. Je testerai ce pluging ASAP. En tous cas, depuis ce matin, j’ai une paix royale de ce côté.

      Merci pour ton avis.

      Topic à suivre...

      Répondre à ce message

      • Stopper le spam dans le forum 13 août 2010 11:00, par squirrel
        C’est ce que fait (ou doit faire) le champ (input) nobot (consulter le fichier forum.html pour info). Mais certains amis spammeurs semblent avoir trouvé la faille. »

        Peut être que le champ input nobot pourrait avoir un champ rempli par défault avec une valeur précise. Donc, si une autre valeur est ajouter ou remplacer alors le formulaire n’envoi pas :)

        En plus je pense que le chiffre 4 devait ếtre aléatoire, parce qu’à force les robots vont trouver le 4.

        Répondre à ce message

        • Stopper le spam dans le forum 13 août 2010 11:04, par Christian PAULUS

          En plus je pense que le chiffre 4 devait ếtre aléatoire

          Oui, c’est ce que je ferai. Le code est déjà prêt. Là, j’attends juste pour savoir combien de temps ça va tenir ;-)

          Répondre à ce message

    • une idée de programmeur débutant 10 janvier 2012 01:21, par sylvano

      Bonjour à tous !

      Je partirais plutôt du principe que le spam que nous recevons vient de robots "entrainés", c’est à dire spécialisés dans spip : ils connaissent la structure du formulaire_forum, ainsi que le nom du champ "nobot" à ne pas remplir... (il est vraisemblable que les programmeurs des robots se tiennent même ici au courant des dernières astuces mises en place... ;)
      Et si on remplaçait les valeurs des attributs name de chacun des champs par des valeurs personnalisées que chacun choisirait (à remplacer dans le squelette et le php). Il faudrait probablement changer aussi la valeur de l’attribut "id", pour que ces champs-là ne puissent plus être tracés.

      J’ai voulu commencer à le faire à la main sur deux de mes sites, mais problème, difficile de trouver où sont récupérés les champs "titre" et "texte", puisqu’ils passent par le traitement des raccourcis typographiques... Peut-être que quelqu’un pourrait écrire la fonction à placer dans le fichier mes-fonctions.php ? Car faire les modifs en dur me semble être un peu au delà du raisonnable...)

      une idée, comme ça...

      Mais pourquoi les programmeurs de spip n’ont pas inclus une protection plus efficace ? les plugins captcha/nospam/etc... ne sont pas certifiés spip 2.

      Répondre à ce message