Toute requête peut être injectée, qu'elle soit en lecture ou en écriture, persistante ou transitoire. Les injections peuvent être effectuées en terminant une requête et en en exécutant une autre (possible avec mysqli
), ce qui rend la requête voulue non pertinente.
Toute entrée d'une requête provenant d'une source externe, qu'elle provienne d'utilisateurs ou même d'une source interne, doit être considérée comme un argument de la requête et un paramètre dans le contexte de la requête. Tout paramètre d'une requête doit être paramétré. Cela conduit à une requête correctement paramétrée à partir de laquelle vous pouvez créer une instruction préparée et l'exécuter avec des arguments. Par exemple :
SELECT col1 FROM t1 WHERE col2 = ?
?
est un espace réservé pour un paramètre. Utilisation de mysqli
, vous pouvez créer une instruction préparée en utilisant prepare
, lier une variable (argument) à un paramètre en utilisant bind_param
, et exécutez la requête avec execute
. Vous n'avez pas du tout besoin d'assainir l'argument (en fait, c'est préjudiciable de le faire). mysqli
fait ça pour toi. Le processus complet serait :
$stmt = $mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();
Il existe également une distinction importante entre requête paramétrée et déclaration préparée . Cette instruction, bien que préparée, n'est pas paramétrée et est donc vulnérable à l'injection :
$stmt = $mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");
Pour résumer :
- Tous Les requêtes doivent être correctement paramétrées (sauf si elles n'ont pas de paramètres)
- Tous les arguments d'une requête doivent être traités de la manière la plus hostile possible, quelle que soit leur source