Semaine 2 - Jour 5 : Validation et sécurité des formulaires

Pourquoi sécuriser les formulaires ?

La sécurité des formulaires est cruciale en développement web. Les données envoyées par les utilisateurs peuvent contenir du code malveillant, des tentatives d'injection SQL, ou du JavaScript dangereux (attaques XSS).

Dans ce cours, nous allons apprendre à valider les données (vérifier qu'elles sont correctes) et à les sécuriser (les protéger contre les attaques). La règle d'or : ne jamais faire confiance aux données utilisateur !

1. Validation des champs

Définition : Vérifier que les données sont présentes et au bon format.

<?php
$erreurs = [];

// Vérifier si le champ est vide
if (empty($_POST['nom'])) {
    $erreurs[] = "Le nom est obligatoire";
}

// Alternative avec trim()
$nom = trim($_POST['nom'] ?? '');
if ($nom === '') {
    $erreurs[] = "Le nom est obligatoire";
}

// Afficher les erreurs
foreach ($erreurs as $erreur) {
    echo "❌ " . $erreur . "\n";
}
?>
Astuce : Utilisez trim() pour enlever les espaces au début et à la fin.

2. Validation d'email

Définition : Vérifier qu'une adresse email est valide avec filter_var().

<?php
$email = $_POST['email'];

// Validation avec filter_var()
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "❌ Email invalide";
} else {
    echo "✅ Email valide : " . $email;
}

// Exemples de validation
filter_var("user@example.com", FILTER_VALIDATE_EMAIL);
// ✅ Valide

filter_var("userexample.com", FILTER_VALIDATE_EMAIL);
// ❌ Invalide (pas de @)

filter_var("user@", FILTER_VALIDATE_EMAIL);
// ❌ Invalide (pas de domaine)
?>
Résultat : filter_var() retourne l'email si valide, ou false sinon.

3. Protection XSS

XSS (Cross-Site Scripting) : Injection de code JavaScript malveillant dans une page.

<?php
// ❌ DANGEREUX - Ne JAMAIS faire ça !
$nom = $_POST['nom'];
echo "Bonjour " . $nom;
// Si l'utilisateur entre : <script>alert('XSS')</script>
// Le script sera exécuté !

// ✅ SÉCURISÉ avec htmlspecialchars()
$nom = $_POST['nom'];
echo "Bonjour " . htmlspecialchars($nom, ENT_QUOTES, 'UTF-8');
// Le code HTML est converti en texte
// <script> devient &lt;script&gt;

// Autres fonctions utiles
strip_tags($texte);
// Enlève toutes les balises HTML
?>
Règle d'or : Toujours utiliser htmlspecialchars() avant d'afficher des données utilisateur.

4. Protection CSRF

CSRF (Cross-Site Request Forgery) : Forcer un utilisateur à exécuter une action non désirée.

<?php
session_start();

// Générer un token unique
if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>

<!-- Ajouter le token dans le formulaire -->
<form method="POST">
    <input type="hidden" name="csrf_token"
           value="<?= $_SESSION['csrf_token'] ?>">
    <button type="submit">Envoyer</button>
</form>

<?php
// Vérifier le token lors du traitement
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die("❌ Erreur CSRF : token invalide");
}
?>
Comment ça marche : Le token est unique à chaque session et impossible à deviner.
Froggiesplaining :


Objectifs de ce cours :
✅ Comprendre les risques de sécurité (XSS, CSRF)
✅ Valider les données avec filter_var() et preg_match()
✅ Protéger contre les attaques XSS avec htmlspecialchars()
✅ Implémenter des tokens CSRF pour sécuriser les formulaires
✅ Utiliser password_hash() pour hasher les mots de passe

Points clés à retenir :
• NEVER TRUST USER INPUT - ne jamais faire confiance aux données utilisateur
• Toujours utiliser htmlspecialchars() avant d'afficher des données
• Valider côté serveur (la validation JavaScript peut être contournée)
• Utiliser filter_var() pour valider emails, URLs, nombres
• Implémenter des tokens CSRF pour les actions sensibles
• password_hash() pour les mots de passe, JAMAIS MD5 ou SHA1
• trim() pour enlever les espaces inutiles
• empty() vérifie si une variable est vide

Checklist de sécurité :
✅ Validation côté serveur (obligatoire)
✅ htmlspecialchars() pour afficher les données utilisateur
✅ filter_var() pour valider emails, URLs, nombres
✅ Tokens CSRF pour les formulaires sensibles
✅ password_hash() et password_verify() pour les mots de passe
✅ HTTPS pour transmettre des données sensibles
✅ Limiter les tentatives de soumission (rate limiting)
✅ Requêtes préparées PDO pour les bases de données

Exercice pratique :
1. Créez un formulaire d'inscription avec nom, email, mot de passe
2. Validez que tous les champs sont remplis
3. Validez l'email avec filter_var()
4. Validez le mot de passe (8+ caractères, maj, min, chiffre)
5. Ajoutez un token CSRF
6. Utilisez htmlspecialchars() pour afficher les données
7. Hashez le mot de passe avec password_hash()

Froggie explain

GitHub - eCrea