Formulaire recu par mail avec mauvais caracteres

demande de verification du code

Le problème exposé dans ce sujet a été résolu.

Bonjour

J'ai rédigé ce formulaire qui s'envoie par mail en format html.

Le probleme etant que les caracteres avec accents sont mal affichés une fois le mail recu.

Je le soumet à votre analyse:

Merci d'avance

  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
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
            <?php

            if(isset($_POST['submit']))
            {
                $regex_email = "#^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]{2,}\.[a-zA-Z]{2,4}$#";
                $email = stripslashes(htmlentities($_POST['email'], ENT_QUOTES));


                        $societe = stripslashes(htmlentities ($_POST['societe'], ENT_QUOTES));
                        $nom = stripslashes(htmlentities ($_POST['nom'], ENT_QUOTES));
                        $prenom = stripslashes(htmlentities ($_POST['prenom'], ENT_QUOTES));
                        $adresse = stripslashes(htmlentities ($_POST['adresse'], ENT_QUOTES)); 
                        $codepostal = stripslashes(htmlentities ($_POST['codepostal'], ENT_QUOTES)); 
                        $ville = stripslashes(htmlentities ($_POST['ville'], ENT_QUOTES)); 
                        $email = stripslashes(htmlentities ($_POST['email'], ENT_QUOTES)); 
                        $telephone = stripslashes(htmlentities ($_POST['telephone'], ENT_QUOTES));
                        //piscine
                        $couvertname = stripslashes(htmlentities ($_POST['couvertname'], ENT_QUOTES));
                        $largeur = stripslashes(htmlentities ($_POST['largeur'], ENT_QUOTES));
                        $longueur = stripslashes(htmlentities ($_POST['longueur'], ENT_QUOTES));
                        $hauteurhaut = stripslashes(htmlentities ($_POST['hauteurhaut'], ENT_QUOTES));
                        $hauteurbas = stripslashes(htmlentities ($_POST['hauteurbas'], ENT_QUOTES));
                        $materiau = stripslashes(htmlentities ($_POST['materiau'], ENT_QUOTES));
                        $longueur = stripslashes(htmlentities ($_POST['longueur'], ENT_QUOTES));
                        $datservice = stripslashes(htmlentities ($_POST['datservice'], ENT_QUOTES));
                        $autrestravaux = stripslashes(htmlentities ($_POST['autrestravaux'], ENT_QUOTES));
                        //message
                        $request = stripslashes(htmlentities ($_POST['request'], ENT_QUOTES));
                        $request = nl2br($request);
                        $headers  = 'MIME-Version: 1.0' . "\r\n";
                        $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
                        $headers .= 'From: <'.$email.'>' . "\r\n";


                        $subject = 'le formulaire rempli';
                        $date = date('j/n/Y');
                        $ip = $_SERVER['REMOTE_ADDR'];

                        $message='
                        <html>
                        <head>
                        </head>
                        <body>
                        <p>Le '.$date.' </p>
                        <div style="border: 1px solid black; padding: 4px; margin-bottom: 3px;">
                        <p>Société: '.$societe.'</p>
                        <p>Nom: '.$nom.' </p>
                        <p>Prénom: '.$prenom.' </p>
                        <p>Adresse: '.$adresse.' </p>
                        <p>Code postal: '.$codepostal.' </p>
                        <p>Ville: '.$ville.' </p>
                        <p>E-mail: '.$email.'</p>
                        <p>Téléphone: '.$telephone.' </p>
                        </div>
                        <div style="border: 1px solid grey; padding: 4px; margin-bottom: 3px;">
                        <p>Piscine couverte ? : '.$couvertname.' </p>
                        <p>Largeur: '.$largeur.' </p>
                        <p>Longueur: '.$longueur.' </p>
                        <p>Hauteur au + bas: '.$hauteurbas.' </p>
                        <p>Hauteur au + haut: '.$hauteurhaut.' </p>
                        <p>Materiau: '.$materiau.' </p>
                        <p>Longueur: '.$longueur.' </p>
                        <p>Mise en service: '.$datservice.' </p>
                        <p>Autres travaux: '.$autrestravaux.' </p>
                        </div>
                        <div style="border: 1px solid black; padding: 4px;">
                        <p>'.$request.' </p>
                        </div>
                        <p>IP: '.$ip.'</p>
                        </body>
                        </html>
                        ';

                        $to = '***blabla@or**.fr';
                        mail($to, $subject, $message, $headers);
                        $to2 = '*****blba@gm**.com'; 
                        mail($to2, $subject, $message, $headers);

                        if (isset($_POST['submit']))
                        {

                            echo '<div class="mailok">Votre demande a bien été envoyée<br />Nous vous contacterons dans les meilleurs délais par e-mail ou téléphone.<br />Merci pour l\'intéret que vous portez à notre travail.</div>';
                        }
            }       

         else
         {
                ?>

                <form action="" method="POST">

                    <fieldset>
                        <legend>Vos informations</legend>
                            <label for="societe">Société: <input type="text" name="societe" id="societe" placeholder="Société" /></label>
                            <label for="name">Nom(*):  <input type="text" name="nom" id="name" placeholder="Nom(*)" required /></label>
                            <label for="prenom">Prénom: <input type="text" name="prenom" id="prenom" placeholder="Prénom" /></label>
                            <label for="adresse">Adresse: <input type="text" name="adresse" id="adresse" placeholder="Adresse" /></label>
                            <label for="codepostal">Code postal: <input type="text" name="codepostal" id="codepostal" placeholder="Code postal" /></label>
                            <label for="ville">Ville: <input type="text" name="ville" id="ville" placeholder="Ville" /></label>
                            <label for="email">Votre e-mail(*): <input type="email" name="email" id="email" placeholder="E-mail(*)" required /></label>
                            <label for="telephone">Téléphone: <input type="tel" name="telephone" id="telephone" placeholder="Téléphone" /></label>
                    </fieldset>

                    <fieldset>
                        <legend>Votre piscine</legend>
                            <label for="largeur">Largeur: <input type="text" name="largeur" id="largeur" placeholder="Largeur" /></label>
                            <label for="longueur">Longueur: <input type="text" name="longueur" id="longueur" placeholder="Longueur" /></label>
                            <label for="hauteurbas">Hauteur au + bas: <input type="text" name="hauteurbas" id="hauteurbas" placeholder="Hauteur au + bas" /></label>
                            <label for="hauteurhaut">Hauteur au + haut: <input type="text" name="hauteurhaut" id="hauteurhaut" placeholder="Hauteur au + haut" /></label>
                            <label for="materiau">Matériau sur lequel sera appliqué le revêtement polyester: <input type="text" name="materiau" id="materiau" placeholder="Matériau" /></label>
                            <label for="datservice">Date de mise en service de la piscine: <input type="text" name="datservice" id="datservice" placeholder="Date de mise en service" /></label>
                            <label for="autrestravaux">Autres travaux: <input type="text" name="autrestravaux" id="autrestravaux" placeholder="Autres travaux" /></label>
                    </fieldset>

                <span class="couverte">
                            Votre piscine est-elle couverte ?<br/>
                            <label for="oui"><input type="radio" name="couvertname" value="Oui" id="oui" /> Oui</label>
                            <label for="non"><input type="radio" name="couvertname" value="Non" id="non" /> Non</label> 


                    <textarea name="request" rows="4" cols="40">Votre message:</textarea>
                </span> 
                    <input type="submit" name="submit" value="envoyer" class="bouton" />

                </form>
         <?php
         }
             ?>
+0 -0

Salut :)

Il faut rajouter dans le header un $headers .='Content-Transfer-Encoding: 8bit'; pour tout ce qui est accent/etc. Sinon ca encode en 7bit et ca marche pas :|

Si vous avez des mails en anglais vous verrez dans la source du mail un Content-Transfer-Encoding: 7bit, et en français le 7 devient un 8 :)

Ps : la validation d'adresse mail avec une regex c'est pas top… Notamment car dans les RFC y'a rien qui interdit une adresse de la forme "Toto il est [g3nt1l]"_et-cool.Sisi@president. Ok c'est pas courant, mais du moment que c'est quelquechose@quelquechose c'est une adresse mail valide.

+1 -0

Ligne 90 j'ai laissé <form action =""> vide.

Est ce que cela pourrait etre en rapport avec le probleme?

Je ne vois pas quelle page de destination y mettre etant donné que tout est sur la meme page.

En tout cas je precise que tout est enregistré en UTF-8 sans BOM

+0 -0

Le <form action =""> ne pose pas de problème, ca donne juste la page actuelle en destinatrice du "form".

Puisque ce marche en local et pas sur ton serveur je pencherais plus vers ce que dit mon VDD. Tu as bien la page du formulaire encodé en utf8 ?

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> dans le header de la page ?

Si c'est pas lié à l'encodage de ton serveur, par sûr que ca marche pour toi, mais j'ai trouvé ca : essaie de mettre '=?UTF-8?B?'.base64_encode($subject).'?=' à la place de juste $subject. Car normalement on a pas le droit au non-ASCII dans le header, et le "sujet" fait parti du "header" en réalité.

(source : http://ncona.com/2011/06/using-utf-8-characters-on-an-e-mail-subject/)

Merci pour vos reponses.

Perchan: Je viens de poser la question sur le forum d'OVH :)

Gwend@l: J'ai cette balise meta entre <head></head> de la page : <meta charset="utf-8" />

Je teste egalement tes autres suggestions.

+0 -0

C'est juste au niveau du mail ou ça a lieu avant en réalité ?

Quelle version de PHP ?

Quel est le charset en content-type de ton script ? (voir les entêtes HTTP, onglet réseau de la console ou outils de dév de ton navigateur)

htmlentities reçoit les données dans un autre jeu de caractères que celui qu'elle attend par défaut ? (PHP < 5.4.0 : ISO-8859-1 vs PHP >= 5.6.0 : défini par default_charset vs PHP [5.4.0;5.6.0[ : UTF-8)

HS :

  • il n'y a pas lieu d'utiliser stripslashes à moins d'être sur PHP < 5.4 avec les magic_quotes_gpc à on
  • tu n'utilises pas ta regexp (qui revient "en un sens" à réécrire filter_var + FILTER_VALIDATE_EMAIL), de ce fait, on pourrait t'injecter des données via $_POST['email']
+1 -0

htmlentities reçoit les données dans un autre jeu de caractères que celui qu'elle attend par défaut ? (PHP < 5.4.0 : ISO-8859-1 vs PHP >= 5.6.0 : défini par default_charset vs PHP [5.4.0;5.6.0[ : UTF-8)

vibrice

J ai enlevé htmlentities. Je les ai remplacé par htmlspecialchars et ca fonctionne :) :

1
2
3
$societe = (htmlspecialchars ($_POST['societe'], ENT_QUOTES));
$nom = (htmlspecialchars ($_POST['nom'], ENT_QUOTES));
$prenom = (htmlspecialchars ($_POST['prenom'], ENT_QUOTES));

Le code ci-dessus te parrait correct?

Il me reste ensuite à résoudre les autres erreurs que tu as mentionné.

+0 -0

Oui mais il m'est d'avis que tu n'as pas pour autant corrigé le problème, tu l'as juste caché sous le tapis : je pense que tu as PHP < 5.4 ou PHP > 5.6 avec un default_charset en ISO-8859-1 (questions auxquelles tu n'as pas répondu). Donc là le htmlspecialchars n'a pas vraiment conscience de travailler sur de l'UTF-8, croyant bosser sur de l'ISO-8859-1, il laisse juste passer [copier] bêtement les octets >= 128 (puisqu'il n'a pas besoin, contrairement à htmlentities, de toucher à/réécrire ceux-ci).

Pour en avoir le coeur net, il faudrait tenter un htmlentities avec 'UTF-8' en 3^e argument (ou envoyer des points de code Unicode invalides et/ou de l'UTF-8 mal encodé pour lesquels les deux fonctions sont censées renvoyer une chaîne vide).

Bien qu'il ne soit pas recommandé d'utiliser htmlentities avec de l'UTF-8, car tu réécris inutilement en entités HTML des caractères que tu sais pouvoir représenter, ça devait te permettre d'être certain (au moins pour les caractères latins ?) qu'ils soient reconnus. Sinon, tels quels, ça dépend du client (s'il détecte bien le jeu de caractères du mail, celui qu'il utilise par défaut, etc) et pour être tranquille/portable/etc à ce niveau il devrait être encodé tel que Gwend@l l'a +/- évoqué à moins de substituer mail par mb_send_mail qui s'en charge pour toi si tu lui fournis ce dont il a besoin pour le faire.

+1 -0

Euh, sûr, la dernière version de PHP 4.4 va dater de 8 ans ? Sérieusement, ils ont toujours ça chez OVH ? Tu ne serais pas en train de nous donner celle de phpMyAdmin ou je ne sais quoi ?

Il suffit de regarder un phpinfo sinon tout simplement de faire un echo phpversion();.

EDIT :

Il faut croire qu'ils le proposent :O

J'ai mis 5.6 maintenant

htmlentities/htmlspecialchars doivent maintenant correspondre à tes besoins sans avoir rien à faire de particulier.

+1 -0

Euh, sûr, la dernière version de PHP 4.4 va dater de 8 ans ? Sérieusement, ils ont toujours ça chez OVH ? Tu ne serais pas en train de nous donner celle de phpMyAdmin ou je ne sais quoi ?

Il suffit de regarder un phpinfo sinon tout simplement de faire un echo phpversion();.

EDIT :

J'ai mis 5.6 maintenant

Le defaut_charset devrait être en UTF-8 par défaut, donc htmlentities/htmlspecialchars, même sans expliciter ton jeu par leur troisième argument, doivent coller à tes besoins.

vibrice

Merci pour ton aide.

Alors la version precise a laquelle je fais reference est la Version PHP globale. Je l'ai trouvé en suivant les indications de la documentation d'OVH. Un petit triangle d'avertissement rouge etait affiché à coter du numero de version 4.4, m'incitant à changer de version.

Le site date en effet d'il y a plus de 8 ans. Je le refais completement.

+0 -0

Comme disait Gwend@al, le regex n'etant pas top, je vais voir ca de plus pres.

Y aurait-il un tuto quelque part que tu pourrais me recommander?

Vibrice: Malheureusement le Tuto PHP sur OCR, qui par ailleurs est vraiment tres bien fait, n'est pas tres fourni en ce qui concerne les formulaires et leur envoi par mail. Est ce que je risque une injection de script avec le code ci-dessous?

 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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<?php



            if(isset($_POST['submit']))
            {
                $regex_email = "#^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]{2,}\.[a-zA-Z]{2,4}$#";
                $email = (htmlspecialchars($_POST['email'], ENT_QUOTES));


                        $societe = (htmlspecialchars ($_POST['societe'], ENT_QUOTES));
                        $nom = (htmlspecialchars ($_POST['nom'], ENT_QUOTES));
                        $prenom = (htmlspecialchars ($_POST['prenom'], ENT_QUOTES));
                        $adresse = (htmlspecialchars ($_POST['adresse'], ENT_QUOTES)); 
                        $codepostal = (htmlspecialchars ($_POST['codepostal'], ENT_QUOTES)); 
                        $ville = (htmlspecialchars ($_POST['ville'], ENT_QUOTES)); 
                        $email = (htmlspecialchars ($_POST['email'], ENT_QUOTES)); 
                        $telephone = (htmlspecialchars ($_POST['telephone'], ENT_QUOTES));
                        //piscine
                        $couvertname = (htmlspecialchars ($_POST['couvertname'], ENT_QUOTES));
                        $largeur = (htmlspecialchars ($_POST['largeur'], ENT_QUOTES));
                        $longueur = (htmlspecialchars ($_POST['longueur'], ENT_QUOTES));
                        $hauteurhaut = (htmlspecialchars ($_POST['hauteurhaut'], ENT_QUOTES));
                        $hauteurbas = (htmlspecialchars ($_POST['hauteurbas'], ENT_QUOTES));
                        $materiau = (htmlspecialchars ($_POST['materiau'], ENT_QUOTES));
                        $longueur = (htmlspecialchars ($_POST['longueur'], ENT_QUOTES));
                        $datservice = (htmlspecialchars ($_POST['datservice'], ENT_QUOTES));
                        $autrestravaux = (htmlspecialchars ($_POST['autrestravaux'], ENT_QUOTES));
                        //message
                        $request = (htmlspecialchars ($_POST['request'], ENT_QUOTES));
                        $request = nl2br($request);
                        $headers  = 'MIME-Version: 1.0' . "\r\n";
                        $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
                        $headers .= 'From: <'.$email.'>' . "\r\n";


                        $subject = 'contact formulaire';
                        $date = date('j/n/Y');
                        $ip = $_SERVER['REMOTE_ADDR'];

                        $message='
                        <html>
                        <head>
                        </head>
                        <body>
                        <p>Le '.$date.' </p>
                        <div style="border: 1px solid black; padding: 4px; margin-bottom: 3px;">
                        <p>Société: '.$societe.'</p>
                        <p>Nom: '.$nom.' </p>
                        <p>Prénom: '.$prenom.' </p>
                        <p>Adresse: '.$adresse.' </p>
                        <p>Code postal: '.$codepostal.' </p>
                        <p>Ville: '.$ville.' </p>
                        <p>E-mail: '.$email.'</p>
                        <p>Téléphone: '.$telephone.' </p>
                        </div>
                        <div style="border: 1px solid grey; padding: 4px; margin-bottom: 3px;">
                        <p>Piscine couverte ? : '.$couvertname.' </p>
                        <p>Largeur: '.$largeur.' </p>
                        <p>Longueur: '.$longueur.' </p>
                        <p>Hauteur au + bas: '.$hauteurbas.' </p>
                        <p>Hauteur au + haut: '.$hauteurhaut.' </p>
                        <p>Materiau: '.$materiau.' </p>
                        <p>Longueur: '.$longueur.' </p>
                        <p>Mise en service: '.$datservice.' </p>
                        <p>Autres travaux: '.$autrestravaux.' </p>
                        </div>
                        <div style="border: 1px solid black; padding: 4px;">
                        <p>'.$request.' </p>
                        </div>
                        <p>IP: '.$ip.'</p>
                        </body>
                        </html>
                        ';

                        $to = '***@o***e.fr';
                        mail($to, $subject, $message, $headers);
                        $to2 = '****@g****.com'; 
                        mail($to2, $subject, $message, $headers);

                        if (isset($_POST['submit']))
                        {

                            echo '<div class="mailok">Votre demande a bien été envoyée<br />Nous vous contacterons dans les meilleurs délais par e-mail ou téléphone.<br />Merci pour l\'intéret que vous portez à notre travail.</div>';
                        }
            }       

         else
         {
                ?>
+0 -0

Est ce que je risque une injection de script avec le code ci-dessous?

Agir sur le mail, oui puisqu'il n'y a toujours aucune vérification du format de $email/$_POST['email']. Si je ne dis pas de bêtise (jamais testé non plus à vrai dire), pour illustrer bêtement, en entrant dans ton champ : toto>\r\nCC: <me@domain.tld (en recodant le \r\n bien sûr) je me retrouve avec une copie du mail. Mais ça peut être bien moins innocent que s'envoyer une copie surtout si on modifie (injecte pour être précis) de la même manière le corps du message (deux (\r)\n et on passe des entêtes au corps).

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte