103 votes

Qu'est-ce que l'injection SQL ?

Quelqu'un peut-il expliquer l'injection SQL ? Comment provoque-t-elle des vulnérabilités ? Où se trouve exactement le point où le SQL est injecté ?

91voto

Bill Karwin Points 204877

Quelqu'un peut-il expliquer l'injection SQL ?

L'injection SQL se produit lorsque vous interpolez du contenu dans une chaîne de requête SQL, et que le résultat modifie la syntaxe de votre requête d'une manière que vous n'aviez pas prévue.

Ce n'est pas forcément malveillant, ça peut être un accident. Mais une injection SQL accidentelle a plus de chances d'aboutir à une erreur qu'à une vulnérabilité.

Le contenu préjudiciable ne doit pas nécessairement provenir d'un utilisateur, il peut s'agir d'un contenu que votre application obtient de n'importe quelle source, ou même qu'elle génère elle-même dans le code.

Comment cela provoque-t-il des vulnérabilités ?

Elle peut conduire à des vulnérabilités car les attaquants peuvent envoyer à une application des valeurs dont ils savent qu'elles seront interpolées dans une chaîne SQL. En étant très malins, ils peuvent manipuler le résultat des requêtes, lire des données ou même modifier des données qu'ils ne devraient pas être autorisés à faire.

Exemple en PHP :

$password = $_POST['password'];
$id = $_POST['id'];
$sql = "UPDATE Accounts SET PASSWORD = '$password' WHERE account_id = $id";

Supposons maintenant que l'attaquant fixe les paramètres de la requête POST à " password=xyzzy " et " id=account_id ", ce qui donne le SQL suivant :

UPDATE Accounts SET PASSWORD = 'xyzzy' WHERE account_id = account_id

Bien que je m'attendais $id pour être un nombre entier, l'attaquant a choisi une chaîne de caractères qui est le nom de la colonne. Bien sûr, maintenant la condition est vraie sur chaque l'attaquant vient donc de définir le mot de passe de l'option chaque compte. L'attaquant peut maintenant se connecter au compte de n'importe qui, y compris les utilisateurs privilégiés.

Où se trouve exactement le point où le SQL est injecté ?

Ce n'est pas le SQL qui est injecté, c'est le contenu qui est interpolé ("injecté") dans une chaîne SQL, ce qui donne un type de requête différent de celui que j'avais prévu. J'ai fait confiance au contenu dynamique sans le vérifier, et j'ai exécuté aveuglément la requête SQL qui en résultait. C'est là que les problèmes commencent.

L'injection SQL est une faille dans le code de l'application, et non généralement dans la base de données ou dans la bibliothèque ou le cadre d'accès à la base de données.

La plupart des cas d'injection SQL peuvent être évités en utilisant des paramètres de requête. Voir Comment prévenir l'injection SQL en PHP ? par exemple.

28voto

Jim OHalloran Points 4034

L'injection SQL se produit lorsque l'utilisateur d'une application est capable d'affecter la signification d'une requête de base de données. Cela se produit souvent lorsque des chaînes arbitraires provenant de l'entrée de l'utilisateur sont concaténées pour créer un SQL qui est transmis à la base de données. Par exemple, imaginons que nous ayons le code suivant (en PHP, mais la même chose est valable pour n'importe quel langage), qui pourrait être utilisé pour gérer la connexion d'un utilisateur.

$sql = "SELECT  FROM users WHERE username='".$_GET['username']."' AND password='".$_GET['password']."'";

Le mal est fait lorsque l'utilisateur entre quelque chose comme

administrator'; --

... pour le nom d'utilisateur. Sans un encodage approprié, la requête devient :

SELECT * FROM users WHERE username='administrator'; -- AND password=''

Le problème ici est que le ' dans le nom d'utilisateur ferme le champ du nom d'utilisateur, puis le -- commence un commentaire SQL, ce qui fait que le serveur de base de données ignore le reste de la chaîne. Le résultat net est que l'utilisateur peut maintenant se connecter en tant qu'administrateur sans avoir à connaître le mot de passe. La connexion SQL peut également être utilisée pour exécuter des requêtes UPDATE, DELETE ou DROP et endommager réellement la base de données.

L'injection SQL peut être évitée en utilisant des requêtes paramétrées ou en appliquant les fonctions d'échappement de votre langage/outil (comme mysql_real_escape_string() en PHP).

Une fois que vous aurez compris l'injection SQL, vous comprendrez la blague derrière ce dessin animé .

14voto

L'injection SQL, c'est quand des choses qui sont censées être des données sont traitées comme du code SQL sans le vouloir.

Par exemple, si vous faites

mysql_query("SELECT * FROM posts WHERE postid=$postid");

Normalement, cela devrait vous permettre d'obtenir le message avec un id donné, mais supposez que $postid est défini comme la chaîne de caractères 10; DROP TABLE posts -- tout d'un coup, la requête que vous envoyez est

mysql_query("SELECT * FROM posts WHERE postid=10; DROP TABLE posts --");

C'est un problème, car vous perdriez l'intégralité de votre table des messages à cause d'un utilisateur malveillant - oh là là.

La manière la plus simple d'éviter cela est d'utiliser des instructions préparées, par exemple par le biais de AOP ou MySQLi .

L'exemple équivalent dans PDO serait alors

$statement = $db->prepare('SELECT * FROM posts WHERE postid = :postid');
$statement->bindValue(':postid', $postid);
$statement->execute();

Cela garantit que le système de base de données sait que $postid doit être traité comme une donnée et non comme un code, et qu'il sera donc traité de manière appropriée.

12voto

Bill Karwin Points 204877

Cette question a reçu de nombreuses réponses sur StackOverflow, mais il s'agit d'un sujet important à connaître pour tout le monde, donc je ne vais pas voter pour fermer cette question.

Voici des liens vers certaines de mes réponses passées sur ce sujet :

J'ai également donné une présentation à la conférence MySQL ce mois-ci, et mes diapositives sont en ligne :

11voto

Smashery Points 13208

Il existe de nombreuses ressources sur le web - il suffit de les chercher sur Google :

http://en.wikipedia.org/wiki/SQL_Injection est un bon point de départ.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X