Les bases de données constituent le cœur de nombreuses applications en ligne, stockant une variété d’informations, des noms d’utilisateurs aux données financières. Cependant, il existe une menace sournoise qui peut compromettre vos données : les injections SQL. Mais qu’est-ce que c’est exactement et comment pouvez-vous protéger votre système contre une injection SQL ?
Qu’est-ce qu’une Injection SQL ?
Une injection SQL est une technique utilisée par les pirates pour exploiter les failles de sécurité des applications web qui interagissent avec des bases de données. En exploitant ces failles, les attaquants peuvent manipuler les requêtes SQL de l’application pour accéder, modifier ou supprimer des données non autorisées.
Comment ça marche ?
Prenons un exemple simple. Supposons qu’un site web utilise une requête SQL pour authentifier les utilisateurs lors de la connexion :
SELECT * FROM utilisateurs WHERE nom_utilisateur='[nom_utilisateur]' AND mot_de_passe='[mot_de_passe]';
L’utilisateur entre son nom d’utilisateur et son mot de passe, puis l’application exécute cette requête pour vérifier s’il existe un utilisateur correspondant dans la base de données. Cependant, si l’application ne filtre pas correctement les entrées de l’utilisateur, un pirate peut entrer une entrée malveillante comme ceci :
' OR '1'='1
La requête SQL résultante ressemblera à ceci :
SELECT * FROM utilisateurs WHERE nom_utilisateur='' OR '1'='1' AND mot_de_passe='' OR '1'='1';
Cette requête renverra toutes les lignes de la table utilisateurs, car la condition '1'='1'
est toujours vraie. Ainsi, l’attaquant peut accéder à n’importe quel compte sans authentification.
Comment se Protéger d’une injection SQL ?
La meilleure façon de se protéger contre les injections SQL est d’utiliser des requêtes préparées ou des paramètres de requête. Avec MySQLi, vous pouvez utiliser des déclarations préparées comme ceci :
// Connexion à la base de données
$conn = new mysqli($serveur, $utilisateur, $motdepasse, $basededonnees);
// Vérification de la connexion
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Requête préparée
$stmt = $conn->prepare("SELECT * FROM utilisateurs WHERE nom_utilisateur = ? AND mot_de_passe = ?");
$stmt->bind_param("ss", $nom_utilisateur, $mot_de_passe);
// Assignation des valeurs et exécution
$nom_utilisateur = $utilisateur;
$mot_de_passe = $password;
$stmt->execute();
Les requêtes préparées avec MySQLi offrent une manière sécurisée de passer des paramètres à la requête SQL, ce qui rend beaucoup plus difficile pour les attaquants d’injecter du code malveillant.
De plus, tout comme avec PDO, il est crucial de valider et filtrer toutes les entrées utilisateur pour empêcher les attaques par injection SQL.
Les injections SQL sont une menace sérieuse pour la sécurité des applications web. En comprenant comment elles fonctionnent et en mettant en œuvre des pratiques de développement sécurisé, vous pouvez protéger vos données et votre système contre ces attaques néfastes.
La fonction prepare
Lorsque vous préparez une requête avec MySQLi, vous créez un objet de requête qui est ensuite utilisé pour exécuter cette requête plusieurs fois avec différentes valeurs de paramètres. Cela permet d’optimiser les performances de la base de données en préparant la requête une seule fois et en l’exécutant plusieurs fois avec différentes valeurs.
Voici comment vous pouvez préparer une requête avec MySQLi :
$stmt = $conn->prepare("SELECT * FROM utilisateurs WHERE nom_utilisateur = ? AND mot_de_passe = ?");
Dans cet exemple, conn
est l’objet de connexion à la base de données, et la requête SQL est passée en tant que chaîne de caractères. Les ?
dans la requête sont des marqueurs de paramètres qui seront remplacés par les valeurs réelles lors de l’exécution de la requête.
La fonction bind_param
Une fois que la requête est préparée, vous devez associer les valeurs aux paramètres de la requête. C’est là que bind_param intervient. Cette fonction associe les variables aux marqueurs de paramètres dans la requête préparée.
Voici comment vous pouvez utiliser bind_param :
$stmt->bind_param("ss", $nom_utilisateur, $mot_de_passe);
Dans cet exemple, ss
indique le type de données des paramètres. Dans ce cas, les deux paramètres sont des chaînes de caractères : s
pour string. Les variables $nom_utilisateur
et $mot_de_passe
sont les valeurs réelles que vous souhaitez passer à la requête.
Après avoir lié les paramètres, vous pouvez exécuter la requête avec execute() :
$stmt->execute();
Cela envoie la requête à la base de données avec les valeurs spécifiées pour les paramètres, et la base de données l’exécute avec ces valeurs.
Les types de paramètres
Tableau récapitulatif des types de paramètres possibles avec MySQLi, utilisés dans la fonction bind_param :
Type | Description |
---|---|
i |
Int (Entier) |
d |
Double (nombre à virgule flottante) |
s |
String (Chaîne de caractères) |
b |
Blob (données binaires) |
Fondateur de l’agence Créa-troyes.
Intervenant en Freelance.
Contactez-moi