La validation des entrées consiste à vérifier, filtrer et nettoyer systématiquement toute donnée provenant de l’extérieur d’un système (utilisateur, API, fichier, capteur, formulaire, etc.) avant de l’utiliser — notamment pour éviter les attaques comme les injections SQL, le XSS (Cross-Site Scripting) ou l’exécution de code malveillant.
C’est l’une des premières lignes de défense d’un système sécurisé un pilier de la sécurité dès la conception (Security by Design).
Pourquoi c’est critique ?
Les attaquants exploitent souvent les hypothèses implicites des développeurs :
- « L’utilisateur va taper un email normal. »
- « Ce champ ne contiendra que des chiffres. »
- « Personne n’enverra du code JavaScript ici. »
Mais rien n’empêche un utilisateur (ou un bot) d’envoyer :
<script>volerCookies()</script>
ou
'; DROP TABLE users; --
Sans validation, ces chaînes peuvent être exécutées comme du code → compromission totale.
Bonnes pratiques de validation des entrées
| Principe | Explication | Exemple |
|---|---|---|
| Valider par liste blanche | Autoriser uniquement ce qui est attendu, pas tenter de bloquer ce qui est « dangereux » | Pour un champ « pays », n’accepter que les codes ISO 3166 (FR, DE, etc.) |
| Vérifier le type et le format | Un âge doit être un entier entre 0 et 120 ; un email doit correspondre à une regex valide | Utiliser des validateurs natifs (ex. : HTML5 type="email", mais aussi côté serveur !) |
| Limiter la longueur | Éviter les attaques par déni de service ou les dépassements de tampon | Nom de famille ≤ 100 caractères |
| Sanitization (assainissement) | Supprimer ou échapper les caractères spéciaux dangereux | Transformer < en < pour empêcher le XSS |
| Valider côté serveur (toujours) | La validation client (JavaScript) peut être contournée | Même si le navigateur bloque un champ vide, le serveur doit refuser la requête si elle arrive quand même |
Règle d’or :
Toute donnée venant de l’extérieur = donnée potentiellement hostile.
Même si elle vient d’un “utilisateur de confiance” ou d’un système interne.
Validation des entrées – Exemples concrets par stack
| Stack / Contexte | Où valider ? | Comment valider ? | Exemple concret |
|---|---|---|---|
| WordPress (PHP) | Côté serveur, dans le thème/plugin | Utiliser les fonctions de sanitization natives de WordPress | php$email = sanitize_email($_POST['email']);if (!is_email($email)) {< wp_die('Email invalide');} |
| Symfony (PHP) | Dans les contrôleurs ou via les Form Types | Validation avec annotations ou objets Validator | phpuse Symfony\Component\Validator\Constraints as Assert;class ContactData {#[Assert\Email] public string $email;} |
| React (frontend) | Jamais seul – uniquement pour UX | Vérification côté client (regex, librairies) → mais toujours doubler côté serveur | jsxconst isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); |
| Next.js (API Routes) | Dans les routes API (/pages/api/...) | Valider avec zod, joi, ou manuellement | ts// pages/api/contact.tsimport { z } from 'zod';const schema = z.object({ email: z.string().email() });export default function handler(req, res) { const result = schema.safeParse(req.body);if (!result.success) return res.status(400).json({ error: 'Données invalides' });} |
| Express.js (Node.js) | Dans les middlewares ou contrôleurs | Utiliser express-validator ou joi | jsconst { body, validationResult } = require('express-validator');app.post('/contact', body('email').isEmail(), (req, res) => {<br> const errors = validationResult(req); if (!errors.isEmpty()) return res.status(400).json({ errors: errors.array() });}); |
Principes transversaux à retenir
- La validation frontend (React, Next.js) sert uniquement l’expérience utilisateur
→ Elle peut être contournée. Toujours valider côté serveur. - WordPress fournit des outils robustes (
sanitize_*,is_*,wp_kses)
→ À utiliser systématiquement, même dans des plugins internes. - Les frameworks modernes (Symfony, Express, Next.js) disposent de validateurs dédiés
→ Privilégier les bibliothèques éprouvées (zod,joi,express-validator, composants Symfony Validator). - Ne jamais insérer directement une entrée utilisateur dans :
- Une requête SQL → utiliser des requêtes préparées
- Un template HTML → échapper le contenu (
htmlspecialchars,dangerouslySetInnerHTMLinterdit sans nettoyage) - Une commande système → éviter
exec()avec entrées non fiables
Erreurs fréquentes à éviter
| Erreur | Conséquence |
|---|---|
Se fier uniquement à la validation HTML5 (<input type="email">) | Contournable en 10 secondes avec DevTools |
| Nettoyer les données après les avoir utilisées | Trop tard : l’attaque a déjà eu lieu |
| Valider uniquement la présence, pas le format | Un champ « âge » rempli avec "><script> passe si on ne vérifie pas le type |
Utiliser strip_tags() comme seule défense contre le XSS | Insuffisant : il existe des vecteurs sans balises (javascript: dans href, etc.) |