IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Protection d'un formulaire anti-spam avec une addition


Sujet :

Langage PHP

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2021
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2021
    Messages : 4
    Points : 6
    Points
    6
    Par défaut Protection d'un formulaire anti-spam avec une addition
    Bonjour à toutes et à tous !

    Je rencontre actuellement un bug qui me tracasse:

    Il s'agit de protéger un formulaire de contact contre le spam à l'aide d'un honeypot (un champ caché à l'utilisateur qui sera rempli automatiquement par le bot et l'on vérifiera lors du traitement avec PHP si le champ est vide ou non).

    Le honeypot fonctionne.

    L'autre sécurité: Proposer une addition générée aléatoirement à l'utilisateur qui devra rentrer la bonne somme dans le formulaire. Le résultat sera également vérifié côté PHP.

    Note: Le formulaire utilise Ajax via Jquery. L'envoi du mail se fait avec Swiftmailer.

    Le soucis provient de cette dernière sécurité: Le mail, que la somme soit bonne ou mauvaise, refuse de partir. J'ai comme l'impression que la somme n'est pas considérée comme exacte. Ou alors, selon les paramètres (simple égal au lieu d'un triple égal lors de la vérification), le mail part dans les deux cas...

    J'ai tenté de débuguer, je n'arrive pas à déterminer où se situe le problème.

    Pour vous expliquer ma méthode:

    • Je génère deux nombres aléatoirement compris entre 1 et 20 avec la fonction rand() .
    • Je stocke dans une session le résultat de l'addition de ces deux nombres.
    • Ensuite, je vérifie si le nombre envoyée par le formulaire est égal au nombre stocké en session.
    • Si la donnée est correcte, je passe une variable $SecurityCheck à true. Si ce n'est pas le cas je passe cette dernière à false.
    • Pour terminer, pour confirmer la procédure d'envoi du mail, je vérifie si le honeypot a fonctionné (ou plutôt n'a pas fonctionné) et si $SecurityCheck est égal à true.


    Ensuite, le message d'erreur ou de réussite est passé à Ajax qui se charge de l'afficher.

    Je vous poste ici mon formulaire html:
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     <div class="box-form-contact">
                    <h4>Par mail :</h4>
                    <form id="contact-form" action="sendmail.php" method="post">
                        <p class="form-group"><label for="nameFirstname">Nom et prénom:</label></p>
                        <p class="form-group"><input type="text" name="nameFirstname" id="nameFirstname" class="form-input-line" required/></p>
                        <p class="form-group"><label for="email">Votre email:</label></p>
                        <p class="form-group"><input type="email" name="email" id="email" class="form-input-line" required/></p>
                        <p class="form-group"><label for="subject">Sujet:</label></p>
                        <p class="form-group"><input type="text" name="subject" id="subject" class="form-input-line" required/></p>
                        <p class="form-group"><label for="email">Votre message:</label></p>
                        <p class="form-group"><textarea name="message" id="message" rows="10" cols="50" class="form-input-area" required></textarea></p>
    <!-- Honeypot -->
                        <p class="form-group-zap2"><label for="country">Country:</label></p>
                        <p class="form-group-zap2"><input type="text" name="country" id="country" class="form-input-line"/></p>
    <!-- Fin du Honeypot -->
    <!-- Le champ pour l'addition de sécurité -->
                        <p class="form-group"><label for="security">Combien font <?php echo $FirstNumber; ?> + <?php echo $SecondNumber; ?> ?</label></p>
                        <p class="form-group"><input type="number" name="security" id="security" class="form-input-line" required></p>
    <!-- Fin du champ de l'addition de sécurité -->
                        <p class="form-group"><input type="submit" class="form-input-submit" value="Envoyer le message" /></p>
                    </form>
    <!-- Un loading qui s'affiche durant le traitement du formulaire qui est contrôlé avec Jquery --> 
                    <div class="loading"><img src="loading.gif" class="loading" alt="Mail en cours d'envoi." /></div>
    <!-- L'endroit où sera affiché le message d'erreur --> 
                    <aside class="alert d-none"></aside>
                  </div>

    Le code PHP (note: il est inclus avec include_once() dans la page du formulaire pour bien générer le session_start() ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    <?php
    session_start();
    //Security
    $FirstNumber = rand(1,20);
    $SecondNumber = rand(1,20);
    $TotalNumber = $FirstNumber + $SecondNumber;
    $_SESSION['SecurityNumber'] = $TotalNumber;
     
     
    //On vérifie si tout les variables POST existent
    if (isset($_POST['nameFirstname']) and isset($_POST['email']) and isset($_POST['subject'])and isset($_POST['message']) and isset($_POST['security']) and isset($_POST['country'])) {
     
     
        //On sécurise la variable qui contient le résultat de l'addition envoyée par le formulaire
        $security = htmlspecialchars($_POST['security']);
     
        // on vérifie si le résultat envoyé par le formulaire correspond bien à ce que l'on a en session
        if($security === $_SESSION['SecurityNumber']) 
        {
            $SecurityCheck = true;
        }
        else 
        {
            $SecurityCheck = false;
        }
        //Si le honeypot est bien vide et si le résultat de l'addition est correct on passe à l'envoi du mail
        if (empty($_POST['country']) AND $SecurityCheck === true) {
            $name = htmlspecialchars($_POST['nameFirstname']);
            $email = htmlspecialchars($_POST['email']);
            $subject = htmlspecialchars($_POST['subject']);
            $description = htmlspecialchars($_POST['message']);
     
     
            header('Content-Type: application/json');
     
            require __DIR__ . '/vendor/autoload.php';
     
            $transport = (new Swift_SmtpTransport('nomduservicemail.net', 587))
                ->setUsername('xxxxxxxxxxxxxxx')
                ->setPassword('xxxxxxxxxxxx');
     
            $mailer = new Swift_Mailer($transport);
     
            $message = (new Swift_Message("Nouveau message de {$name}[{$email}] : {$subject}"))
                ->setFrom(['xxxxxxxxxxxxxxxxxx'])
                ->setTo(['xxxxxxxxxxxxxxxxxxx'])
                ->setReplyTo($email)
                ->setBody($description);
            // On encode le résultat
            $result = $mailer->send($message);
            echo json_encode([
                'result' => $result
            ]);
        } else {
            //Si les conditions ne sont pas remplies on encode le résultat pour l'affichage du message
            $result = false;
            echo json_encode([
                'result' => $result
            ]);
        }
    }
    Si besoin, le code Javascript Jquery:

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $(function () {
     
        $(".loading").hide();
     
        $('#contact-form').submit(function (event) {
            event.preventDefault();
            $(".loading").show();
            $.post($(this).attr('action'), $(this).serializeArray(), function (data) {
                let $aside = $('aside');
     
                if (data.result === 1) {
                    $(".loading").hide();
                    $aside.addClass('alert-success').text('Le message a bien été envoyé !').removeClass('d-none');
     
                } else {
                    $(".loading").hide();
                    $aside.addClass('alert-danger').text('Erreur lors de l\'envoi du message !').removeClass('d-none');
     
                }
            });
     
        });
     
    });


    Voila. Je vous avoue que je taffe dessus depuis deux soirées maintenant et je n'arrive pas à trouver où se situe l'erreur..


    Je vous remercie d'avance pour vos réponses.

    Cordialement;

    Valentin.

  2. #2
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 235
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 235
    Points : 15 532
    Points
    15 532
    Par défaut
    vous avez le souci d'envoi quand vous testez le formulaire ou quand une autre personne le test ?
    si c'est une autre personne, je vous conseille d'enregistrer le maximum d'informations dans un journal (contenu de $_POST et $_SESSION, valeurs des variables) quand l'e-mail ne part pas. peut être que le testeur a ajouté un espace quelque part ou alors il a un navigateur défectueux qui vide la session à chaque appel.

  3. #3
    Membre confirmé
    Homme Profil pro
    Autre
    Inscrit en
    Juillet 2021
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Juillet 2021
    Messages : 321
    Points : 642
    Points
    642
    Par défaut
    Bonjour,

    Tu as un problème sur la gestion des données en session :
    - Au premier chargement de la page pour afficher le formulaire (première requête http), ton script PHP est exécuté et deux nombres aléatoires sont enregistrés en session.
    - Lorsque l'utilisateur soumet le formulaire (deuxième requête http), ton script PHP est de nouveau exécuté et donc deux nouveaux nombres aléatoires sont enregistrés en session, ce qui écrase les deux nombres aléatoires enregistrés sur la première requête http.

    En conséquence, tu ne peux pas vérifier que la somme envoyé par l'utilisateur sur la deuxième requête http correspond bien à la somme des deux nombres aléatoires générés lors de la première requête puisque ces derniers sont écrasés.

    Ton script PHP ne doit donc pas générer de nouveaux nombres aléatoires lors de la soumission du formulaire.
    Tu peux éventuellement vérifier si la variable $_SESSION['SecurityNumber'] est déjà définie avec isset afin d'y enregistrer la somme des nombres aléatoire uniquement si cette variable n'est pas définie.

Discussions similaires

  1. [AC-2010] Connexion d'un formulaire en ligne avec une macro Access
    Par Azuriate dans le forum Macros Access
    Réponses: 0
    Dernier message: 25/11/2019, 17h43
  2. Anti Spam avec authentification
    Par Yepazix dans le forum Outlook
    Réponses: 0
    Dernier message: 19/01/2019, 14h02
  3. Anti spam avec authentification de l'expéditeur
    Par claude28 dans le forum C++
    Réponses: 11
    Dernier message: 13/01/2017, 08h31
  4. Réponses: 1
    Dernier message: 29/10/2013, 12h13
  5. Problème avec une addition...
    Par 10-nice dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 19/11/2005, 14h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo