Spammeur, mon ami !

Stopper les spammeurs (partie 2) : Utiliser le module Stop Form Spam

mercredi 03 juillet 2013 à 15h19 • catégories : Comment faire ?

Dans la première partie, nous avons vu comment créer un formulaire d'enregistrement custom.
Nous avons également tenté de limiter le spam par la mise en place d'un champ caché, supposé être rempli par les bots.

Mais les bots ont évolué et savent à présent gérer la technique du pot de miel (honeypot).
Nous allons utiliser le nouveau module ionize SFS, afin de confronter les données envoyées au formulaire à la base de données du service "Stop Forum Spam".

Qu'est ce que Stop Form Spam ?

Le module SFS (Stop Form Spam) interroge la base de données des spammeurs connus du service Stop Forum Spam

Cette base est alimentée par les contributeurs qui, lorsqu'ils suspectent fortement un spam sur leur formulaire, envoient ces données (IP, username, email, données du spam (evidence)) au service Stop Forum Spam, enrichissant la base.
Le module ionize SFS vérifie l'existence de l'IP ou de l'email envoyé chez Stop Forum Spam.

Le module peut également envoyer les données suspectées comme étant du spam, soit automatiquement si les informations du formulaire sont déjà connues, soit manuellement via un lien ajouté dans l'email envoyé à l'administrateur lors de l'enregistrement de l'utilisateur.
Ceci nécessite une clé API optionnelle mais le module peut fonctionner sans cette option.

Installer le module SFS

Le module SFS nécessite ionize 1.0.4.

Il est disponible ici : https://github.com/ionize/ionize-module-sfs

  • Copier le dossier "Sfs" dans le dossier "/modules" de votre installation de ionize
  • Dans le backend, aller à : Modules > Administration
  • Cliquer on "install"
  • Recharger le backend

Paramétrer le module

  • Dans ionize, ouvrir le panneau d'administration du module
  • Dans le champ de paramétrage nommé "Event", définir un événement par exemple "Myform.register.check"
    Cet événement va être utilisé par le module pour contrôler les données postées

Optionnel : Pour envoyer les données via l'API :

  • Obtenir une clé d'API en s'enregistrant sur : http://www.stopforumspam.com/signup
  • Ajouter la clé obtenue dans le champ API key
  • Renseigner le nom du champ utilisé comme "evidence" (en général, le message envoyé par le spammer)
  • Renseigner les champs utilisés comme nom d'utilisateur par le spammer

Modification de la méthode de traitement du formulaire

Dans le post précédent, nous avions créé une méthode de traitement custom pour le formulaire d'enregistrement.
Nous allons modifier cette méthode pour ajouter la vérification des données via SFS.

Editer le fichier : /themes/your_theme/libraries/Tagmanager/Register.php :

<?php

class TagManager_Register extends TagManager
{
    public static function process_data(FTL_Binding $tag)
    {
        if (TagManager_Form::validate('register'))
        {
            $post = self::$ci->input->post();

            // Fire the event we setup : returns an array
            $results = Event::fire('Myform.register.check', $post);

            $return = TRUE;

            if (is_array($results))
            {
                foreach($results as $result)
                    if ( ! $result)
                        $return = FALSE;
            }

            // The user can register
            if ( return == TRUE)
            {
                // Get user's allowed fields
                $fields = TagManager_Form::get_form_fields('register');
                if ( is_null($fields))
                    show_error('No definition for the form "register"');

                $fields = array_fill_keys($fields, FALSE);
                $user = array_merge($fields, self::$ci->input->post());

                // Compliant with User, based on username
                $user['username'] = $user['email'];
                $user['join_date'] = date('Y-m-d H:i:s');

                // Register fails ?
                if ( ! User()->register($user))
                {
                    $message = User()->error();
                    if ( empty($message))
                        $message = TagManager_Form::get_form_message('error');

                    TagManager_Form::set_additional_error('register', $message);
                }
                else
                {
                    // Get the user saved in DB
                    $user = self::$ci->user_model->find_user($user['username']);

                    if (is_array($user))
                    {
                        // Must be set before set the clear password
                        $user['activation_key'] = User()->calc_activation_key($user);

                        $user['password'] = User()->decrypt($user['password'], $user);

                        // Merge POST data for email template
                        $user = array_merge($user, self::$ci->input->post());

                        // Create data array and Send Emails
                        $user['ip'] = self::$ci->input->ip_address();

                        // Add the SFS API key to the data we will use in the email
                        $sfs_config = Modules()->get_module_config('Sfs');
                        $user['sfs_api_server'] = $sfs_config['api_server'];
                        $user['sfs_api_key'] = $sfs_config['api_key'];
                        $user['sfs_username'] = urlencode($user['firstname'].' '.$user['lastname']);
                        $user['sfs_evidence'] = urlencode($user['message']);

                        TagManager_Email::send_form_emails($tag, '', $user);

                        $message = TagManager_Form::get_form_message('success');
                        TagManager_Form::set_additional_success('register', $message);

                        // Potentially redirect to the page setup in /application/config/forms.php
                        $redirect = TagManager_Form::get_form_redirect();
                        if ($redirect !== FALSE) redirect($redirect);
                    }
                    else
                    {
                        $message = TagManager_Form::get_form_message('error');
                        TagManager_Form::set_additional_error('register', $message);
                    }
                }
            }
            // User cannot register
            // Let's tell him he registered successfully !
            else
            {
                Event::fire('User.register.check.fail', $post);

                $message = TagManager_Form::get_form_message('success');
                TagManager_Form::set_additional_success('register', $message);

                $redirect = TagManager_Form::get_form_redirect();
                if ($redirect !== FALSE) redirect($redirect);
            }
        }
    }
}

Nous avons ajouté les données de résultat du test aux données envoyées à TagManager_Email::send_form_emails().

L'objectif est de pouvoir disposer de ces données au niveau de la vue de l'email envoyé à l'admin. Nous pourrons ainsi ajouter le lien vers l'aPI permettant de déclarer un spammeur, dans le cas où il ne serait pas encore déclaré dans la base de Stop Forum Spam.

Créer le lien d'envoi des données à Stop Forum Spam

Quand un utilisateur s'enregistre, 2 emails sont envoyés :

  • Un email à l'utilisateur, pour le remercier et lui indiquer le lien d'activation de son compte,
  • Un email à l'Admin du site.

Nous allons créer un email custom à destination de l'Admin du site.

Create the custom email view

Copier le fichier :
/application/views/mail/register/to_admin.php
vers :
/themes/your_theme/views/mail/register/to_admin.php
.

ionize va à présent utiliser la vue copiée à la place de la vue par défaut.

Adaptation de l'email custom

Editer le fichier /themes/your_theme/views/mail/register/to_admin.php
et ajouter, après
<ion:message />
(ou quelque part à la fin de la vue) :

<p style="font-size: 11px;color: #444;">
   <br/>
   <br/>
   Declare as SPAM :<br/>
   <a href="<ion:data:sfs_api_server />/add?api_key=<ion:data:sfs_api_key />&username=<ion:data:sfs_username />&email=<ion:data:email />&ip_addr=<ion:data:ip />&evidence=<ion:data:sfs_evidence />">
      <ion:data:sfs_api_server />/add?api_key=<ion:data:sfs_api_key />&username=<ion:data:firstname />%20<ion:data:lastname />&email=<ion:data:email />&ip_addr=<ion:data:ip />
   </a>
</p>

Et voilà !

Nous avons à présent un formulaire d'enregistrement protégé via le module SFS.