Blog

Les codeurs conquièrent la sécurité : Partager et apprendre - Injection SQL

Jaap Karan Singh
Publié le 06 décembre 2018

En termes simples, SQL (ou Structured Query Language) est le langage utilisé pour communiquer avec les bases de données relationnelles ; c'est le langage de requête utilisé par les développeurs, les administrateurs de bases de données et les applications pour gérer les quantités massives de données générées chaque jour.

Nos données deviennent rapidement l'une des marchandises les plus précieuses au monde... et lorsque quelque chose a de la valeur, les malfaiteurs veulent mettre la main dessus pour en tirer profit.

Les attaquants utilisent l'injection SQL, l'une des vulnérabilités les plus anciennes(depuis 1998!) et les plus ennuyeuses, pour voler et modifier les informations sensibles disponibles dans des millions de bases de données à travers le monde. C'est insidieux, et les développeurs doivent comprendre l'injection SQL (ainsi que la manière de s'en défendre) si nous voulons garder nos données en sécurité.

À cette fin, nous allons aborder trois aspects clés de l'injection SQL :

  • Comment cela fonctionne-t-il ?
  • Pourquoi c'est si dangereux
  • Comment s'en défendre ?

Comprendre l'injection SQL

L'injection SQL peut être comprise à l'aide d'un seul mot : le contexte.

Au sein d'une application, il existe deux contextes : l'un pour les données, l'autre pour le code. Le contexte du code indique à l'ordinateur ce qu'il doit exécuter et le sépare des données à traiter.

L'injection SQL se produit lorsqu'un attaquant saisit des données qui sont traitées par erreur comme du code par l'interpréteur SQL.

Un exemple est un champ de saisie sur un site web, où un pirate saisit "'' OR 1=1" et qui est ajouté à la fin d'une requête SQL. Lorsque cette requête est exécutée, elle renvoie "true" pour chaque ligne de la base de données. Cela signifie que tous les enregistrements de la table interrogée seront renvoyés.

Les conséquences d'une injection SQL peuvent être catastrophiques. Si elle se produit sur une page de connexion, elle peut renvoyer tous les enregistrements des utilisateurs, y compris éventuellement les noms d'utilisateur et les mots de passe. Si une simple requête visant à extraire des données est couronnée de succès, les requêtes visant à modifier les données le seront également.

Jetons un coup d'œil à un code vulnérable afin que vous puissiez voir à quoi ressemble une vulnérabilité par injection de code SQL en chair et en os.

Consultez ce code :

String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
   Statement statement = connection.createStatement( ... );
   ResultSet results = statement.executeQuery( query );
}

Le code ici ajoute simplement les informations des paramètres du client à la fin de la requête SQL sans aucune validation. Dans ce cas, un attaquant peut saisir du code dans un champ de saisie ou dans les paramètres d'une URL et l'exécuter.

L'essentiel n'est pas que les attaquants puissent seulement ajouter ''' OR 1=1" à chaque requête SELECT, mais qu'ils puissent manipuler n'importe quel type de requête SQL (INSERT, UPDATE, DELETE, DROP, etc.) et l'étendre à tout ce que la base de données supporte. Il existe d'excellentes ressources et des outils disponibles dans le domaine public qui montrent ce qu'il est possible de faire.

Nous verrons bientôt comment remédier à ce problème. Tout d'abord, il convient de comprendre l'ampleur des dégâts.

Pourquoi l'injection SQL est-elle si dangereuse ?

Voici trois exemples de failles causées par une injection SQL :

  • Le site web de la commission électorale de l'Illinois a fait l'objet d'une violation en raison de vulnérabilités liées à une injection SQL. Les attaquants ont volé les données personnelles de 200 000 citoyens américains. En raison de la nature de la vulnérabilité découverte, les attaquants auraient pu également modifier les données, mais ils ne l'ont pas fait.
  • Hetzner, une société sud-africaine d'hébergement de sites web, a été victime d'une violation de 40 000 enregistrements de clients. Une faille d'injection SQL a permis le vol de tous les enregistrements de clients dans leur base de données.
  • Un prestataire de services financiers catholiques du Minnesota, aux États-Unis, a été victime d'une intrusion par injection SQL. Les informations relatives aux comptes, y compris les numéros de compte, de près de 130 000 clients ont été dérobées.

Les données sensibles peuvent être utilisées pour prendre le contrôle de comptes, réinitialiser des mots de passe, voler de l'argent ou commettre des fraudes.

Même les informations qui ne sont pas considérées comme sensibles ou personnellement identifiables peuvent être utilisées pour d'autres attaques. L'adresse ou les quatre derniers chiffres de votre numéro d'identification gouvernemental peuvent être utilisés pour usurper votre identité auprès d'entreprises ou pour réinitialiser votre mot de passe.

Lorsqu'une attaque réussit, les clients peuvent perdre confiance en l'entreprise. La réparation des dommages causés aux systèmes ou des amendes réglementaires peut coûter des millions de dollars.

Mais il n'est pas nécessaire que cela se termine ainsi pour vous.

Vaincre l'injection SQL

L'injection SQL peut être évitée en étiquetant clairement les parties de votre application, de sorte que l'ordinateur sache si une partie donnée est une donnée ou un code à exécuter. Pour ce faire, vous pouvez utiliser des requêtes paramétrées.

Lorsque les requêtes SQL utilisent des paramètres, l'interpréteur SQL utilise le paramètre uniquement en tant que données. Il ne l'exécute pas en tant que code.

Par exemple, une attaque telle que "'' OR 1=1" ne fonctionnera pas. La base de données recherchera la chaîne "OR 1=1" et ne la trouvera pas dans la base de données. Elle se contentera de hausser les épaules et de dire : "Désolé, je ne peux pas trouver ça pour vous".

Voici un exemple de requête paramétrée en Java :

La plupart des cadres de développement fournissent des défenses intégrées contre l'injection SQL.

Les ORM (Object Relational Mappers), tels qu'Entity Framework dans la famille .NET, paramétrent les requêtes par défaut. Cela permet de se prémunir contre les injections SQL sans aucun effort de votre part.

Cependant, vous devez savoir comment fonctionne votre ORM spécifique. Par exemple, Hibernate, un ORM populaire dans le monde Java, peut toujours être vulnérable à l'injection SQL s'il est utilisé de manière incorrecte.

Le paramétrage des requêtes est la première et la meilleure défense, mais il en existe d'autres. Les procédures stockées prennent également en charge les paramètres SQL et peuvent être utilisées pour prévenir les injections SQL. Gardez à l'esprit que les procédures stockées doivent également être construites correctement pour que cela fonctionne.

// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";

PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );

Validez et assainissez toujours vos entrées. Étant donné que certains caractères, tels que "OR 1=1", ne seront pas saisis par un utilisateur légitime de votre application, il n'est pas nécessaire de les autoriser. Vous pouvez afficher un message d'erreur à l'utilisateur ou les supprimer de vos entrées avant de les traiter.

Cela dit, ne comptez pas uniquement sur la validation et l'assainissement pour vous protéger. Des êtres humains astucieux ont trouvé des moyens de les contourner. Ce sont de bonnes stratégies de défense en profondeur (DiD), mais le paramétrage est le moyen le plus sûr de couvrir toutes les bases.

Une autre bonne stratégie DiD consiste à utiliser le "moindre privilège" au sein de la base de données et à établir une liste blanche des entrées. L'application du principe du moindre privilège signifie que votre application ne dispose pas d'un pouvoir illimité au sein de la base de données. Si un attaquant parvient à accéder à la base de données, les dommages qu'il peut causer sont limités.

L'OWASP dispose d'une excellente feuille de contrôle sur l'injection SQL qui montre comment gérer cette vulnérabilité dans plusieurs langues et plateformes... mais si vous voulez aller plus loin, vous pouvez dès maintenant jouer à un défi d'injection SQL dans votre langue préférée sur notre plateforme ; voici quelques-unes des plus populaires pour commencer :

Injection SQL en C#

Injection SQL dans Node.js

Injection SQL dans Python Django

Injection SQL en Java Spring

Le voyage commence

Vous avez fait de grands progrès dans la compréhension de l'injection SQL et des étapes nécessaires pour la corriger. C'est génial !

Nous avons vu comment se produit l'injection SQL, généralement lorsqu'un pirate utilise des données d'entrée pour contrôler les requêtes de votre base de données à des fins malveillantes.

Nous avons également constaté les dégâts causés par l'exploitation des failles d'injection SQL : Des comptes peuvent être compromis et des millions de dollars perdus... un cauchemar, qui plus est coûteux.

Nous avons vu comment prévenir les injections SQL :

  • Paramétrage des requêtes
  • Utilisation de mappeurs objet-relationnel et de procédures stockées
  • Validation et inscription sur liste blanche des données saisies par les utilisateurs

Maintenant, c'est à vous de jouer. La pratique est le meilleur moyen de continuer à apprendre et d'acquérir de la maîtrise, alors pourquoi ne pas jeter un coup d'œil à nos Ressources pédagogiques sur l'injection SQL, puis essayez notre démo gratuite de la plateforme ? Vous serez sur la bonne voie pour devenir un Secure Code Warrior.

Voir la ressource
Voir la ressource

Les attaquants utilisent l'injection SQL - l'une des vulnérabilités les plus anciennes (depuis 1998 !) et les plus ennuyeuses - pour voler et modifier les informations sensibles disponibles dans des millions de bases de données à travers le monde.

Vous souhaitez en savoir plus ?

Jaap Karan Singh est un évangéliste du codage sécurisé, Chief Singh et cofondateur de Secure Code Warrior.

Secure Code Warrior est là pour vous aider à sécuriser le code tout au long du cycle de vie du développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Réservez une démonstration
Partager sur :
Auteur
Jaap Karan Singh
Publié le 06 décembre 2018

Jaap Karan Singh est un évangéliste du codage sécurisé, Chief Singh et cofondateur de Secure Code Warrior.

Partager sur :

En termes simples, SQL (ou Structured Query Language) est le langage utilisé pour communiquer avec les bases de données relationnelles ; c'est le langage de requête utilisé par les développeurs, les administrateurs de bases de données et les applications pour gérer les quantités massives de données générées chaque jour.

Nos données deviennent rapidement l'une des marchandises les plus précieuses au monde... et lorsque quelque chose a de la valeur, les malfaiteurs veulent mettre la main dessus pour en tirer profit.

Les attaquants utilisent l'injection SQL, l'une des vulnérabilités les plus anciennes(depuis 1998!) et les plus ennuyeuses, pour voler et modifier les informations sensibles disponibles dans des millions de bases de données à travers le monde. C'est insidieux, et les développeurs doivent comprendre l'injection SQL (ainsi que la manière de s'en défendre) si nous voulons garder nos données en sécurité.

À cette fin, nous allons aborder trois aspects clés de l'injection SQL :

  • Comment cela fonctionne-t-il ?
  • Pourquoi c'est si dangereux
  • Comment s'en défendre ?

Comprendre l'injection SQL

L'injection SQL peut être comprise à l'aide d'un seul mot : le contexte.

Au sein d'une application, il existe deux contextes : l'un pour les données, l'autre pour le code. Le contexte du code indique à l'ordinateur ce qu'il doit exécuter et le sépare des données à traiter.

L'injection SQL se produit lorsqu'un attaquant saisit des données qui sont traitées par erreur comme du code par l'interpréteur SQL.

Un exemple est un champ de saisie sur un site web, où un pirate saisit "'' OR 1=1" et qui est ajouté à la fin d'une requête SQL. Lorsque cette requête est exécutée, elle renvoie "true" pour chaque ligne de la base de données. Cela signifie que tous les enregistrements de la table interrogée seront renvoyés.

Les conséquences d'une injection SQL peuvent être catastrophiques. Si elle se produit sur une page de connexion, elle peut renvoyer tous les enregistrements des utilisateurs, y compris éventuellement les noms d'utilisateur et les mots de passe. Si une simple requête visant à extraire des données est couronnée de succès, les requêtes visant à modifier les données le seront également.

Jetons un coup d'œil à un code vulnérable afin que vous puissiez voir à quoi ressemble une vulnérabilité par injection de code SQL en chair et en os.

Consultez ce code :

String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
   Statement statement = connection.createStatement( ... );
   ResultSet results = statement.executeQuery( query );
}

Le code ici ajoute simplement les informations des paramètres du client à la fin de la requête SQL sans aucune validation. Dans ce cas, un attaquant peut saisir du code dans un champ de saisie ou dans les paramètres d'une URL et l'exécuter.

L'essentiel n'est pas que les attaquants puissent seulement ajouter ''' OR 1=1" à chaque requête SELECT, mais qu'ils puissent manipuler n'importe quel type de requête SQL (INSERT, UPDATE, DELETE, DROP, etc.) et l'étendre à tout ce que la base de données supporte. Il existe d'excellentes ressources et des outils disponibles dans le domaine public qui montrent ce qu'il est possible de faire.

Nous verrons bientôt comment remédier à ce problème. Tout d'abord, il convient de comprendre l'ampleur des dégâts.

Pourquoi l'injection SQL est-elle si dangereuse ?

Voici trois exemples de failles causées par une injection SQL :

  • Le site web de la commission électorale de l'Illinois a fait l'objet d'une violation en raison de vulnérabilités liées à une injection SQL. Les attaquants ont volé les données personnelles de 200 000 citoyens américains. En raison de la nature de la vulnérabilité découverte, les attaquants auraient pu également modifier les données, mais ils ne l'ont pas fait.
  • Hetzner, une société sud-africaine d'hébergement de sites web, a été victime d'une violation de 40 000 enregistrements de clients. Une faille d'injection SQL a permis le vol de tous les enregistrements de clients dans leur base de données.
  • Un prestataire de services financiers catholiques du Minnesota, aux États-Unis, a été victime d'une intrusion par injection SQL. Les informations relatives aux comptes, y compris les numéros de compte, de près de 130 000 clients ont été dérobées.

Les données sensibles peuvent être utilisées pour prendre le contrôle de comptes, réinitialiser des mots de passe, voler de l'argent ou commettre des fraudes.

Même les informations qui ne sont pas considérées comme sensibles ou personnellement identifiables peuvent être utilisées pour d'autres attaques. L'adresse ou les quatre derniers chiffres de votre numéro d'identification gouvernemental peuvent être utilisés pour usurper votre identité auprès d'entreprises ou pour réinitialiser votre mot de passe.

Lorsqu'une attaque réussit, les clients peuvent perdre confiance en l'entreprise. La réparation des dommages causés aux systèmes ou des amendes réglementaires peut coûter des millions de dollars.

Mais il n'est pas nécessaire que cela se termine ainsi pour vous.

Vaincre l'injection SQL

L'injection SQL peut être évitée en étiquetant clairement les parties de votre application, de sorte que l'ordinateur sache si une partie donnée est une donnée ou un code à exécuter. Pour ce faire, vous pouvez utiliser des requêtes paramétrées.

Lorsque les requêtes SQL utilisent des paramètres, l'interpréteur SQL utilise le paramètre uniquement en tant que données. Il ne l'exécute pas en tant que code.

Par exemple, une attaque telle que "'' OR 1=1" ne fonctionnera pas. La base de données recherchera la chaîne "OR 1=1" et ne la trouvera pas dans la base de données. Elle se contentera de hausser les épaules et de dire : "Désolé, je ne peux pas trouver ça pour vous".

Voici un exemple de requête paramétrée en Java :

La plupart des cadres de développement fournissent des défenses intégrées contre l'injection SQL.

Les ORM (Object Relational Mappers), tels qu'Entity Framework dans la famille .NET, paramétrent les requêtes par défaut. Cela permet de se prémunir contre les injections SQL sans aucun effort de votre part.

Cependant, vous devez savoir comment fonctionne votre ORM spécifique. Par exemple, Hibernate, un ORM populaire dans le monde Java, peut toujours être vulnérable à l'injection SQL s'il est utilisé de manière incorrecte.

Le paramétrage des requêtes est la première et la meilleure défense, mais il en existe d'autres. Les procédures stockées prennent également en charge les paramètres SQL et peuvent être utilisées pour prévenir les injections SQL. Gardez à l'esprit que les procédures stockées doivent également être construites correctement pour que cela fonctionne.

// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";

PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );

Validez et assainissez toujours vos entrées. Étant donné que certains caractères, tels que "OR 1=1", ne seront pas saisis par un utilisateur légitime de votre application, il n'est pas nécessaire de les autoriser. Vous pouvez afficher un message d'erreur à l'utilisateur ou les supprimer de vos entrées avant de les traiter.

Cela dit, ne comptez pas uniquement sur la validation et l'assainissement pour vous protéger. Des êtres humains astucieux ont trouvé des moyens de les contourner. Ce sont de bonnes stratégies de défense en profondeur (DiD), mais le paramétrage est le moyen le plus sûr de couvrir toutes les bases.

Une autre bonne stratégie DiD consiste à utiliser le "moindre privilège" au sein de la base de données et à établir une liste blanche des entrées. L'application du principe du moindre privilège signifie que votre application ne dispose pas d'un pouvoir illimité au sein de la base de données. Si un attaquant parvient à accéder à la base de données, les dommages qu'il peut causer sont limités.

L'OWASP dispose d'une excellente feuille de contrôle sur l'injection SQL qui montre comment gérer cette vulnérabilité dans plusieurs langues et plateformes... mais si vous voulez aller plus loin, vous pouvez dès maintenant jouer à un défi d'injection SQL dans votre langue préférée sur notre plateforme ; voici quelques-unes des plus populaires pour commencer :

Injection SQL en C#

Injection SQL dans Node.js

Injection SQL dans Python Django

Injection SQL en Java Spring

Le voyage commence

Vous avez fait de grands progrès dans la compréhension de l'injection SQL et des étapes nécessaires pour la corriger. C'est génial !

Nous avons vu comment se produit l'injection SQL, généralement lorsqu'un pirate utilise des données d'entrée pour contrôler les requêtes de votre base de données à des fins malveillantes.

Nous avons également constaté les dégâts causés par l'exploitation des failles d'injection SQL : Des comptes peuvent être compromis et des millions de dollars perdus... un cauchemar, qui plus est coûteux.

Nous avons vu comment prévenir les injections SQL :

  • Paramétrage des requêtes
  • Utilisation de mappeurs objet-relationnel et de procédures stockées
  • Validation et inscription sur liste blanche des données saisies par les utilisateurs

Maintenant, c'est à vous de jouer. La pratique est le meilleur moyen de continuer à apprendre et d'acquérir de la maîtrise, alors pourquoi ne pas jeter un coup d'œil à nos Ressources pédagogiques sur l'injection SQL, puis essayez notre démo gratuite de la plateforme ? Vous serez sur la bonne voie pour devenir un Secure Code Warrior.

Voir la ressource
Voir la ressource

Remplissez le formulaire ci-dessous pour télécharger le rapport

Nous aimerions que vous nous autorisiez à vous envoyer des informations sur nos produits et/ou sur des sujets liés au codage sécurisé. Nous traiterons toujours vos données personnelles avec le plus grand soin et ne les vendrons jamais à d'autres entreprises à des fins de marketing.

Soumettre
Pour soumettre le formulaire, veuillez activer les cookies "Analytics". N'hésitez pas à les désactiver à nouveau une fois que vous aurez terminé.

En termes simples, SQL (ou Structured Query Language) est le langage utilisé pour communiquer avec les bases de données relationnelles ; c'est le langage de requête utilisé par les développeurs, les administrateurs de bases de données et les applications pour gérer les quantités massives de données générées chaque jour.

Nos données deviennent rapidement l'une des marchandises les plus précieuses au monde... et lorsque quelque chose a de la valeur, les malfaiteurs veulent mettre la main dessus pour en tirer profit.

Les attaquants utilisent l'injection SQL, l'une des vulnérabilités les plus anciennes(depuis 1998!) et les plus ennuyeuses, pour voler et modifier les informations sensibles disponibles dans des millions de bases de données à travers le monde. C'est insidieux, et les développeurs doivent comprendre l'injection SQL (ainsi que la manière de s'en défendre) si nous voulons garder nos données en sécurité.

À cette fin, nous allons aborder trois aspects clés de l'injection SQL :

  • Comment cela fonctionne-t-il ?
  • Pourquoi c'est si dangereux
  • Comment s'en défendre ?

Comprendre l'injection SQL

L'injection SQL peut être comprise à l'aide d'un seul mot : le contexte.

Au sein d'une application, il existe deux contextes : l'un pour les données, l'autre pour le code. Le contexte du code indique à l'ordinateur ce qu'il doit exécuter et le sépare des données à traiter.

L'injection SQL se produit lorsqu'un attaquant saisit des données qui sont traitées par erreur comme du code par l'interpréteur SQL.

Un exemple est un champ de saisie sur un site web, où un pirate saisit "'' OR 1=1" et qui est ajouté à la fin d'une requête SQL. Lorsque cette requête est exécutée, elle renvoie "true" pour chaque ligne de la base de données. Cela signifie que tous les enregistrements de la table interrogée seront renvoyés.

Les conséquences d'une injection SQL peuvent être catastrophiques. Si elle se produit sur une page de connexion, elle peut renvoyer tous les enregistrements des utilisateurs, y compris éventuellement les noms d'utilisateur et les mots de passe. Si une simple requête visant à extraire des données est couronnée de succès, les requêtes visant à modifier les données le seront également.

Jetons un coup d'œil à un code vulnérable afin que vous puissiez voir à quoi ressemble une vulnérabilité par injection de code SQL en chair et en os.

Consultez ce code :

String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
   Statement statement = connection.createStatement( ... );
   ResultSet results = statement.executeQuery( query );
}

Le code ici ajoute simplement les informations des paramètres du client à la fin de la requête SQL sans aucune validation. Dans ce cas, un attaquant peut saisir du code dans un champ de saisie ou dans les paramètres d'une URL et l'exécuter.

L'essentiel n'est pas que les attaquants puissent seulement ajouter ''' OR 1=1" à chaque requête SELECT, mais qu'ils puissent manipuler n'importe quel type de requête SQL (INSERT, UPDATE, DELETE, DROP, etc.) et l'étendre à tout ce que la base de données supporte. Il existe d'excellentes ressources et des outils disponibles dans le domaine public qui montrent ce qu'il est possible de faire.

Nous verrons bientôt comment remédier à ce problème. Tout d'abord, il convient de comprendre l'ampleur des dégâts.

Pourquoi l'injection SQL est-elle si dangereuse ?

Voici trois exemples de failles causées par une injection SQL :

  • Le site web de la commission électorale de l'Illinois a fait l'objet d'une violation en raison de vulnérabilités liées à une injection SQL. Les attaquants ont volé les données personnelles de 200 000 citoyens américains. En raison de la nature de la vulnérabilité découverte, les attaquants auraient pu également modifier les données, mais ils ne l'ont pas fait.
  • Hetzner, une société sud-africaine d'hébergement de sites web, a été victime d'une violation de 40 000 enregistrements de clients. Une faille d'injection SQL a permis le vol de tous les enregistrements de clients dans leur base de données.
  • Un prestataire de services financiers catholiques du Minnesota, aux États-Unis, a été victime d'une intrusion par injection SQL. Les informations relatives aux comptes, y compris les numéros de compte, de près de 130 000 clients ont été dérobées.

Les données sensibles peuvent être utilisées pour prendre le contrôle de comptes, réinitialiser des mots de passe, voler de l'argent ou commettre des fraudes.

Même les informations qui ne sont pas considérées comme sensibles ou personnellement identifiables peuvent être utilisées pour d'autres attaques. L'adresse ou les quatre derniers chiffres de votre numéro d'identification gouvernemental peuvent être utilisés pour usurper votre identité auprès d'entreprises ou pour réinitialiser votre mot de passe.

Lorsqu'une attaque réussit, les clients peuvent perdre confiance en l'entreprise. La réparation des dommages causés aux systèmes ou des amendes réglementaires peut coûter des millions de dollars.

Mais il n'est pas nécessaire que cela se termine ainsi pour vous.

Vaincre l'injection SQL

L'injection SQL peut être évitée en étiquetant clairement les parties de votre application, de sorte que l'ordinateur sache si une partie donnée est une donnée ou un code à exécuter. Pour ce faire, vous pouvez utiliser des requêtes paramétrées.

Lorsque les requêtes SQL utilisent des paramètres, l'interpréteur SQL utilise le paramètre uniquement en tant que données. Il ne l'exécute pas en tant que code.

Par exemple, une attaque telle que "'' OR 1=1" ne fonctionnera pas. La base de données recherchera la chaîne "OR 1=1" et ne la trouvera pas dans la base de données. Elle se contentera de hausser les épaules et de dire : "Désolé, je ne peux pas trouver ça pour vous".

Voici un exemple de requête paramétrée en Java :

La plupart des cadres de développement fournissent des défenses intégrées contre l'injection SQL.

Les ORM (Object Relational Mappers), tels qu'Entity Framework dans la famille .NET, paramétrent les requêtes par défaut. Cela permet de se prémunir contre les injections SQL sans aucun effort de votre part.

Cependant, vous devez savoir comment fonctionne votre ORM spécifique. Par exemple, Hibernate, un ORM populaire dans le monde Java, peut toujours être vulnérable à l'injection SQL s'il est utilisé de manière incorrecte.

Le paramétrage des requêtes est la première et la meilleure défense, mais il en existe d'autres. Les procédures stockées prennent également en charge les paramètres SQL et peuvent être utilisées pour prévenir les injections SQL. Gardez à l'esprit que les procédures stockées doivent également être construites correctement pour que cela fonctionne.

// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";

PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );

Validez et assainissez toujours vos entrées. Étant donné que certains caractères, tels que "OR 1=1", ne seront pas saisis par un utilisateur légitime de votre application, il n'est pas nécessaire de les autoriser. Vous pouvez afficher un message d'erreur à l'utilisateur ou les supprimer de vos entrées avant de les traiter.

Cela dit, ne comptez pas uniquement sur la validation et l'assainissement pour vous protéger. Des êtres humains astucieux ont trouvé des moyens de les contourner. Ce sont de bonnes stratégies de défense en profondeur (DiD), mais le paramétrage est le moyen le plus sûr de couvrir toutes les bases.

Une autre bonne stratégie DiD consiste à utiliser le "moindre privilège" au sein de la base de données et à établir une liste blanche des entrées. L'application du principe du moindre privilège signifie que votre application ne dispose pas d'un pouvoir illimité au sein de la base de données. Si un attaquant parvient à accéder à la base de données, les dommages qu'il peut causer sont limités.

L'OWASP dispose d'une excellente feuille de contrôle sur l'injection SQL qui montre comment gérer cette vulnérabilité dans plusieurs langues et plateformes... mais si vous voulez aller plus loin, vous pouvez dès maintenant jouer à un défi d'injection SQL dans votre langue préférée sur notre plateforme ; voici quelques-unes des plus populaires pour commencer :

Injection SQL en C#

Injection SQL dans Node.js

Injection SQL dans Python Django

Injection SQL en Java Spring

Le voyage commence

Vous avez fait de grands progrès dans la compréhension de l'injection SQL et des étapes nécessaires pour la corriger. C'est génial !

Nous avons vu comment se produit l'injection SQL, généralement lorsqu'un pirate utilise des données d'entrée pour contrôler les requêtes de votre base de données à des fins malveillantes.

Nous avons également constaté les dégâts causés par l'exploitation des failles d'injection SQL : Des comptes peuvent être compromis et des millions de dollars perdus... un cauchemar, qui plus est coûteux.

Nous avons vu comment prévenir les injections SQL :

  • Paramétrage des requêtes
  • Utilisation de mappeurs objet-relationnel et de procédures stockées
  • Validation et inscription sur liste blanche des données saisies par les utilisateurs

Maintenant, c'est à vous de jouer. La pratique est le meilleur moyen de continuer à apprendre et d'acquérir de la maîtrise, alors pourquoi ne pas jeter un coup d'œil à nos Ressources pédagogiques sur l'injection SQL, puis essayez notre démo gratuite de la plateforme ? Vous serez sur la bonne voie pour devenir un Secure Code Warrior.

Accès aux ressources

Cliquez sur le lien ci-dessous et téléchargez le PDF de cette ressource.

Secure Code Warrior est là pour vous aider à sécuriser le code tout au long du cycle de vie du développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Voir le rapportRéservez une démonstration
Télécharger le PDF
Voir la ressource
Partager sur :
Vous souhaitez en savoir plus ?

Partager sur :
Auteur
Jaap Karan Singh
Publié le 06 décembre 2018

Jaap Karan Singh est un évangéliste du codage sécurisé, Chief Singh et cofondateur de Secure Code Warrior.

Partager sur :

En termes simples, SQL (ou Structured Query Language) est le langage utilisé pour communiquer avec les bases de données relationnelles ; c'est le langage de requête utilisé par les développeurs, les administrateurs de bases de données et les applications pour gérer les quantités massives de données générées chaque jour.

Nos données deviennent rapidement l'une des marchandises les plus précieuses au monde... et lorsque quelque chose a de la valeur, les malfaiteurs veulent mettre la main dessus pour en tirer profit.

Les attaquants utilisent l'injection SQL, l'une des vulnérabilités les plus anciennes(depuis 1998!) et les plus ennuyeuses, pour voler et modifier les informations sensibles disponibles dans des millions de bases de données à travers le monde. C'est insidieux, et les développeurs doivent comprendre l'injection SQL (ainsi que la manière de s'en défendre) si nous voulons garder nos données en sécurité.

À cette fin, nous allons aborder trois aspects clés de l'injection SQL :

  • Comment cela fonctionne-t-il ?
  • Pourquoi c'est si dangereux
  • Comment s'en défendre ?

Comprendre l'injection SQL

L'injection SQL peut être comprise à l'aide d'un seul mot : le contexte.

Au sein d'une application, il existe deux contextes : l'un pour les données, l'autre pour le code. Le contexte du code indique à l'ordinateur ce qu'il doit exécuter et le sépare des données à traiter.

L'injection SQL se produit lorsqu'un attaquant saisit des données qui sont traitées par erreur comme du code par l'interpréteur SQL.

Un exemple est un champ de saisie sur un site web, où un pirate saisit "'' OR 1=1" et qui est ajouté à la fin d'une requête SQL. Lorsque cette requête est exécutée, elle renvoie "true" pour chaque ligne de la base de données. Cela signifie que tous les enregistrements de la table interrogée seront renvoyés.

Les conséquences d'une injection SQL peuvent être catastrophiques. Si elle se produit sur une page de connexion, elle peut renvoyer tous les enregistrements des utilisateurs, y compris éventuellement les noms d'utilisateur et les mots de passe. Si une simple requête visant à extraire des données est couronnée de succès, les requêtes visant à modifier les données le seront également.

Jetons un coup d'œil à un code vulnérable afin que vous puissiez voir à quoi ressemble une vulnérabilité par injection de code SQL en chair et en os.

Consultez ce code :

String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
   Statement statement = connection.createStatement( ... );
   ResultSet results = statement.executeQuery( query );
}

Le code ici ajoute simplement les informations des paramètres du client à la fin de la requête SQL sans aucune validation. Dans ce cas, un attaquant peut saisir du code dans un champ de saisie ou dans les paramètres d'une URL et l'exécuter.

L'essentiel n'est pas que les attaquants puissent seulement ajouter ''' OR 1=1" à chaque requête SELECT, mais qu'ils puissent manipuler n'importe quel type de requête SQL (INSERT, UPDATE, DELETE, DROP, etc.) et l'étendre à tout ce que la base de données supporte. Il existe d'excellentes ressources et des outils disponibles dans le domaine public qui montrent ce qu'il est possible de faire.

Nous verrons bientôt comment remédier à ce problème. Tout d'abord, il convient de comprendre l'ampleur des dégâts.

Pourquoi l'injection SQL est-elle si dangereuse ?

Voici trois exemples de failles causées par une injection SQL :

  • Le site web de la commission électorale de l'Illinois a fait l'objet d'une violation en raison de vulnérabilités liées à une injection SQL. Les attaquants ont volé les données personnelles de 200 000 citoyens américains. En raison de la nature de la vulnérabilité découverte, les attaquants auraient pu également modifier les données, mais ils ne l'ont pas fait.
  • Hetzner, une société sud-africaine d'hébergement de sites web, a été victime d'une violation de 40 000 enregistrements de clients. Une faille d'injection SQL a permis le vol de tous les enregistrements de clients dans leur base de données.
  • Un prestataire de services financiers catholiques du Minnesota, aux États-Unis, a été victime d'une intrusion par injection SQL. Les informations relatives aux comptes, y compris les numéros de compte, de près de 130 000 clients ont été dérobées.

Les données sensibles peuvent être utilisées pour prendre le contrôle de comptes, réinitialiser des mots de passe, voler de l'argent ou commettre des fraudes.

Même les informations qui ne sont pas considérées comme sensibles ou personnellement identifiables peuvent être utilisées pour d'autres attaques. L'adresse ou les quatre derniers chiffres de votre numéro d'identification gouvernemental peuvent être utilisés pour usurper votre identité auprès d'entreprises ou pour réinitialiser votre mot de passe.

Lorsqu'une attaque réussit, les clients peuvent perdre confiance en l'entreprise. La réparation des dommages causés aux systèmes ou des amendes réglementaires peut coûter des millions de dollars.

Mais il n'est pas nécessaire que cela se termine ainsi pour vous.

Vaincre l'injection SQL

L'injection SQL peut être évitée en étiquetant clairement les parties de votre application, de sorte que l'ordinateur sache si une partie donnée est une donnée ou un code à exécuter. Pour ce faire, vous pouvez utiliser des requêtes paramétrées.

Lorsque les requêtes SQL utilisent des paramètres, l'interpréteur SQL utilise le paramètre uniquement en tant que données. Il ne l'exécute pas en tant que code.

Par exemple, une attaque telle que "'' OR 1=1" ne fonctionnera pas. La base de données recherchera la chaîne "OR 1=1" et ne la trouvera pas dans la base de données. Elle se contentera de hausser les épaules et de dire : "Désolé, je ne peux pas trouver ça pour vous".

Voici un exemple de requête paramétrée en Java :

La plupart des cadres de développement fournissent des défenses intégrées contre l'injection SQL.

Les ORM (Object Relational Mappers), tels qu'Entity Framework dans la famille .NET, paramétrent les requêtes par défaut. Cela permet de se prémunir contre les injections SQL sans aucun effort de votre part.

Cependant, vous devez savoir comment fonctionne votre ORM spécifique. Par exemple, Hibernate, un ORM populaire dans le monde Java, peut toujours être vulnérable à l'injection SQL s'il est utilisé de manière incorrecte.

Le paramétrage des requêtes est la première et la meilleure défense, mais il en existe d'autres. Les procédures stockées prennent également en charge les paramètres SQL et peuvent être utilisées pour prévenir les injections SQL. Gardez à l'esprit que les procédures stockées doivent également être construites correctement pour que cela fonctionne.

// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";

PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );

Validez et assainissez toujours vos entrées. Étant donné que certains caractères, tels que "OR 1=1", ne seront pas saisis par un utilisateur légitime de votre application, il n'est pas nécessaire de les autoriser. Vous pouvez afficher un message d'erreur à l'utilisateur ou les supprimer de vos entrées avant de les traiter.

Cela dit, ne comptez pas uniquement sur la validation et l'assainissement pour vous protéger. Des êtres humains astucieux ont trouvé des moyens de les contourner. Ce sont de bonnes stratégies de défense en profondeur (DiD), mais le paramétrage est le moyen le plus sûr de couvrir toutes les bases.

Une autre bonne stratégie DiD consiste à utiliser le "moindre privilège" au sein de la base de données et à établir une liste blanche des entrées. L'application du principe du moindre privilège signifie que votre application ne dispose pas d'un pouvoir illimité au sein de la base de données. Si un attaquant parvient à accéder à la base de données, les dommages qu'il peut causer sont limités.

L'OWASP dispose d'une excellente feuille de contrôle sur l'injection SQL qui montre comment gérer cette vulnérabilité dans plusieurs langues et plateformes... mais si vous voulez aller plus loin, vous pouvez dès maintenant jouer à un défi d'injection SQL dans votre langue préférée sur notre plateforme ; voici quelques-unes des plus populaires pour commencer :

Injection SQL en C#

Injection SQL dans Node.js

Injection SQL dans Python Django

Injection SQL en Java Spring

Le voyage commence

Vous avez fait de grands progrès dans la compréhension de l'injection SQL et des étapes nécessaires pour la corriger. C'est génial !

Nous avons vu comment se produit l'injection SQL, généralement lorsqu'un pirate utilise des données d'entrée pour contrôler les requêtes de votre base de données à des fins malveillantes.

Nous avons également constaté les dégâts causés par l'exploitation des failles d'injection SQL : Des comptes peuvent être compromis et des millions de dollars perdus... un cauchemar, qui plus est coûteux.

Nous avons vu comment prévenir les injections SQL :

  • Paramétrage des requêtes
  • Utilisation de mappeurs objet-relationnel et de procédures stockées
  • Validation et inscription sur liste blanche des données saisies par les utilisateurs

Maintenant, c'est à vous de jouer. La pratique est le meilleur moyen de continuer à apprendre et d'acquérir de la maîtrise, alors pourquoi ne pas jeter un coup d'œil à nos Ressources pédagogiques sur l'injection SQL, puis essayez notre démo gratuite de la plateforme ? Vous serez sur la bonne voie pour devenir un Secure Code Warrior.

Table des matières

Télécharger le PDF
Voir la ressource
Vous souhaitez en savoir plus ?

Jaap Karan Singh est un évangéliste du codage sécurisé, Chief Singh et cofondateur de Secure Code Warrior.

Secure Code Warrior est là pour vous aider à sécuriser le code tout au long du cycle de vie du développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Réservez une démonstrationTélécharger
Partager sur :
Centre de ressources

Ressources pour vous aider à démarrer

Plus d'articles
Centre de ressources

Ressources pour vous aider à démarrer

Plus d'articles