Tutoriel SQL

ACCUEIL SQL Introduction SQL Syntaxe SQL Sélection SQL SQL Select Distinct SQL Où SQL et, ou, pas Tri SQL par Insertion SQL dans Valeurs nulles SQL Mise à jour SQL Supprimer SQL SQL Sélectionner Haut Min et Max SQL Nombre SQL, Moy, Somme J'aime SQL Caractères génériques SQL Entrée SQL SQL Entre Alias ​​SQL Jointures SQL Jointure interne SQL Jointure gauche SQL Jointure droite SQL Jointure complète SQL Auto-jointure SQL Union SQL Regrouper SQL par SQL ayant SQL existe SQL Tout, Tout SQL Sélectionner dans Insertion SQL dans la sélection Cas SQL Fonctions nulles SQL Procédures stockées SQL Commentaires SQL Opérateurs SQL

Base de données SQL

SQL Créer une base de données BD de suppression SQL Base de données de sauvegarde SQL Créer une table SQL Table de dépôt SQL Table de modification SQL Contraintes SQL SQL non nul SQL unique Clé primaire SQL Clé étrangère SQL Vérification SQL SQL par défaut Index SQL Incrément automatique SQL Dates SQL Vues SQL Injection SQL Hébergement SQL Types de données SQL

Références SQL

Mots clés SQL Fonctions MySQL Fonctions SQL Server Fonctions MS Access Référence rapide SQL

Exemples SQL

Exemples SQL Questionnaire SQL Exercices SQL Certificat SQL

Injection SQL


Injection SQL

L'injection SQL est une technique d'injection de code qui peut détruire votre base de données.

L'injection SQL est l'une des techniques de piratage Web les plus courantes.

L'injection SQL est le placement de code malveillant dans des instructions SQL, via une entrée de page Web.


SQL dans les pages Web

L'injection SQL se produit généralement lorsque vous demandez à un utilisateur une entrée, comme son nom d'utilisateur/ID utilisateur, et au lieu d'un nom/ID, l'utilisateur vous donne une instruction SQL que vous exécuterez sans le savoir sur votre base de données.

Regardez l'exemple suivant qui crée une SELECTinstruction en ajoutant une variable (txtUserId) à une chaîne de sélection. La variable est extraite de l'entrée utilisateur (getRequestString) :

Exemple

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Le reste de ce chapitre décrit les dangers potentiels de l'utilisation de l'entrée utilisateur dans les instructions SQL.


L'injection SQL basée sur 1=1 est toujours vraie

Reprenez l'exemple ci-dessus. L'objectif initial du code était de créer une instruction SQL pour sélectionner un utilisateur, avec un identifiant d'utilisateur donné.

Si rien n'empêche un utilisateur d'entrer une "mauvaise" entrée, l'utilisateur peut entrer une entrée "intelligente" comme celle-ci :

Identifiant d'utilisateur:

Ensuite, l'instruction SQL ressemblera à ceci :

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

Le SQL ci-dessus est valide et renverra TOUTES les lignes de la table "Utilisateurs", puisque OR 1=1 est toujours VRAI.

L'exemple ci-dessus vous semble-t-il dangereux ? Que faire si la table "Utilisateurs" contient des noms et des mots de passe ?

L'instruction SQL ci-dessus est sensiblement la même que celle-ci :

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

Un pirate peut avoir accès à tous les noms d'utilisateur et mots de passe d'une base de données, en insérant simplement 105 OR 1=1 dans le champ de saisie.



L'injection SQL basée sur ""="" est toujours vraie

Voici un exemple de connexion d'un utilisateur sur un site Web :

Nom d'utilisateur:

Mot de passe:

Exemple

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

Résultat

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

Un pirate peut accéder aux noms d'utilisateur et aux mots de passe d'une base de données en insérant simplement " OR ""=" dans la zone de texte du nom d'utilisateur ou du mot de passe :

Nom d'utilisateur:

Mot de passe:

Le code sur le serveur créera une instruction SQL valide comme celle-ci :

Résultat

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

Le SQL ci-dessus est valide et renverra toutes les lignes de la table "Utilisateurs", puisque OR ""="" est toujours VRAI.


Injection SQL basée sur des instructions SQL par lots 

La plupart des bases de données prennent en charge les instructions SQL par lots.

Un lot d'instructions SQL est un groupe de deux ou plusieurs instructions SQL, séparées par des points-virgules.

L'instruction SQL ci-dessous renverra toutes les lignes de la table "Utilisateurs", puis supprimera la table "Fournisseurs".

Exemple

SELECT * FROM Users; DROP TABLE Suppliers

Regardez l'exemple suivant :

Exemple

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Et l'entrée suivante :

Identifiant d'utilisateur:

L'instruction SQL valide ressemblerait à ceci :

Résultat

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

Utiliser les paramètres SQL pour la protection

Pour protéger un site Web contre l'injection SQL, vous pouvez utiliser des paramètres SQL.

Les paramètres SQL sont des valeurs qui sont ajoutées à une requête SQL au moment de l'exécution, de manière contrôlée.

Exemple de rasoir ASP.NET

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

Notez que les paramètres sont représentés dans l'instruction SQL par un marqueur @.

Le moteur SQL vérifie chaque paramètre pour s'assurer qu'il est correct pour sa colonne et qu'il est traité littéralement, et non comme faisant partie du SQL à exécuter.

Un autre exemple

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

Exemples

Les exemples suivants montrent comment créer des requêtes paramétrées dans certains langages Web courants.

SÉLECTIONNER L'INSTRUCTION DANS ASP.NET :

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();

INSÉRER DANS LA DÉCLARATION DANS ASP.NET :

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();

INSÉRER DANS LA DÉCLARATION EN PHP :

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();