Puisque toutes les requêtes SQL doivent être préparées pour empêcher les injections SQL, pourquoi sommes-nous autorisés à écrire et exécuter des requêtes non préparées? Cela ne semble-t-il pas contre-intuitif?

2
riste 5 mai 2020 à 18:18

3 réponses

Dans les cas où la requête est une chaîne fixe et ne nécessite aucune variable de programme, vous pouvez utiliser query() en toute sécurité pour l'exécuter.

Voici l'exemple de https://www.php.net/manual/en/ pdo.query.php:

<?php
$sql = 'SELECT name, color, calories FROM fruit ORDER BY name';
foreach ($conn->query($sql) as $row) {
    print $row['name'] . "\t";
    print $row['color'] . "\t";
    print $row['calories'] . "\n";
}

La requête ne contient aucune variable PHP. Le query() est suffisant et accomplit la même chose que prepare() et execute().

Si vous devez remplacer des variables PHP par des valeurs dans des expressions SQL, vous utiliserez des paramètres:

$sql = 'SELECT name, colour, calories FROM fruit
    WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql);
$sth->execute(array('calories' => 150, 'colour' => 'red'));

Vous constaterez peut-être que cela est plus courant dans votre application que d'exécuter une requête fixe.

1
Bill Karwin 5 mai 2020 à 18:59

Les paramètres liés et la préparation des requêtes sont deux différents des choses. Vous pouvez faire l'un ou l'autre ou les deux.

Vous devez lier des paramètres pour empêcher l'injection SQL. Cependant, il y a des choses qui ne peuvent pas être passées en tant que paramètres (par exemple la liste ORDER BY), auquel cas vous pouvez concaténer la syntaxe SQL souhaitée directement dans la chaîne SQL. Cela s'appelle «SQL dynamique» et ne doit généralement utiliser que des chaînes sur liste blanche pour empêcher l'injection SQL.

Donc, pour répondre (ce que je pense être), vous vous interrogez: le SQL dynamique est autorisé car il y a des cas non couverts par les paramètres liés.

1
Branko Dimitrijevic 5 mai 2020 à 19:20

Même si vous avez besoin d'utiliser des instructions préparées, il n'y a aucun moyen d'empêcher la création de l'instruction préparée à partir d'une substitution de variable. Par exemple.

$sql = "SELECT * FROM someTable WHERE id = $id";
$stmt = $conn->prepare($sql);
1
Barmar 5 mai 2020 à 15:22