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

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() ou filter_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 :

  1. Le type MIME réel (pas seulement l’extension)
  2. La taille maximale
  3. 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é.");
}