web-dev-qa-db-fra.com

PHP MySQLI Prevent SQL Injection

J'ai créé un site Web qui sera bientôt en ligne et je n'ai que quelques questions sur la prévention de l'injection SQL, je comprends comment utiliser mysqli_real_escape_string mais je me demande simplement si je dois utiliser cela sur toutes les variables que j'obtiens pour mon instruction SQL et dois-je l'utiliser lorsque je fais des instructions select aussi ou simplement lors de l'insertion de la mise à jour et de la suppression? Quelle autre sécurité recommanderiez-vous que je mette en œuvre avant de mettre le site en ligne, merci d'avance pour toute aide!

39
user2201765

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 exécutant une autre (possible avec mysqli), ce qui rend la requête souhaitée non pertinente.

Toute entrée d'une requête provenant d'une source externe, qu'elle provienne d'utilisateurs ou même 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. En utilisant 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 de désinfecter l'argument (en fait, c'est préjudiciable de le faire). mysqli fait cela pour vous. 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 instruction préparée . Cette déclaration, 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])");

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 aussi hostiles que possible, quelle que soit leur source
46
Explosion Pills

Il sera fermé en quelques secondes, mais juste pour mettre les choses au clair

Je comprends comment utiliser mysqli_real_escape_string

J'ai bien peur que non.

si je dois l'utiliser sur toutes les variables que je reçois pour mon instruction SQL

définitivement pas.
cette fonction doit être utilisée pour formater les chaînes SQL niquement

dois-je l'utiliser lorsque je fais des instructions select aussi ou simplement pour insérer la mise à jour et la suppression?

TOUTE instruction SQL. Mais encore une fois, pas "en utilisant mysqli_real_escape_string" mais en formatant vos littéraux complètement et correctement

Quelle autre sécurité recommanderiez-vous

en ce qui concerne la sécurité SQL - vous devez formater correctement non seulement les chaînes mais les littéraux de type any. Et chacun requiert un ensemble distinct de règles de formatage

1
Your Common Sense