Quand des pirates visent un formulaire, ils ne le remplissent pas normalement. Ils envoient du code conçu pour s'introduire dans vos systèmes ou voler des données. Ils peuvent soumettre du JavaScript qui s'exécute dans le navigateur de vos visiteurs, des commandes SQL pour casser votre base de données, ou du contenu malveillant pour causer des dégâts. La validation et la désinfection des saisies sont les défenses qui arrêtent ces attaques.
Ce que vous allez apprendre : ce que sont la validation et la désinfection des saisies, en quoi elles diffèrent, comment fonctionnent les attaques par injection, quelles protections conviennent à chaque type de donnée et comment les mettre en place sur vos formulaires.
Qu'est-ce que la validation des saisies ?
La validation des saisies consiste à vérifier que les données envoyées par votre formulaire ont le format attendu et respectent vos exigences. C'est la première ligne de défense contre les saisies malveillantes.
La validation répond à des questions comme : s'agit-il d'une adresse e-mail ou d'un texte quelconque, d'un nombre ou d'un mot, ce champ est-il vide alors qu'il ne devrait pas l'être, et le visiteur a-t-il saisi quelque chose de cohérent pour ce champ ou quelque chose de suspect.
Exemples de ce que la validation vérifie :
- Un champ e-mail doit contenir un @ et un domaine
- Un champ de numéro de téléphone ne doit contenir que des chiffres et des tirets
- Un champ numérique ne doit pas contenir de lettres
- Un champ obligatoire ne doit pas être vide
- Un champ de mot de passe doit respecter une longueur minimale
La validation se fait à deux endroits. Sur l'appareil du visiteur, on parle de validation côté client. Sur votre serveur, on parle de validation côté serveur. La validation côté client donne un retour immédiat en cas d'erreur. La validation côté serveur est celle qui protège réellement contre les attaques, car un pirate peut contourner les contrôles côté client.
Qu'est-ce que la désinfection des saisies ?
La désinfection (sanitization) consiste à retirer ou neutraliser tout élément dangereux d'une saisie avant de la stocker ou de la traiter. Même si une donnée passe la validation, elle peut contenir du code ou des caractères destinés à nuire.
Exemples de ce que fait la désinfection :
- Elle retire les balises HTML comme `<script>` et `<img>` des champs de texte
- Elle retire les caractères spéciaux SQL qui pourraient servir à s'introduire dans une base de données
- Elle échappe les caractères spéciaux pour qu'ils soient traités comme du texte et non comme du code
- Elle limite la longueur de la saisie pour éviter les attaques par dépassement de mémoire tampon
La validation et la désinfection fonctionnent ensemble, mais n'ont pas le même rôle. La validation vérifie que la donnée a le bon format. La désinfection retire tout ce qui est dangereux, même si le format est techniquement correct.
Comment fonctionnent les attaques par injection
Injection SQL
Une injection SQL se produit quand un pirate place du code SQL dans un champ de formulaire. Si le code de votre formulaire ne désinfecte pas cette saisie, le code SQL est exécuté sur votre base de données.
Exemple : un formulaire de connexion demande une adresse e-mail. Au lieu de saisir son e-mail, le pirate envoie :
' OR '1'='1 Si votre formulaire ne désinfecte pas cette saisie, votre code peut exécuter une requête SQL de ce genre :
SELECT * FROM users WHERE email = '' OR '1'='1' La partie `OR '1'='1'` rend la condition toujours vraie : la requête renvoie alors tous les utilisateurs au lieu d'un seul. Le pirate a contourné le système de connexion.
Cross-Site Scripting (XSS)
Une attaque XSS se produit quand un pirate envoie du code JavaScript dans un champ de formulaire. Si le formulaire ne désinfecte pas ce code et le stocke, le JavaScript s'exécute dans le navigateur de toute personne qui consulte ensuite ces données.
Exemple : un formulaire de commentaires accepte les messages des visiteurs. Un pirate envoie :
<script>alert('hacked')</script> Si ce code n'est pas désinfecté et qu'il est stocké dans la base de données, le JavaScript s'exécute et affiche une alerte dès que quelqu'un ouvre la section des commentaires. Une version plus dangereuse pourrait voler des cookies, rediriger les visiteurs vers une page de phishing ou extraire des données de formulaire.
Injection de commandes
Si les données de votre formulaire sont utilisées dans des commandes système (ce qui arrive dans certains systèmes en arrière-plan), un pirate peut y injecter des commandes du système d'exploitation.
Exemple : un champ de formulaire est utilisé dans une commande comme :
ffmpeg -i $filename output.mp4 Si `$filename` n'est pas désinfecté et qu'un pirate envoie `;rm -rf /`, la commande devient :
ffmpeg -i ;rm -rf / output.mp4 La commande `rm -rf /` s'exécute et supprime des fichiers du système. C'est pourquoi une commande système ne doit jamais recevoir de saisie non désinfectée.
Validation et désinfection selon le type de donnée
Adresses e-mail
Validation : vérifiez que la saisie correspond à un format d'e-mail (du type texte@domaine.extension). Confirmez qu'elle ne contient que des caractères autorisés.
Désinfection : retirez les balises HTML et les caractères spéciaux. Gardez uniquement les caractères alphanumériques, les points, les tirets et le @.
Numéros de téléphone
Validation : vérifiez qu'il ne contient que des chiffres, des tirets, des parenthèses et des espaces. Contrôlez que la longueur correspond au pays attendu.
Désinfection : retirez tous les caractères non numériques, sauf les tirets et les parenthèses. Supprimez les zéros ou espaces en début de saisie si nécessaire.
Champs de texte (commentaires, noms, adresses)
Validation : vérifiez que le champ n'est pas vide et que sa longueur est raisonnable (pas des millions de caractères).
Désinfection : retirez ou échappez les balises HTML, le JavaScript et les caractères spéciaux SQL. Gardez uniquement du texte brut et la ponctuation de base.
Nombres et montants
Validation : vérifiez que la saisie est un nombre. Pour un prix ou une quantité, vérifiez qu'il est positif.
Désinfection : retirez tous les caractères non numériques. Si besoin, arrondissez au bon nombre de décimales.
Mots de passe
Validation : vérifiez la longueur minimale (au moins 8 caractères) et, si vous le souhaitez, exigez un mélange de majuscules, de minuscules, de chiffres et de symboles.
Désinfection : ne retirez et ne modifiez rien dans un mot de passe. Il doit être conservé tel quel (haché, jamais en clair). Si vous retirez des caractères, les utilisateurs ne pourront plus se connecter.
Envois de fichiers
Validation : vérifiez que le type de fichier est celui que vous attendez (par exemple uniquement des PDF, uniquement des images). Vérifiez que la taille n'est pas trop grande.
Désinfection : renommez le fichier pour que les pirates ne puissent pas exploiter des noms spéciaux. Analysez le fichier à la recherche de logiciels malveillants. Stockez-le en dehors de la racine web pour qu'il ne puisse pas être exécuté comme du code.
Comment mettre en place la validation et la désinfection
Côté client (dans le navigateur)
Utilisez les attributs de validation HTML5 pour donner un retour immédiat aux visiteurs :
<input type="email" name="email" required> <input type="tel" name="phone" pattern="[0-9]{10}"> <input type="number" name="age" min="0" max="120"> Cela repère les erreurs évidentes et améliore l'expérience. Mais la validation côté client peut être contournée : ce n'est donc pas une mesure de sécurité à elle seule.
Côté serveur (sur votre serveur)
C'est ici que la sécurité se joue. Le code de votre serveur doit valider et désinfecter chaque donnée :
// Pseudo-code example if (email does not match email pattern) { reject the submission } // Remove HTML tags sanitized_comment = remove_html_tags(comment_text) // Escape special characters for database safe_name = escape_sql_characters(user_name) // Only then store the data store_in_database(safe_name, sanitized_comment) Utilisez des requêtes paramétrées pour les bases de données
La meilleure défense contre l'injection SQL, ce sont les requêtes paramétrées (aussi appelées requêtes préparées). Au lieu de placer la saisie directement dans la requête SQL, vous utilisez des espaces réservés et vous transmettez les données séparément :
// Bad (vulnerable): query = "SELECT * FROM users WHERE email = '" + email + "'" // Good (safe): query = "SELECT * FROM users WHERE email = ?" execute(query, [email]) Avec des requêtes paramétrées, l'analyseur SQL sait que la saisie est une donnée et non du code. Même si un pirate envoie du code SQL, il est traité comme du texte brut.
Utilisez des bibliothèques et des frameworks
N'écrivez pas votre code de désinfection de zéro. Utilisez des bibliothèques établies, conçues pour cela. En PHP, utilisez htmlspecialchars() ou une bibliothèque comme HTML Purifier. En Python, utilisez le module `html` ou une bibliothèque comme bleach. Dans Node.js, utilisez `express-validator` ou un outil similaire. Ces bibliothèques ont été testées et sont mises à jour pour faire face aux nouveaux types d'attaques.
Erreurs courantes de validation et de désinfection
Valider uniquement côté client. La validation côté client sert à l'expérience utilisateur, pas à la sécurité. Un pirate peut la contourner. Vous devez aussi valider côté serveur.
Interdire les caractères dangereux au lieu d'autoriser les caractères sûrs. Si vous essayez de bloquer l'injection SQL en retirant les points-virgules et les guillemets, les pirates trouveront un moyen de passer. Autorisez plutôt les caractères attendus (pour un numéro de téléphone, uniquement les chiffres et les tirets) et rejetez tout le reste.
Faire confiance au type de donnée du champ. Si vous avez un champ numérique, le navigateur envoie un texte qui ressemble à un nombre. Votre serveur doit quand même vérifier que c'est bien un nombre avant de l'utiliser. Ne supposez jamais que le type de donnée est correct.
Oublier de désinfecter les données affichées. Même si les données sont stockées en toute sécurité, si vous les affichez sur une page web sans échapper le HTML, un pirate peut injecter du code qui s'exécute dans le navigateur des visiteurs.
Désinfecter dans le mauvais ordre. Validez d'abord (le format est-il le bon ?), puis désinfectez (est-ce sûr ?). Si vous désinfectez avant de valider, vous risquez de rejeter des données qui étaient en réalité sûres.
Ce que fait WEMASY pour la validation des saisies
WEMASY valide automatiquement les champs de formulaire selon le type de champ que vous choisissez. Les champs e-mail sont vérifiés pour le format d'une adresse valide. Les champs numériques sont vérifiés pour une saisie numérique. Les champs obligatoires sont vérifiés avant l'envoi. Côté serveur, WEMASY désinfecte toutes les saisies pour retirer le HTML, le JavaScript et tout autre code dangereux avant de stocker les réponses. Vous choisissez les champs à collecter, et WEMASY s'occupe de la validation et de la désinfection en arrière-plan.
Consultez les fonctionnalités de formulaire incluses dans votre offre sur la page des tarifs.