La sécurité des formulaires en PHP
Une chose primordiale lorsqu’on se lance dans le développement web. On est souvent amener à en créer pour diverses raisons que ce soit sur une application ou un site web. La sécurité d’un formulaire est d’autant plus importante surtout lorsque celui-ci est accessible au public pour des utilisateurs lambda. Malheureusement dans les utilisateurs lambda, il y a des utilisateurs malveillants et vous devez absolument sécuriser vos formulaires.
La sécurité dans le traitement PHP est obligatoire
C’est la partie sécurité obligatoire et la plus importante de toute. Bien souvent, un jeune développeur prendra l’habitude de sécuriser son formulaire au niveau JavaScript (client) et négligera la partie PHP (serveur). Rappelez-vous bien que le dernier traitement de votre formulaire c’est le PHP qui le fera et non le JavaScript. Le JavaScript ne sert qu’à améliorer l’ergonomie des utilisateurs et l’intuitivité de vos formulaires. Vous devez absolument privilégier cette partie et ne jamais la négliger.
Pour savoir comment sécuriser un formulaire, il faut d’abord connaître les failles de sécurité et comment les exploiter bien évidemment, ce qui n’est pas toujours évident de les connaître quand on est débutant.
La faille XSS
La faille XSS, aussi appelé « Cross-Site Scripting », permet d’injecter du code directement dans une page par l’URL, en POST, en GET et bien évidemment par l’intermédiaire d’un formulaire. Le plus souvent, cette faille est utilisée dans l’optique de capturée les cookies d’identification des utilisateurs sur un site Internet. Les failles de ce type, qui se cachent souvent dans les actions les plus simples, ne doivent surtout pas être négligées.
Imaginons que nous avons un formulaire de connexion très simple :
<form method="post" action="connexion.php"> <input type="text" name="pseudo" /> <input type="password" name="password" /> <input type="submit" value="Connexion" /> </form>
Et que ce formulaire affiche sur la page de connexion ceux-ci :
<?php echo "Ravi de vous revoir ".$_POST['pseudo']." !" ?>
Si votre formulaire n’est pas sécurisé pour afficher les données soumises par l’utilisateur, alors rien n’empêche personne de mettre de ce qu’il veut dans vos champs. Comme par exemple ceux-ci :
<script>alert('C\'est une faille XSS qu\'on a là')</script>
Et ce script s’éxecutera dans votre navigateur. Testez ici.
Je vous laisse imaginer ce qu’il est alors possible de faire dans ce genre de cas. Un simple strip_tags permet de pallier à ce problème :
<?php echo "Ravi de vous revoir ".strip_tags($_POST['pseudo'])." !" ?>
L’injection SQL
J’ai effectué un article à ce sujet que vous trouverez ici. Les injections SQL n’auront plus de secret pour vous. Il est très important dans vos développements de faire vos requêtes SQL en des requêtes préparées via PDO en PHP. Ce système de requête préparée est très puissant puisqu’il se charge de faire le nettoyage contre les injections SQL à votre place. Vous serez donc obligé de passer en orientée objet puisque PDO est un objet.
cURL
Un bon moyen de se rendre compte que la sécurité côté traitement (PHP) est la plus importante que côté client (JavaScript) c’est de comprendre et maîtriser le cURL. cURL est une librairie permettant de faire des requêtes URL aux client tout cela en ligne de commande. C’est un mécanisme très puissant puisque cela vous permet de récupérer le contenu d’une page web, d’envoyer des fichiers, de s’authentifier et donc bien évidemment de soumettre des données dans un formulaire HTML. En effet, il est tout à fait possible de soumettre un formulaire sans y accéder par un navigateur où plutôt soumettre des données sur l’action du formulaire. Cela s’applique également pour les formulaires en Ajax qui contiennent une URL.
cURL peut être utilisé dans des objectifs sains comme l’utilisation d’API REST ou bien de façon néfaste comme pirater un site Internet en contournant les sécurités mis en place côté client.
Si on reprend le formulaire précédent et qu’on veut le soumettre en cURL, voilà le code à produire :
$lien = 'http://www.deviotyourself.com/exemples/securiser-vos-formulaires/xss/connexion.php'; $postfields = array( 'pseudo' => 'test', 'password' => 'test', ); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $lien); curl_setopt($curl, CURLOPT_COOKIESESSION, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields); $return = curl_exec($curl); curl_close($curl); echo 'Retour cURL : '.$return;
Testez ici.
Ce script est l’équivalent de se rendre sur le formulaire, de remplir ses champs et le soumettre pour arriver au même résultat. Il est alors possible de pouvoir créer des scripts pour se connecter via des identifiants sur un site Internet et ainsi de récupérer son contenu par exemple. Vous avez peut être également remarqué, j’ai soumis les données sur la page de traitement contournant ainsi toute la sécurité client que j’aurais pu mettre sur le formulaire. Cela veut aussi dire qu’on peut soumettre le formulaire autant de fois que l’on veut avec un tel script en y ajoutant une boucle et il serait alors judicieux de le protéger avec un captcha par exemple.
Conclusion
Le but de l’article était de vous montrer que la sécurité de vos formulaires web n’est pas à prendre à la légère puisqu’il est très facile de contourner la sécurité d’un formulaire côté client.
9 commentaires
Meegolo
Bonjour,
J’ai une question, est-il possible de sécurisé un formulaire d’une page html.
Mon formulaire de contact ne stock pas dans une bd mais envoie uniquement des mails.
Merci
Gaëtan
Bonjour Meegolo,
Oui il est possible de les sécuriser un minimum avec certains attributs HTML et un peu de JavaScript.
Bien à toi,
klein
Bonjour, j’ai lu tes avis et tu m’a l’air très compétent, je suis novice et j’ai tant bien que mal crée mon site internet qui fonctionne, pas contre mon formulaire est obsolète. Es ce que tu pourrais me fournir un formulaire sécurisé et la pratique pour le mettre en place.
Je te remercie par avance
Gaëtan
Bonjour Klein,
Je t’invite à me contacter par e-mail pour en discuter et t’aider au mieux sur ton problème.
J’imagine que c’est pour ton site Internet cheminees inserts n’est-ce pas ?
Bien à toi,
Luis
Bonjour Gaëtan,
Le lien vers l’article sur l’injection SQL renvoie en fait sur le formulaire exemple de la faille XSS. Et je ne trouve pas très compréhensible quand vous écrivez par exemple : [crayon-5bf4f6193fd6c248679964/]
Cordialement,
Luis
Gaëtan
Bonjour Luis,
Un grand merci pour m’avoir communiqué ces différentes remarques :-).
J’ai fait le nécessaire et corriger tout ce qui n’allait pas.
Je pense que ce sera un peu plus clair pour toi.
Bien à toi,
Robert Carpentier
Voici le détail de mon Formulaire sur la page logiciel (Magix Web):
body,td,th {
color:#ffffff;
}
function verifSelection() {if (mail_form.champ1.value == « ») {
alert(« Votre Nom est requis »)
return false
} if (mail_form.champ2.value == « ») {
alert(« Votre Téléphone est requis »)
return false
} if (mail_form.champ3.value == « ») {
alert(« La date du spectacle est requise »)
return false
} if (mail_form.champ4.value == « ») {
alert(« Le lieu du spectacle est requis »)
return false
} if (mail_form.champ5.value == « ») {
alert(« Le code postal est requis »)
return false
} if (mail_form.champ6.value == « ») {
alert(« Nbre de spectateurs est requis »)
return false
} if (mail_form.champ7.value == « ») {
alert(« avec ou sans (Sono et Eclairages est requis »)
return false
} if (mail_form.zone_email.value == « ») {
alert(« Votre mail est requis »)
return false
}
invalidChars = » /:,;' »
for (i=0; i -1) {
alert(« Votre adresse e-mail contient des caractères invalides. Veuillez vérifier. »)
mail_form.zone_email.focus()
return false
}
}
atPos = mail_form.zone_email.value.indexOf(« @ »,1) // there must be one « @ » symbol
if (atPos == -1) {
alert(‘Votre adresse e-mail ne contient pas le signe « @ ». Veuillez vérifier.’)
mail_form.zone_email.focus()
return false
}
if (mail_form.zone_email.value.indexOf(« @ »,atPos+1) != -1) { // and only one « @ » symbol
alert(‘Il ne doit y avoir qu\’un signe « @ ». Veuillez vérifier.’)
mail_form.zone_email.focus()
return false
}
periodPos = mail_form.zone_email.value.indexOf(« . »,atPos)
if (periodPos == -1) { // and at least one « . » after the « @ »
alert(‘Vous avez oublié le point « . » après le signe « @ ». Veuillez vérifier.’)
mail_form.zone_email.focus()
return false
}
if (periodPos+3 > mail_form.zone_email.value.length) { // must be at least 2 characters after the
alert(‘Il doit y avoir au moins deux caractères après le signe « . ». Veuillez vérifier.’)
mail_form.zone_email.focus()
return false
}} // Fin de la fonction
Nom
Téléphone
Date du spectacle
Lieu du spectacle
Code Postal
Nbre de spectateurs
Sonorisation Eclairages
avec
sans
Email
Objet
Robert Carpentier
Bonjour Gaëtan
Voici mon problème sur mon formulaire de contact il y a des déconneurs qui mettent m’importe quoi dans les champs (Nom, Email etc) je vous le sécurise ou s’avoir qui fait ca
Merci de ton aide
Cordialement Robert
zable
pour éviter que n’importe qui envois n’importe quoi dans les formulaire il y a preg_match() c’est asse chiant a mettre en place mais ça oblige a respecter un paterne d’écriture.
comme par exemple le nombre de caractère limiter ou obligatoire, l’obligation d’avoirs un @, ou autoriser uniquement les chiffre etc etc.
ça n’oblige pas les gents a dire la vérité mais ça évite qu’une personne copie colle dans votre formulaire de contact la trilogie du seigneur des anneaux