web-dev-qa-db-fra.com

Qu'est-ce que l'injection SQL?

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

90
subu

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 le résultat modifie la syntaxe de votre requête d'une manière que vous ne vouliez pas.

Cela n'a pas besoin d'être malveillant, cela peut être un accident. Mais une injection SQL accidentelle est plus susceptible d'entraîner une erreur qu'une vulnérabilité.

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

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

Cela peut entraîner des vulnérabilités car les attaquants peuvent envoyer des valeurs à une application dont ils savent qu'elles seront interpolées dans une chaîne SQL. En étant très intelligents, ils peuvent manipuler le résultat de 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 définit les paramètres de requête POST sur "password=xyzzy" et "id=account_id "résultant en SQL suivant:

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

Même si je m'attendais à $id pour être un entier, l'attaquant a choisi une chaîne qui est le nom de la colonne. Bien sûr, maintenant la condition est vraie sur la ligne every, donc l'attaquant vient de définir le mot de passe pour le compte every. Désormais, l'attaquant peut se connecter au compte de n'importe qui - y compris les utilisateurs privilégiés.

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

Ce n'est pas du SQL qui est injecté, c'est du contenu qui est interpolé ("injecté") dans une chaîne SQL, résultant en un type de requête différent de celui que je souhaitais. J'ai fait confiance au contenu dynamique sans le vérifier et j'ai exécuté la requête SQL résultante à l'aveugle. C'est là que le problème commence.

L'injection SQL est une erreur dans le code d'application, pas typiquement dans la base de données ou dans la bibliothèque ou l'infrastructure 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 puis-je empêcher l'injection SQL en PHP? pour des exemples.

81
Bill Karwin

L'injection SQL se produit lorsque l'utilisateur d'une application est en mesure d'affecter la signification de la requête de base de données. Cela se produit souvent lorsque des chaînes arbitraires de l'entrée utilisateur sont concaténées pour créer du SQL qui est alimenté dans la base de données. Par exemple, disons que nous avions le code suivant (en PHP, mais il en va de même pour n'importe quel langage), qui pourrait être utilisé pour gérer une connexion 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 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 - démarre un commentaire SQL obligeant le serveur de base de données à ignorer le reste de la chaîne. Le résultat net est que l'utilisateur peut désormais se connecter en tant qu'administrateur sans avoir à connaître le mot de passe. SQL Inection peut également être utilisé 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/boîte à outils (telles que mysql_real_escape_string () en PHP).

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

27
Jim OHalloran

L'injection SQL, c'est quand des choses qui sont censées être des données sont traitées à contrecœur comme du code SQL.

Par exemple, si vous deviez faire

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

Normalement, vous obtiendrez le message avec un identifiant donné, mais supposez que $postid est défini sur la chaîne 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 tout un problème, car vous perdriez l'intégralité de votre tableau de messages en raison d'un utilisateur malveillant - oh mon cher.

Le moyen le plus simple d'empêcher cela est d'utiliser des instructions préparées, par exemple via PDO ou MySQLi .

L'exemple équivalent en AOP 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 des données et non comme du code, et sera donc traité de manière appropriée.

Cette question a reçu de nombreuses réponses sur StackOverflow, mais c'est un sujet important que tout le monde doit connaître, donc je ne vais pas voter pour clore cette question.

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

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

11
Bill Karwin

L'injection SQL est l'endroit où un utilisateur malveillant mettra du SQL dans les champs de saisie pour essayer d'exécuter le SQL sur votre serveur.

Le conseil n ° 1 auquel j'adhère est d'utiliser des procédures stockées paramétrées plutôt que de construire du SQL brut dans du code.

Les paramètres de procédure stockée ne sont pas exécutés, ce qui les rend sûrs dans la plupart des cas.

6
John Weldon

J'ai trouvé que ce document était une très bonne lecture des techniques d'injection SQL (lien vers PDF): Injection SQL avancée dans les applications SQL Server .

Malgré le titre "Avancé", il est assez lisible même si vous n'avez pas beaucoup de connaissances sur l'injection SQL.

4
Chad Birch

Vous aimerez this article du projet de code; )

Résumé

  • Chiffrez les données sensibles.
  • Accédez à la base de données en utilisant un compte avec le moins de privilèges nécessaires.
  • Installez la base de données en utilisant un compte avec le moins de privilèges nécessaires.
  • Assurez-vous que les données sont valides.
  • Examinez le code pour vérifier la possibilité d'attaques de second ordre.
  • Utilisez des requêtes paramétrées.
  • Utilisez des procédures stockées.
  • Re-valider les données dans les procédures stockées.
  • Assurez-vous que les messages d'erreur ne révèlent rien sur l'architecture interne de l'application ou de la base de données.
1
SDReyes

Pour obtenir des informations générales, consultez le article Wikipedia sur l'injection SQL .

En bref, les attaques par injection SQL peuvent vous rendre vulnérable à tout type de vol et de destruction de données de base de données. Les détails exacts de ce qui peut être fait pour votre système dépendent des détails du système lui-même.

Chaque fois que vous transmettez une entrée de vos utilisateurs à votre base de données, vous avez un point d'injection potentiel. Les applications Web manquent souvent à cet égard, car les nouveaux programmeurs ne comprennent souvent pas les risques de gérer les entrées des utilisateurs, et les applications Web sont attaquées par des gens très intelligents que vous n'auriez jamais pensé trouver votre programme.

1
acrosman

Le point où SQL est injecté est tout point où votre application accepte les entrées de l'utilisateur.

Que cela devienne une vulnérabilité dangereuse pour votre application Web dépend de l'utilisation ultérieure de cette entrée dans le cadre d'une requête SQL sans vérifier correctement son type et l'échapper si nécessaire.

Sans échappement approprié, du code SQL "injecté" par l'utilisateur pourrait être exécuté par le moteur SQL sous forme de code SQL, plutôt qu'une simple chaîne ou valeur.

0
thomasrutter