Ce wikiHow vous apprend comment empêcher l'injection SQL à l'aide d'instructions préparées en PHP. L'injection SQL est l'une des vulnérabilités les plus courantes dans les applications Web aujourd'hui. Les instructions préparées utilisent des paramètres liés et ne combinent pas de variables avec des chaînes SQL, ce qui empêche un attaquant de modifier l'instruction SQL.
Les instructions préparées combinent la variable avec l'instruction SQL compilée, de sorte que le SQL et les variables sont envoyés séparément. Les variables sont alors interprétées comme de simples chaînes et ne font pas partie de l'instruction SQL. En utilisant les méthodes décrites dans les étapes ci-dessous, vous n'aurez pas besoin d'utiliser d'autres techniques de filtrage d'injection SQL telles que mysql_real_escape_string().
Pas
Partie 1 sur 2: Comprendre l'injection SQL
Étape 1. L'injection SQL est un type de vulnérabilité dans les applications qui utilisent une base de données SQL
La vulnérabilité survient lorsqu'une entrée utilisateur est utilisée dans une instruction SQL:
$nom = $_GET['nom d'utilisateur']; $query = "SELECT mot de passe FROM tbl_user WHERE nom = '$nom' ";
Étape 2. La valeur qu'un utilisateur entre dans la variable URL username sera affectée à la variable $name
Il est ensuite placé directement dans l'instruction SQL, permettant à l'utilisateur de modifier l'instruction SQL.
$nom = "admin' OU 1=1 -- "; $query = "SELECT mot de passe FROM tbl_user WHERE nom = '$nom' ";
Étape 3. La base de données SQL recevra alors l'instruction SQL comme suit:
SELECTIONNER le mot de passe FROM tbl_users WHERE nom = 'admin' OU 1=1 -- '
-
C'est du SQL valide, mais au lieu de renvoyer un mot de passe pour l'utilisateur, l'instruction renverra tous les mots de passe de la table tbl_user. Ce n'est pas quelque chose que vous voulez dans vos applications Web.
Partie 2 sur 2: Utilisation de mySQLi pour créer des instructions préparées
Étape 1. Créez la requête mySQLi SELECT
Utilisez le code ci-dessous pour SÉLECTIONNER les données d'une table à l'aide d'instructions préparées mySQLi.
$nom = $_GET['nom d'utilisateur']; if ($stmt = $mysqli->prepare("SELECT password FROM tbl_users WHERE name=?")) { // Lie une variable au paramètre sous forme de chaîne. $stmt->bind_param("s", $nom); // Exécute l'instruction. $stmt->execute(); // Récupère les variables de la requête. $stmt->bind_result($pass); // Récupérer les données. $stmt->fetch(); // Affiche les données. printf("Le mot de passe pour l'utilisateur %s est %s\n", $name, $pass); // Ferme l'instruction préparée. $stmt->close(); }
Remarque: La variable $mysqli est l'objet de connexion mySQLi
Étape 2. Créez la requête mySQLi INSERT
Utilisez le code ci-dessous pour INSÉRER des données dans une table à l'aide d'instructions préparées mySQLi.
$nom = $_GET['nom d'utilisateur']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("INSERT INTO tbl_users (nom, mot de passe) VALUES (?, ?)")) { // Lie les variables au paramètre sous forme de chaînes. $stmt->bind_param("ss", $name, $password); // Exécute l'instruction. $stmt->execute(); // Ferme l'instruction préparée. $stmt->close(); }
Remarque: La variable $mysqli est l'objet de connexion mySQLi
Étape 3. Créez la requête de mise à jour mySQLi
Utilisez le code ci-dessous pour METTRE À JOUR les données d'une table à l'aide d'instructions préparées mySQLi.
$nom = $_GET['nom d'utilisateur']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("UPDATE tbl_users SET mot de passe = ? WHERE nom = ?")) { // Lie les variables au paramètre sous forme de chaînes. $stmt->bind_param("ss", $password, $name); // Exécute l'instruction. $stmt->execute(); // Ferme l'instruction préparée. $stmt->close(); }
Remarque: La variable $mysqli est l'objet de connexion mySQLi
Étape 4. Créez la requête mySQLi DELETE
Le script ci-dessous explique comment SUPPRIMER des données d'une table à l'aide d'instructions préparées mySQLi.
$nom = $_GET['nom d'utilisateur']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("DELETE FROM tbl_users WHERE name = ?")) { // Lie la variable au paramètre sous forme de chaîne. $stmt->bind_param("s", $nom); // Exécute l'instruction. $stmt->execute(); // Ferme l'instruction préparée. $stmt->close(); }