TD04 : filter_var et filtrage des données des formulaires en PHP
Lorsque nous utilisons des formulaires sur une page web, leur traitement en PHP doit assurer la sécurité de leur contenu. Dans cette séance, on va essayer de comprendre ce qui peut mal se passer lors du traitement des informations par le code PHP.
1) Sécurité des champs d'un formulaire de connexion :
On donne le formulaire de connexion "form1.php" suivant :
Dans ce formulaire, on demande à l'utilisateur de définir une adresse e-mail et un mot de passe pour sa connexion. Le champ "e-mail" est de type "text", le champ "mdp" est de type "password".
On donne le fichier de traitement "t1.php" :
Dans ce fichier de traitement, on regarde si les deux champs ont bien été remplis correctement. S'il en manque un des deux, on retourne à la page du formulaire. Si les deux champs sont remplis, on affiche leur contenu (d'ailleurs en passant, ce n'est pas bien d'afficher le contenu d'un mot de passe...).
Envoyez ces deux fichiers sur votre VPS dans le dossier "public_html/travaux/sae203/td06/". Testez le code en entrant un e-mail "normal" et un mot de passe "bidon" : "toto1234" par exemple. Que se passe-t-il au niveau de l'affichage par la page de traitement (y a-t-il un problème) ?
Maintenant sur votre navigateur, retournez sur la page du formulaire et entrez :
toto@toto.to<script>alert('script 1');</script>
dans le champ "e-mail" ettoto1234<script>alert('script 2');</script>
dans le champ "mdp". Validez votre formulaire, que se passe-t-il sur la page de traitement ?
Il y a donc possibilité d'injecter du code Javascript dans un champ de type "text" dans un formulaire (c'est de l'injection de code XSS). Cela donne un problème de sécurité, n'importe qui peut envoyer des scripts dans vos champs de formulaire. Ici, c'est juste un affichage mais on pourrait injecter un script qui redirige vers une autre page...
Il faut donc, pour n'importe quelle donnée, respecter les trois étapes suivantes :
Sanitize input (assainir les entrées)
Validate data (valider les données)
Escape output (échapper les sorties)
Dans notre cas, le champ qui pose problème est le champ "email" car le champ "mdp" n'a pas besoin d'être affiché (et ne doit jamais l'être sur un site), même sa version cryptée ! Mettez en commentaire la ligne //echo '<p>'.$_POST['mdp'].'</p>'."\n";
dans votre page de traitement "t1.php".
Modifiez votre code pour "assainir", "valider" et "échapper" le champ email. Envoyez votre nouveau code sur votre VPS, testez ce qui se passe avec
"toto@toto.to<script>alert('script 1');</script>"
dans le champ "e-mail" et"toto1234<script>alert('script 2');</script>"
dans le champ mot de passe. Normalement, votre code n'affichera plus les fenêtres pop-up "alert()".
Pour éviter ce genre de problème, vous pouvez passer le champ "email" du type "text" au type "email" qui existe en HTML.
2) Sécurité des champs d'un formulaire de renseignement :
On donne le code du formulaire "form2.php" ici :
On donne le fichier de traitement "t2.php" :
Envoyez ces deux fichiers sur votre VPS dans le dossier "public_html/travaux/sae203/td06/". Testez le code en entrant
Robert<script>alert('Prénom pas sûr !')</script>
et20<script>alert('Âge pas sûr non plus !')</script>
. Que se passe-t-il au niveau de l'affichage par la page de traitement (y a-t-il un problème) ?Appliquez l'assainissement, la validation et l'échappement dans le fichier de traitement "t2.php". Testez votre code avec
Robert<script>alert('Prénom pas sûr !')</script>
et20<script>alert('Âge pas sûr non plus !')</script>
jusqu'à ce qu'il n'y ait plus de problème d'injection de code Javascript dans vos champs de formulaire.En résumé, pour garantir un premier niveau de sécurité, il faut mettre les types qui correspondent aux champs dans les champs de formulaire :
<input type= "email">
pour un e-mail, "number" pour un nombre, "date" pour une date... Tout mettre en<input type="text" ...>
n'est pas une bonne idée !
On aurait pu aussi démarrer les sessions sur les pages de notre site et choisir, au lieu d'afficher des erreurs au niveau de la page de traitement, de les passer en session à la page du formulaire pour prévenir l'utilisateur qu'un champ n'est pas correctement rempli dans le formulaire (on l'a déjà fait en S1 en SAE105...).
3) Sécurité de votre formulaire de recherche SAE203 :
Afin de vérifier si vous avez bien compris la sécurisation de vos données de champs de formulaire, modifiez le code de votre formulaire de recherche et de votre page de traitement "reponse_recherche.php".
Testez votre code en mettant un script dans le champ de recherche par nom/prénom d'un auteur, par exemple Albert Uderzo<script>alert('Danger !!!')</script>
. Si votre protection fonctionne bien, vous ne devez pas voir la fenêtre pop-up qui affiche "Danger !!!" apparaître lors du traitement de votre formulaire.
4) Pour aller plus loin :
Quelques liens à lire pour comprendre un peu mieux les enjeux de la sécurité de vos pages web de traitement de formulaires avec PHP :
Dernière mise à jour