# Résumé # Une attaque par injection SQL consiste en l'insertion ou «injection» d'une requête SQL dans les données entrées par le client. Un exploit réussi de l'injection SQL permet de lire les données sensibles de la base de données, modifier des données de bases de données (INSERT / UPDATE / Supprimer), exécuter dles opérations d'administration sur la base de données (par exemple, l'arrêt du SGBD), récupérer le contenu d'un fichier présent dans le système SGBD et, dans certains cas, passer des commandes sur le système d'exploitation. L'attaque par injection SQL est un type d'attaque par injection, dans lequel les commandes SQL sont injectés dans les données entrées afin d'exécuter des commandes SQL prédéfinies. ## Les attaques de type injection SQL ## Permettent à des attaquants d'altérer les données existantes, d'entraîner des problèmes tels que la répudiation des transactions annulées ou de modifier soldes, de permettre la divulgation complète de toutes les données sur le système, de détruire les données ou rendre indisponible, de devenir des administrateurs du serveur de base de données. Sont très répandues dans les applications PHP et ASP en raison de la prévalence des anciennes interfaces fonctionnelles. En raison de la nature des interfaces de programmation disponibles, les applications J2EE et ASP.NET sont moins susceptibles de permettre une exploitation facile des injections SQL. La gravité des attaques par injection SQL est limitée par les connaissances de l'attaquant, et, dans une moindre mesure, par les contre-mesures de défense, telles que les connexions à faibles privilèges sur le serveur de base de données et ainsi de suite. En général, l'injection SQL a un niveau de gravité et un impact élevés. ## Références : ## Afin de se protéger des injections SQL voir les articles de l'OWASP: https://www.owasp.org/index.php/Guide_to_SQL_Injection * https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet Afin de détecter les vulnérabilités de type injection SQL voir les articles de l'OWASP : * https://www.owasp.org/index.php/Reviewing_Code_for_SQL_Injection * https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OWASP-DV-005) # Description: # Une injection DescriptionSQL se produire lorsque: * Des données peuvent entrer dans un programme à partir d'une source non fiable. * Des données sont utilisées pour construire dynamiquement une requête SQL Les principales conséquences sont les suivantes: * **Confidentialité:** Les bases de données SQL détiennent généralement des données sensibles, la perte de confidentialité est un problème fréquent avec les vulnérabilités d'injection SQL. * **Authentification:** Si des commandes SQL non sécurisées sont utilisées pour vérifier les noms d'utilisateur et mots de passe, il peut être possible de se connecter à un système sans connaissance préalable du mot de passe. * **Autorisation:** Si des informations d'autorisation sont gérées par la base de données SQL, il peut être possible de modifier ces informations à travers l'exploitation réussie d'une vulnérabilité d'injection SQL. * **Intégrité:** Tout comme il peut être possible de lire des informations sensibles, il est également possible d'apporter des modifications ou même supprimer ces informations par une attaque d'injection SQL. L'injection SQL est devenu un problème commun à la plus part des sites Web pilotés par des bases de données. La faille est facilement détectée, et facilement exploitable, chaque site ou logiciel, même avec une base minimale, est susceptible de faire l'objet d'une tentative d'attaque de ce genre. Essentiellement, l'attaque se fait en plaçant un caractère méta dans l'entrée des données pour ensuite placer des commandes SQL, qui n'existait pas auparavant. Ce problème est dû au fait que SQL ne fait pas de distinction réelle entre la commande et la structure des données. # Exemples # ## Exemple 1 ## Si la la requête SQL: select id, firstname, lastname from authors fournit : Firstname: evil'ex Lastname: Newman la requête suivante: select id, firstname, lastname from authors where forename = 'evil'ex' and surname ='newman' Retourne (en raison de ' dans le nom evil'ex) Incorrect syntax near il' as the database tried to execute evil. Une version sécurisée de la déclaration SQL ci-dessus peut être codé en Java: String firstname = req.getParameter("firstname"); String lastname = req.getParameter("lastname"); // FIXME: do your own validation to detect attacks String query = "SELECT id, firstname, lastname FROM authors WHERE forename = ? and surname = ?"; PreparedStatement pstmt = connection.prepareStatement( query ); pstmt.setString( 1, firstname ); pstmt.setString( 2, lastname ); try { ResultSet results = pstmt.execute( ); } ## Exemple 2 : ## Construction dynamique en code C # et l'exécution d'une requête SQL qui recherche des éléments correspondant à un nom spécifié. Cette requête limite les éléments affichés à ceux où le propriétaire correspond au nom de l'utilisateur actuellement authentifié. ... string userName = ctx.getAuthenticatedUserName(); string query = "SELECT * FROM items WHERE owner = "'" + userName + "' AND itemname = '" + ItemName.Text + "'"; sda = new SqlDataAdapter(query, conn); DataTable dt = new DataTable(); sda.Fill(dt); ... La requête que ce code a l'intention d'exécuter serait :: SELECT * FROM items WHERE owner = AND itemname = ; Cependant, parce que la requête est construite dynamiquement en concaténant une chaîne de requête de base constante et une chaîne d'entrée utilisateur, la requête ne se comportera correctement que si itemName ne contient pas un caractère guillemet simple. Si un attaquant avec le nom d'utilisateur wiley entre la chaîne "nom" OU 'a' = 'a "pour itemName, la requête devient la suivante: SELECT * FROM items WHERE owner = 'hacker' AND itemname = 'name'; DELETE FROM items; SELECT * FROM items WHERE 'a'='a'; L'ajout de la condition 'a' = 'a' dans la clause where équivaut à toujours évaluer la réponse à tru. Cette requête est logiquement équivalente à la requête beaucoup plus simple: SELECT * FROM items; Cette requête permet à l'attaquant de contourner l'exigence de ne renvoyer que les articles appartenant à l'utilisateur authentifié, la requête renvoie désormais toutes les entrées de la table des éléments, quel que soit leur propriétaire spécifié. ## Exemple 3 ## Cet exemple étudie les effets d'une valeur malveillante transmise à la requête construite et exécutée dans l'exemple 1. Si un attaquant saisit la chaîne de "hacker'); DELETE FROM items; --" la requête devient les deux requêtes suivantes: SELECT * FROM items WHERE owner = 'hacker' AND itemname = 'name'; DELETE FROM items; --' De nombreux serveurs de bases de données , y compris Microsoft SQL Server ® 2000, permettent que plusieurs instructions SQL séparées par des points-virgules puissent être exécutée. Bien que pour les serveurs de bases de données ORACLE et les serveurs de base de données qui ne permettent pas le lot, il en résulte une erreur, ce type d'attaque permet à l'attaquant d'exécuter des commandes arbitraires contre la base de données . Notez la présence en arrière de la requête du double traits d'union (-), qui précise à la plupart des serveurs de bases de données que le reste de l'instruction doit être traité comme un commentaire et non exécutés. Dans ce cas, le caractère de commentaire sert à éliminer l'échappement par guillemet simple du restant de la requête modifiée. Dans une base de données où les commentaires ne sont pas autorisés à être utilisés de cette manière, l'attaque générale pourraient encore être cependant efficace en utilisant un truc similaire à celui présenté dans l'exemple 1. Si un attaquant insère dans la chaîne "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a", les trois requètes suivantes seront créées: SELECT * FROM items WHERE owner = 'hacker' AND itemname = 'name'; DELETE FROM items; SELECT * FROM items WHERE 'a'='a'; Une approche traditionnelle de la prévention des attaques par injection SQL consiste à les traiter comme un problème de validation d'entrée et d'accepter uniquement des caractères à partir d'une liste blanche des valeurs sûres ou d'identifier et d'échapper une liste noire des valeurs potentiellement malveillants. La liste blanche peut être un moyen très efficace de faire respecter des règles strictes de validation d'entrée, les instructions SQL paramétrées nécessitent moins d'entretien et peuvent offrir plus de garanties en matière de sécurité. Comme c'est presque toujours le cas, la liste noire est criblée de failles qui rendent inefficaces dans la prévention des attaques par injection SQL. Par exemple, les attaquants peuvent: * Utiliser des domaines cibles qui ne sont pas recensés * Trouver des façons de contourner le besoin d'échappé certains méta-caractères * Utiliser des procédures stockées pour cacher les méta-caractères injectés Échapper manuellement les caractères à l'entrée des requêtes SQL peut aider, mais il ne mettra pas l'application à l'abri des attaques par injection SQL. Une autre solution souvent proposée pour faire face aux attaques par injection SQL consiste à utiliser des procédures stockées. Bien que les procédures stockées empêchent certains types d'attaques par injection SQL, elles ne protègent pas contre les autres. Par exemple la procédure PL / SQL qui suit est vulnérable à l'attaque par injection SQL montrée dans le premier exemple. procedure get_item ( itm_cv IN OUT ItmCurTyp, usr in varchar2, itm in varchar2) is open itm_cv for ' SELECT * FROM items WHERE ' || 'owner = '''|| usr || ' AND itemname = ''' || itm || ''''; end get_item; Les procédures stockées aident généralement à prévenir les attaques par injection SQL en limitant les types de déclarations qui peuvent être transmis à leurs paramètres. Cependant, il existe de nombreuses façons de contourner les limitations et de nombreuses déclarations intéressantes qui peuvent encore être transmises à des procédures stockées. Encore une fois, les procédures stockées peuvent empêcher certains exploits, mais elles ne feront pas que l'application soit sécurisée contre les attaques par injection SQL.