A — Injection SQL : contournement total de l'authentification
En saisissant ' OR '1'='1 comme identifiant, la requête devient :
sqlSELECT * FROM administrateurs WHERE login = '' OR '1'='1' AND mot_de_passe = ''
La condition est vraie, une ligne revient, l'attaquant est administrateur
— sans connaître le moindre mot de passe.
php — corrigé$req = $pdo->prepare("SELECT * FROM administrateurs WHERE login = :login");
$req->execute([':login' => $_POST['login']]);
$admin = $req->fetch();
if ($admin && password_verify($_POST['mot_de_passe'], $admin['mot_de_passe'])) {
$_SESSION['admin_connecte'] = true;
$_SESSION['login'] = $admin['login'];
header("Location: dashboard.php");
exit();
}
$erreur = "Identifiants incorrects.";
Notez qu'on ne cherche plus le mot de passe dans la requête : on récupère
l'administrateur par son login, puis on vérifie l'empreinte en PHP.
B — htmlspecialchars() n'est pas une protection SQL
| Fonction | Protège de | À quel moment |
htmlspecialchars() | XSS |
à l'affichage |
prepare() | injection SQL |
à l'envoi en base |
Pire : appliquée avant l'insertion, elle corrompt les données.
« O'Brien » est stocké O'Brien et ressortira ainsi partout.
php — corrigé// à l'ÉCRITURE : on prépare, on ne transforme pas
$req = $pdo->prepare("INSERT INTO etudiants (nom, prenom, classe)
VALUES (:nom, :prenom, :classe)");
$req->execute([
':nom' => trim($_POST['nom']),
':prenom' => trim($_POST['prenom']),
':classe' => trim($_POST['classe'])
]);
// à la LECTURE, dans etudiants.php : c'est là qu'on échappe
echo htmlspecialchars($ligne['nom']);
C — Mot de passe stocké en clair
Quiconque ouvre phpMyAdmin ou récupère une sauvegarde lit tous les mots de passe.
php — générer l'empreinte une foisecho password_hash('admin', PASSWORD_DEFAULT);
// $2y$10$e0MYzXyjpJS7Pd0RVvHwHe1HlcS7.dV8rXk...
sql — et l'insérerINSERT INTO administrateurs (login, mot_de_passe)
VALUES ('admin', '$2y$10$e0MYzXyjpJS7Pd0RVvHwHe1HlcS7.dV8rXk...');
La colonne était déjà déclarée VARCHAR(255) : la structure prévoyait le
hachage, il ne manquait que de s'en servir.
🌍 Ce que ces trois corrections valent à l'examen E6
Un projet fonctionnel qui laisse passer ' OR '1'='1 perd beaucoup plus de
points qu'un projet un peu moins complet mais sécurisé. La sécurité fait partie des
critères d'évaluation — et l'injection SQL est le premier test que fait un
correcteur.
La bonne nouvelle : les trois corrections tiennent en une vingtaine de lignes. Votre
conception de base (tables, clés, PDO, sessions) était déjà juste.
🧰 La checklist de sécurité d'un projet PHP/MySQL
- Toute requête contenant une variable →
prepare() + execute().
- Mots de passe →
password_hash() / password_verify().
- Chaque page privée →
session_start() + garde +
exit().
- Tout affichage de donnée utilisateur →
htmlspecialchars().
- PDO →
utf8mb4 et ERRMODE_EXCEPTION.