Les codeurs conquièrent la sécurité : Partager et apprendre - Injection SQL
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 dans Python Django
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.
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.
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émonstrationJaap Karan Singh est un évangéliste du codage sécurisé, Chief Singh et cofondateur de Secure Code Warrior.
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 dans Python Django
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.
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 dans Python Django
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.
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émonstrationJaap Karan Singh est un évangéliste du codage sécurisé, Chief Singh et cofondateur de Secure Code Warrior.
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 dans Python Django
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
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échargerRessources pour vous aider à démarrer
Évaluation comparative des compétences en matière de sécurité : Rationalisation de la conception sécurisée dans l'entreprise
Le mouvement "Secure-by-Design" (conception sécurisée) est l'avenir du développement de logiciels sécurisés. Découvrez les éléments clés que les entreprises doivent garder à l'esprit lorsqu'elles envisagent une initiative de conception sécurisée.
DigitalOcean réduit sa dette de sécurité avec Secure Code Warrior
L'utilisation par DigitalOcean de la formation Secure Code Warrior a considérablement réduit la dette de sécurité, permettant aux équipes de se concentrer davantage sur l'innovation et la productivité. L'amélioration de la sécurité a renforcé la qualité des produits et l'avantage concurrentiel de l'entreprise. À l'avenir, le score de confiance SCW les aidera à améliorer leurs pratiques de sécurité et à continuer à stimuler l'innovation.
Ressources pour vous aider à démarrer
La note de confiance révèle la valeur des initiatives d'amélioration de la sécurité par la conception
Nos recherches ont montré que la formation au code sécurisé fonctionne. Le Trust Score, qui utilise un algorithme s'appuyant sur plus de 20 millions de points de données d'apprentissage issus du travail de plus de 250 000 apprenants dans plus de 600 organisations, révèle son efficacité à réduire les vulnérabilités et la manière de rendre l'initiative encore plus efficace.
Sécurité réactive contre sécurité préventive : La prévention est un meilleur remède
L'idée d'apporter une sécurité préventive aux codes et systèmes existants en même temps qu'aux applications plus récentes peut sembler décourageante, mais une approche "Secure-by-Design", mise en œuvre en améliorant les compétences des développeurs, permet d'appliquer les meilleures pratiques de sécurité à ces systèmes. C'est la meilleure chance qu'ont de nombreuses organisations d'améliorer leur sécurité.
Les avantages de l'évaluation des compétences des développeurs en matière de sécurité
L'importance croissante accordée au code sécurisé et aux principes de conception sécurisée exige que les développeurs soient formés à la cybersécurité dès le début du cycle de développement durable, et que des outils tels que le Trust Score de Secure Code Warriorles aident à mesurer et à améliorer leurs progrès.
Assurer le succès des initiatives de conception sécurisée de l'entreprise
Notre dernier document de recherche, Benchmarking Security Skills : Streamlining Secure-by-Design in the Enterprise est le résultat d'une analyse approfondie d'initiatives réelles de conception sécurisée au niveau de l'entreprise, et de l'élaboration d'approches de meilleures pratiques basées sur des conclusions fondées sur des données.