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() ) :
Si besoin, le code Javascript Jquery:
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 ]); } }
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.
Partager