Empêcher l'injection SQL dans PHP
- Utilisez les instructions préparées et le PDO pour empêcher l’injection SQL en PHP
-
Utilisez les instructions
Prepared
avec la requête paramétrée pour empêcher l’injection SQL en PHP -
Définissez l’attribut
PDO::ATTR_EMULATE_PREPARES
surfalse
pour empêcher l’injection SQL
Nous allons introduire une méthode pour empêcher l’injection SQL en PHP en utilisant les instructions préparées et les objets de données PHP (PDO). Nous utilisons PDO pour établir la communication avec la base de données dans cette méthode. Cette méthode envoie les données et la requête séparément au serveur de base de données, ce qui empêche le mélange des données et du serveur.
Nous allons introduire une méthode pour empêcher l’injection SQL en PHP en utilisant les instructions préparées et la requête paramétrée. Nous utilisons mysqli
pour établir la communication avec la base de données dans cette méthode. Cette méthode a un mécanisme de travail similaire à la première méthode. Le point de contraste n’est que les fonctions mysqli
que nous utilisons pour empêcher l’injection SQL.
Nous allons vous montrer un exemple de comment se protéger de l’injection SQL tout en utilisant le PDO en PHP en définissant l’émulation des instructions préparées sur false
.
Utilisez les instructions préparées et le PDO pour empêcher l’injection SQL en PHP
Nous pouvons utiliser l’instruction préparée avec le PDO pour empêcher l’injection SQL en PHP. L’injection SQL se produit lors du mélange de la requête et des données lors de l’envoi à la base de données. Dans cette méthode, nous ne spécifions pas la valeur exacte des données dans l’instruction SQL. Nous utilisons les espaces réservés à la place. Pour cette raison, les instructions SQL paramétrées sont envoyées au serveur en tant que première requête. Nous utilisons la fonction prepare()
pour y parvenir. Nous lions la valeur exacte du paramètre dans la deuxième requête au serveur de base de données. Nous utilisons la fonction bindValue()
à cet effet. De cette manière, nous envoyons le programme à la première requête et les données à la seconde requête. Si nous demandons les données avec les codes SQL, l’utilisateur peut modifier le programme et écrire des codes malveillants. Ainsi, il empêche les codes SQL malveillants d’être injectés dans le serveur.
Par exemple, une table utilisateurs
contient les champs et données suivants.
+----+-----------+----------+------------+
| id | firstname | lastname | dob |
+----+-----------+----------+------------+
| 1 | bruce | rose | 1998-02-13 |
| 2 | jeff | james | 2000-03-30 |
+----+-----------+----------+------------+
Il crée une variable $firstname
et lui attribue le nom bruce
. Il crée une variable $sql
et écrit une requête SELECT * FROM users WHERE firstname =:fname;
dessus.
N’écrivez pas la valeur exacte des données pour firstname
. À la place, utilisez le paramètre :fname
. Utilisez la variable $pdo
pour appeler la fonction prepare()
sur la variable de requête. Remplacez la valeur de :fname
par la variable firstname
. Exécutez l’instruction avec la fonction execute()
. Vérifiez le résultat avec la fonction fetch()
si les identifiants correspondent à la base de données. Si c’est le cas, affichez le id
, le firstname
, et le lastname
de la ligne sélectionnée.
L’exemple ci-dessous illustre l’utilisation d’une instruction préparée. Il stocke la valeur du champ firstname
dans une variable pour vérifier si les informations d’identification correspondent. Si la variable contenait du code malveillant à la place, elle afficherait le message Credentials do no match
. En effet, la fonction prepared()
ne prend que la requête paramétrée et n’autorise pas les données exactes. La variable $pdo
contient l’objet de la connexion à la base de données.
Exemple de code:
# php 7.*
<?php
$firstname = "bruce";
$sql = "SELECT * FROM users WHERE firstname =:fname ;";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":fname", $firstname);
$stmt->execute();
if(!$result = $stmt->fetch(PDO::FETCH_OBJ)){
echo "Credentials do no match";
} else {
echo"Id: ".$result->id. " Name: ".$result->firstname." ".$result->lastname;
}
?>
Production:
Id: 1 Name: bruce rose
Utilisez les instructions Prepared
avec la requête paramétrée pour empêcher l’injection SQL en PHP
Nous pouvons utiliser l’instruction préparée avec la requête paramétrée pour empêcher l’injection SQL en PHP. Nous utilisons l’objet de la fonction mysqli()
pour créer une connexion à la base de données. Dans cette méthode, nous utilisons un symbole de point d’interrogation ?
comme espaces réservés des données. Nous utilisons la fonction prepare()
comme méthode ci-dessus. Nous utilisons la fonction bind_param()
pour lier les données réelles dans l’espace réservé. Cette méthode suit un mécanisme de travail similaire à la méthode ci-dessus.
Par exemple, établissez une connexion à la base de données créant un objet de la fonction mysqli()
, et affectez-le à une variable $conn
. Affectez avec le nom jeff
à une variable $firstname
. Créez une variable $sql
et écrivez une requête SELECT * FROM users WHERE first name =?;
. Utilisez la variable $conn
pour appeler la fonction prepare()
sur la variable de requête. Remplacez l’espace réservé ?
avec la variable $firstname
. Exécutez l’instruction avec la fonction execute()
. Appelez la fonction get_result()
pour stocker le résultat dans la variable $result
. Vérifiez si la ligne existe avec la propriété num_rows
et renvoyez le message No Rows
avec la fonction exit()
si la condition échoue. Appelez la méthode fetch_assoc()
et stockez-la dans la variable $row
dans une boucle while. Affichez le id
, le firstname
et le lastname
de la ligne sélectionnée.
Exemple de code:
#php 7.x
<?php
$conn = new mysqli($host, $user, $pwd, $dbName);
$firstname = "jeff";
$sql = "SELECT * FROM users WHERE firstname = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $firstname);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows === 0) exit('No rows');
while($row = $result->fetch_assoc()) {
echo"Id: ".$row['id']. " Name: ".$row['firstname']." ".$row['lastname'];
}
Production:
Id: 2 Name: jeff james
Définissez l’attribut PDO::ATTR_EMULATE_PREPARES
sur false
pour empêcher l’injection SQL
L’utilisation d’instructions préparées dans PDO peut ne pas être suffisante pour empêcher l’injection SQL si nous ne définissons pas correctement les attributs PDO. Il faut mettre l’attribut PDO::ATTR_EMULATE_PREPARES
à false
pour empêcher l’injection. Si nous définissons l’attribut sur true
, le PDO émulera uniquement les instructions préparées au lieu de les utiliser. Ainsi, le système sera vulnérable à l’injection SQL.
Par exemple, créez une connexion PDO à la base de données dans une variable $pdo
. Utilisez la variable pour appeler la fonction setAttribute()
. Définissez l’attribut PDO::ATTR_EMULATE_PREPARES
sur false.
Exemple de code:
#php 7.x
<?php
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
?>
Subodh is a proactive software engineer, specialized in fintech industry and a writer who loves to express his software development learnings and set of skills through blogs and articles.
LinkedIn