Sécuriser les paramètres des formulaires
Publié le 15/01/2026 par Frédéric dans la catégorie "Php"
Des formulaires PHP non sécurisés ? Voici comment valider et filtrer toutes les entrées utilisateur avec les fonctions natives de PHP – sans se prendre la tête.
Prompt pour l'IA
Avertissement : Ce prompt est proposé pour vous permettre d'appliquer cet article à votre code. Surtout, ne faites pas confiance aveuglément à votre Agent favori. Et surtout, comprenez ce que vous faites.
Analyse ce code PHP et vérifie que :
- Toutes les entrées utilisateur (
$_GET,$_POST,$_COOKIE,$_FILES) sont validées avant utilisation - Les données sont filtrées avec
filter_input()oufilter_var() - Aucune entrée n'est utilisée directement sans validation
- Les sanitizations sont appliquées avant affichage ou stockage Propose des corrections si nécessaire, en privilégiant les fonctions natives de PHP.
Explication détaillée
🔍 POURQUOI VALIDER SES ENTREES ?
Un formulaire non sécurisé, c’est comme laisser la porte de votre maison grande ouverte :
- Injections SQL (quelqu’un peut voler ou modifier vos données)
- XSS (du code malveillant peut s’exécuter dans le navigateur de vos utilisateurs)
- Uploads de fichiers dangereux (un pirate peut prendre le contrôle de votre serveur)
La solution ? Valider et filtrer systématiquement toutes les données avant de les utiliser.
🛠️ LES OUTILS NATIFS DE PHP : filter_input() ET filter_var()
1. filter_input() – Pour valider directement depuis $_GET, $_POST, etc.
// Exemple : Valider un email envoyé en POST
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
die("Cet email n'est pas valide.");
}
// Si on arrive ici, $email est valide et sécurisé
2. filter_var() – Pour valider une variable existante
// Exemple : Valider un âge (doit être un entier entre 18 et 120)
$age = filter_var($age, FILTER_VALIDATE_INT, [
'options' => [
'min_range' => 18,
'max_range' => 120
]
]);
if ($age === false) {
die("Âge invalide.");
}
📋 VALIDATION PAR TYPE DE DONNEE – EXEMPLES CONCRETS
✉️ Valider un email
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if (!$email) {
$errors[] = "L'email n'est pas valide.";
}
🔢 Valider un nombre entier
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if (!$id) {
$errors[] = "L'ID doit être un nombre entier.";
}
🌐 Valider une URL
$website = filter_input(INPUT_POST, 'website', FILTER_VALIDATE_URL);
if (!$website) {
$errors[] = "L'URL n'est pas valide.";
}
📝 Nettoyer du texte pour éviter le XSS
$comment = filter_input(INPUT_POST, 'comment', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
// Maintenant, $comment peut être affiché en HTML sans risque
echo "<p>$comment</p>";
📁 SÉCURISER LES UPLOADS DE FICHIERS
Ne faites jamais confiance à l’extension du fichier ! Vérifiez toujours :
- Le type MIME réel (pas seulement l’extension)
- La taille maximale
- Le contenu (pour les images, vérifiez les dimensions)
$allowed_types = ['image/jpeg', 'image/png'];
$max_size = 2 * 1024 * 1024; // 2 Mo
if ($_FILES['avatar']['error'] !== UPLOAD_ERR_OK) {
die("Erreur lors de l'upload.");
}
$file_type = mime_content_type($_FILES['avatar']['tmp_name']);
$file_size = $_FILES['avatar']['size'];
if (!in_array($file_type, $allowed_types)) {
die("Seuls les fichiers JPEG et PNG sont autorisés.");
}
if ($file_size > $max_size) {
die("Le fichier est trop volumineux (max. 2 Mo).");
}
⚠️ ERREURS À ÉVITER ABSOLUMENT
❌ Erreur 1 : Utiliser les données directement sans validation
// ❌ DANGER : Utilisation directe de $_POST
$email = $_POST['email']; // NON SÉCURISÉ !
❌ Erreur 2 : Se fier à isset() ou empty() seul
// ❌ INSUFFISANT : Vérifie seulement si le champ existe, pas son contenu
if (isset($_POST['email'])) {
$email = $_POST['email']; // Toujours dangereux !
}
❌ Erreur 3 : Utiliser des fonctions obsolètes
// ❌ À BANNIR : Ces fonctions ne protègent pas assez
$safe = addslashes($_POST['data']); // Inutile avec les requêtes préparées
$safe = mysql_real_escape_string($_POST['data']); // MySQL est obsolète !
🔧 EXEMPLE COMPLET : FORMULAIRE D’INSCRIPTION SÉCURISÉ
<?php
// 1. Initialisation des erreurs
$errors = [];
// 2. Validation des entrées
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 13]
]);
$password = filter_input(INPUT_POST, 'password', FILTER_DEFAULT);
// 3. Vérifications supplémentaires
if (!$username || strlen($username) < 3) {
$errors[] = "Le nom d'utilisateur doit faire au moins 3 caractères.";
}
if (!$email) {
$errors[] = "L'email n'est pas valide.";
}
if (!$age) {
$errors[] = "L'âge doit être un nombre valide (minimum 13 ans).";
}
if (strlen($password) < 8) {
$errors[] = "Le mot de passe doit faire au moins 8 caractères.";
}
// 4. Si tout est valide, traiter les données
if (empty($errors)) {
// Hasher le mot de passe (À FAIRE ABSOLUMENT !)
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
// Ici, enregistrez en base de données (avec PDO ou MySQLi)
// ...
echo "Inscription réussie !";
} else {
// Afficher les erreurs
foreach ($errors as $error) {
echo "<p style='color: red;'>⚠️ $error</p>";
}
}
?>
💡 BONNES PRATIQUES SUPPLÉMENTAIRES
✔ Utilisez toujours des requêtes préparées pour les bases de données (PDO ou MySQLi)
✔ Hashes les mots de passe avec password_hash()
✔ Limitez les tentatives de soumission pour éviter le bruteforce
✔ Journalisez les tentatives suspectes :
if (preg_match('/(<script|SELECT|DROP|UNION)/i', $input)) {
error_log("Tentative d'injection détectée depuis " . $_SERVER['REMOTE_ADDR']);
die("Requête bloquée pour sécurité.");
}