Logo Parasoft Rechercher

Découvrez GoogleTest certifié TÜV avec Agentic AI pour les tests C/C++ !
Plus de détails »

Blog Parasoft

Comment empêcher l'injection SQL

By Arthur Hicken • 4 août 2020 • 10 min de lecture
4 août 2020 | 10 min de lecture
By Arthur Hicken
Comment empêcher l'injection SQL

L'injection SQL peut affecter la robustesse et les couches de sécurité de votre logiciel si elle n'est pas détectée et arrêtée tôt. Lisez la suite pour savoir comment l'injection SQL peut affecter votre logiciel et découvrez notre approche de la gestion de l'injection SQL.

L'injection SQL ( Structured Query Language ) est une faille de sécurité logicielle bien connue, voire l'une des plus connues. Malgré sa réputation, la prévention des injections SQL demeure une préoccupation majeure, et les attaques continuent de se multiplier.

Recherche d'injections SQL

Les vulnérabilités par injection (dont les injections SQL font partie) constituent le principal problème de sécurité des applications web selon le Top 10 de l'OWASP . Les injections SQL occupent la sixième place du Top 25 des CWE . Voici d'autres exemples de vulnérabilités de sécurité similaires :

  • Injection de commande (CWE-77)
  • Injection de commande du système d'exploitation (CWE-78)
  • Injection Hibernate (CWE-564)
  • Injection de langage d'expression (CWE-917)

Toutes ces vulnérabilités partagent un attribut commun. Ils sont exploités en utilisant des données extérieures au système, des entrées d'utilisateur ou de fichier, ou quoi que ce soit, dans des fonctions potentiellement dangereuses.

Tests continus pour DevOps : évoluer au-delà de la simple automatisation
Obtenez le livre blanc

Heureusement, les injections SQL sont détectables par des outils à la fois statiquement et dynamiquement. Cependant, vous ne pouvez jamais être sûr de les avoir tous attrapés. La prévention des injections SQL est également essentielle pour réduire la fréquence et l'impact de ces vulnérabilités. Un processus DevSecOps mature qui intègre la détection et la prévention des vulnérabilités est susceptible de détecter et d'empêcher ces types de vulnérabilités de pénétrer dans un produit commercialisé.

Qu'est-ce que SQL?

SQL est un langage spécifique conçu pour la gestion des bases de données relationnelles. Ces bases de données présentent les données sous forme d'un ensemble de tables en lignes et en colonnes. Chaque ligne possède une clé qui établit la relation avec les autres tables. Voici un exemple de table « utilisateur » :

[tableau "1" introuvable /]

SQL est le langage de référence pour la gestion, l'interrogation et la manipulation des données dans une base de données relationnelle. Il définit les tables et les relations lors de la création de la base de données. Au quotidien, les développeurs utilisent SQL pour la création, la lecture, la mise à jour et la suppression de données.

Pourquoi SQL est-il exploitable?

Les langages de programmation généraux n'incluent pas la prise en charge de SQL. L'accès aux commandes de la base de données se fait via une API fournie par le fournisseur de la base de données. Dans de nombreux cas, les commandes SQL sont envoyées sous forme de chaînes que l'API interprète et applique à la base de données. Voici quelques requêtes SQL simples:

Une requête SQL typique prend la forme suivante:

Select (something) from (somewhere) (optional condition)

En utilisant les tables ci-dessus comme exemple pour récupérer l'e-mail de la ligne où le nom de famille est « Smith », l'instruction SQL suivante est utilisée :

Select email from user where lastname = ‘Smith’

Le résultat serait le suivant:

[email protected]
[email protected]
[email protected]

La collecte des données des utilisateurs via un formulaire web (voir ci-dessous) est un cas d'utilisation courant dans les applications web. Les données saisies par les utilisateurs dans le champ « Nom », par exemple, sont utilisées pour générer des requêtes SQL basées sur les données reçues. Prenons le formulaire web simple suivant :

Formulaire Web simple

Le logiciel traite le formulaire et attribue les valeurs aux variables quelque chose comme ceci:

String formName = request.getParameter(Name);

La chaîne saisie comme « Nom » est utilisée pour assembler la requête à l'aide de cette entrée utilisateur :

String myQuery = "select message from user where email = ‘" + formName +"’;"

En utilisant cette requête construite:

Select message from user where email= ‘[email protected]’;

La sortie de ceci (en utilisant le tableau ci-dessus comme exemple) est la suivante:

Hello
How are you

Espérons qu'il est facile de voir comment tout cela peut mal tourner. Étant donné l'utilisation de l'entrée utilisateur directement dans la chaîne, quelqu'un qui comprend la syntaxe SQL peut facilement la manipuler pour générer la requête SQL. Prenons l'exemple suivant:

En utilisant le même formulaire ci-dessus, quelqu'un entre « [email protected] » ou « 1 » = « 1 » dans le champ e-mail.

Le même code assemblera la chaîne de requête SQL suivante:

Select message from user where email = ‘[email protected]’ or ‘1’=’1’;

L'ajout d'un élément apparemment anodin, comme « ou 1=1 », modifie la logique de la requête et risque de provoquer une fuite de données en renvoyant toutes les lignes de la table appelée « utilisateur ». Dans ce cas, les messages de chaque utilisateur de la table s'affichent. Il s'agit d'un grave problème de confidentialité et, dans certaines juridictions ou contextes, d'un problème juridique potentiel, notamment en vertu du RGPD, de la loi HIPAA ou du CCPA.

La requête ci-dessus se termine par la sortie inattendue suivante:

Hello
Password 1234
How are you
Don’t tell anyone
Wassup

Comment fonctionne une injection SQL

Le principe de base d'une injection SQL (et d'autres types de vulnérabilités d'injection) est l'utilisation de données non vérifiées provenant de l'extérieur de l'application, telles que du texte saisi par l'utilisateur, dans une chaîne de requête SQL. La description de la CWE 89 : « Neutralisation incorrecte d'éléments spéciaux utilisés dans une commande SQL (« Injection SQL ») » définit ce principe plus précisément :

Sans suppression ou citation suffisante de la syntaxe SQL dans les entrées contrôlables par l'utilisateur, la requête SQL générée peut entraîner l'interprétation de ces entrées comme du code SQL plutôt que comme des données utilisateur ordinaires. Cela peut permettre de modifier la logique de la requête afin de contourner les contrôles de sécurité ou d'insérer des instructions supplémentaires modifiant la base de données principale, y compris l'exécution de commandes système.

La même entrée dans la base de données CWE (CWE 89) fournit un autre exemple simple de cette attaque. Supposons que l'application effectue une requête pour le compte de l'utilisateur « wiley » et que celui-ci construise une entrée contenant des instructions SQL, par exemple :

name'; DELETE FROM items; --

Si cette application n'effectue aucune vérification de validité sur cette entrée, elle construit une requête comme celle-ci:

SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name';
DELETE FROM items;
--'

Si cette attaque réussit, elle supprime toutes les données des éléments de la table, perturbant ainsi la base de données. Toute commande SQL valide pourrait être exécutée de cette manière. Il s'agit d'une attaque en écriture/modification visant à corrompre la base de données ou à insérer des informations indésirables. L'exemple précédent (« ou 1=1 ») est une attaque en lecture visant à la fuite de données.

De nombreuses implémentations de serveurs de bases de données acceptent le point-virgule comme séparateur de commandes, ce qui rend ces injections SQL dangereuses. Le « – » final signale que le reste du texte est un commentaire, obligeant l'interpréteur SQL à ignorer le guillemet final, ce qui entraînerait une erreur de syntaxe. Il existe de nombreuses façons de tromper la chaîne de requête assemblée, parfois de manières inimaginables pour les développeurs.

Atténuations pour se protéger contre les injections SQL

Il existe plusieurs mesures d'atténuation que les développeurs devraient implémenter. En premier lieu, la position de sécurité doit prendre en compte toutes les données provenant de l'extérieur de l'application qui ne sont pas approuvées. Voici des stratégies d'atténuation typiques:

  • Utilisez des instructions préparées avec des requêtes paramétrées.
  • Utilisez des procédures stockées.
  • Validation d'entrée de la liste blanche.
  • Échappez à toutes les entrées fournies.

Ces éléments sont décrits plus en détail dans le guide OWASP sur les injections SQL.

Test des injections SQL

Une approche typique de la sécurité consiste à effectuer divers types de tests de sécurité dans le cadre des opérations régulières d'assurance qualité lorsque le logiciel intégré est en cours d'exécution. Malheureusement, les tests fonctionnels n'essaient pas d'insérer des exploits dans les champs de saisie utilisateur car la plupart des testeurs ne pensent pas comme de mauvais acteurs.

Outre le fait qu'ils n'ont traditionnellement ni le temps ni la direction pour le faire. Il est également difficile de tester manuellement les vulnérabilités de type injection car cela nécessite d'essayer de nombreuses combinaisons d'entrées différentes. C'est là qu'intervient le test de fuzzing ou de fuzz. Il crée des données aléatoires, inattendues et invalides en tant qu'entrées de l'application testée. Les tests Fuzz font partie des tests d'intrusion car l'objectif est d'exposer les vulnérabilités de sécurité via les interfaces exposées.

Tests de pénétration

Les tests de pénétration (et par extension, les tests fuzz) sont bénéfiques car ils peuvent découvrir des problèmes de sécurité qui se sont glissés dans le processus et révéler des problèmes de sécurité importants. Cependant, comme tous les tests dynamiques, cela dépend de la quantité de test, de code et de couverture d'API pour tester complètement toutes les permutations et combinaisons possibles. Les tests de pénétration dépendent de la rigueur des tests fonctionnels, généralement effectués au niveau de l'interface utilisateur. Il est donc important de soutenir vos efforts de test d'intrusion avec des tests API et SAST pour vous assurer que vous êtes minutieux.

Test d'API

Les tests d'API aident à déplacer vers la gauche les tests fonctionnels et de sécurité en supprimant la dépendance aux tests d'interface utilisateur fragiles et chronophages. La couche API est l'endroit où une grande partie des fonctionnalités de l'application réside et les tests sont plus résilients au changement à ce niveau et plus faciles à automatiser et à maintenir.

Test de pénétration au niveau de l'API

Il est possible de réaliser des tests d'intrusion au niveau de l'API pour détecter les injections SQL grâce à des outils comme Parasoft SOAtest. Ces outils génèrent des tests de fuzzing automatisés à partir de tests fonctionnels existants afin de tester la logique métier de l'application. Parasoft SOAtest s'intègre à Burp Suite , un outil de test d'intrusion reconnu.

Lors de l'exécution de scénarios de test fonctionnel avec Parasoft SOAtest, les appels d'API définis dans le test sont capturés avec le trafic de demande et de réponse. L'outil d'analyse Burp Suite sur chaque test transmettra les données de trafic à une instance en cours d'exécution distincte de l'application Burp Suite, qui effectuera des tests de pénétration sur l'API en fonction des paramètres d'API qu'elle observe dans les données de trafic, en utilisant sa propre heuristique.

L'outil d'analyse Burp Suite prendra alors toutes les erreurs trouvées par Burp Suite et les signalera comme des erreurs dans SOAtest, associées au test qui a accédé à l'API. Les résultats de Parasoft SOAtest sont rapportés dans le tableau de bord de reporting et d'analyse de Parasoft. Pour des fonctionnalités de reporting supplémentaires.

Pour en savoir plus sur cette intégration, consultez notre article précédent sur les tests d'intrusion. Pour plus d'informations de Portswigger sur l'utilisation de Burp pour les injections SQL, consultez leur article . Voici une représentation du fonctionnement de cette intégration avec Burp :

Empêcher les injections SQL à l'aide de Burp et Parasoft DTP

L'intégration de ce type de test de pénétration dans votre processus CI / CD est une partie importante de la défense contre les injections SQL et d'autres types de vulnérabilités.

La pénétration et le fuzzing sont certainement un processus important et critique dans DevSecOps. Cependant, cela pose des questions.

  • Que se passe-t-il lorsque les tests détectent des vulnérabilités de sécurité?
  • Que se passe-t-il lorsqu'une équipe logicielle découvre qu'une grande partie de la gestion des entrées utilisateur n'est pas sécurisée?
  • Il doit certainement être réparé, mais à quel prix?

La découverte de problèmes de sécurité graves à ce stade avancé du développement entraîne des coûts et des retards importants. La prévention et la détection sont essentielles pour déplacer les opérations de sécurité plus vers la gauche, là où elles sont moins chères et plus faciles à réparer.

Décaler la détection et l'élimination des injections SQL vers la gauche

Adopter une approche DevSecOps pour le développement logiciel implique d'intégrer la sécurité à tous les aspects du pipeline DevOps. De même que les équipes mettent en œuvre des processus qualité tels que l'analyse de code et les tests unitaires le plus tôt possible dans le cycle de vie du développement logiciel, il en va de même pour la sécurité.

Les injections SQL pourraient appartenir au passé si les équipes adoptaient cette approche plus largement. La montée des attaques signifie que cela ne se produit pas encore. Quoi qu'il en soit, décrivons une approche pour empêcher les injections SQL le plus tôt possible.

Détecter et corriger les injections SQL potentielles (et autres vulnérabilités d'injection) est bien plus rentable que de simplement corriger (et de présenter des excuses !) une application déjà publiée. Un seul incident majeur peut coûter aux entreprises 200 000 $ ou plus. De nombreux incidents de ce type touchent les petites entreprises. Une seule attaque peut engendrer de graves difficultés financières, sans parler des problèmes réglementaires potentiels liés à la divulgation des violations de données et à la protection des informations personnelles.

L'approche de détection et de prévention décrite ci-dessous est basée sur le passage à gauche de l'atténuation des injections SQL aux premiers stades de développement et sur le renforcement de cela avec la détection via l'analyse de code statique.

Comment détecter les injections SQL

La détection des injections SQL repose sur l'analyse statique pour trouver ces types de vulnérabilités dans le code source. La détection se produit sur le bureau du développeur et dans le système de construction. Il peut inclure du code existant, hérité et tiers.

La détection continue des problèmes de sécurité garantit la détection de tous les problèmes qui:

  • Les développeurs ont raté l'IDE.
  • Existe dans un code antérieur à votre nouvelle approche de détection et de prévention.
Intégration continue et livraison continue pour les systèmes embarqués
Télécharger Whitepaper

L'approche recommandée est un modèle de confiance mais de vérification. L'analyse de sécurité se produit au niveau de l'EDI où les développeurs prennent des décisions en temps réel en fonction des rapports qu'ils reçoivent. Ensuite, vérifiez au niveau de la construction. Idéalement, l'objectif au niveau de la construction n'est pas de trouver des vulnérabilités. C'est pour vérifier que le système est propre.

Prenons l'exemple de l'application de démonstration de Parasoft, Parabank . Une vulnérabilité potentielle d'injection SQL existe dans le fichier StockDataInserter.java situé dans com.parasoft.parabank.dao.jdbc.internal :

…
final String sql = sb.toString();
rows = (nextId - lastId) / JdbcSequenceDao.OFFSET;
totalRows += rows;
getJdbcTemplate().update(sql);
…

Le rapport généré lors de la compilation par Parasoft Jtest est le suivant :

Recherche d'injections SQL: rapport Parasoft Jtest

Dans le détail se trouve l'avertissement suivant:

Call to a dangerous method
StockDataInserter.java (96): getJdbcTemplate().update(sql); *** Tainted data: SQL

Avec un suivi vers un point précédent où se trouvent les données corrompues à la source (décocher, entrée non validée de l'extérieur de l'application):

Tainting point
StockDataInserter.java (47): return getJdbcTemplate().query(SQL, new 
ResultSetExtractor<List<String>>() { *** Tainted data: 
getJdbcTemplate().query(SQL, new ResultSetExtractor<List<Str...return 
symbols; } })

Dans la bataille en cours contre les injections SQL, les développeurs doivent prendre ces avertissements au sérieux. Toute utilisation de données non validées dans les requêtes SQL est un risque sérieux. Même si un avertissement spécifique peut ne pas être un problème dans la forme actuelle, il est possible qu'une refactorisation ultérieure puisse exposer ces vulnérabilités. Vérifiez toutes les données utilisées dans les chaînes de requête!

En fait, les développeurs devraient valider toutes les données externes à l'application afin de garantir leur conformité au format et au contenu attendus. Adopter une philosophie de « validation systématique » et un processus reposant sur un codage sécurisé plutôt que sur des tests de sécurité renforce considérablement la sécurité de votre application. Commencez par renforcer le code pour prévenir les injections SQL.

Quand et comment empêcher l'injection SQL

Le moment et le lieu idéaux pour empêcher les injections SQL sont lorsque les développeurs écrivent du code dans leur IDE. Les équipes qui adoptent des normes de codage sécurisé telles que SEI CERT C pour C et C ++ et OWASP Top 10 pour Java et .NET ou CWE Top 25, ont toutes des directives qui avertissent des entrées non validées dans les requêtes SQL.

L'exécution d'une analyse statique sur du code nouvellement créé est rapide et simple et s'intègre facilement dans le processus CI / CD. Il est recommandé d'enquêter sur les avertissements de sécurité et les pratiques de codage non sécurisées à ce stade pour empêcher ce code de pénétrer dans la construction.

Utiliser l'analyse de code statique pour empêcher les injections SQL

Un autre aspect essentiel de la détection des mauvaises pratiques de codage réside dans l'utilité des rapports. Il est important de comprendre la cause profonde des violations d'analyse statique afin de les corriger rapidement et efficacement. C'est là que des outils commerciaux tels que C/C++test de Parasoft , dotTEST et Jtest se révèlent particulièrement performants.

Les outils de test automatisés de Parasoft donnent des traces complètes des avertissements, les illustrent dans l'EDI et collectent en permanence des informations de construction et d'autres informations. Ces données collectées ainsi que les résultats des tests et les mesures fournissent une vue complète de la conformité avec la norme de codage de l'équipe. Il montre également l'état général de la qualité et de la sécurité.

Les rapports incluent les modèles de risque qui font partie des informations fournies par OWASP, CERT et CWE. De cette façon, les développeurs comprennent mieux l'impact des vulnérabilités potentielles signalées par l'outil et lesquelles de ces vulnérabilités à prioriser. Toutes les données générées au niveau IDE sont en corrélation avec les activités en aval décrites ci-dessus.

Résumé

La fameuse vulnérabilité d'injection SQL continue de sévir dans les applications web. Malgré la connaissance de son fonctionnement et de ses méthodes d'exploitation, elle reste très répandue. Consultez le Panthéon de la honte de l'IoT pour des exemples récents.

Nous proposons une approche de prévention et de détection pour compléter les tests de sécurité actifs. Cette approche empêche les injections SQL le plus tôt possible dans le SDLC - avant d'écrire dans le code. Empêcher les injections SQL au niveau de l'EDI et les détecter dans le pipeline CI / CD est essentiel pour les acheminer hors de votre logiciel. Enfin, recherchez et corrigez ces bogues lors des tests à l'aide de techniques de test d'intrusion.

La bataille contre les injections SQL (ainsi que d'autres exploits de données corrompues) continue. Les équipes intelligentes peuvent inverser la tendance avec le bon processus, les bons outils et l'automatisation dans leurs flux de travail existants.

La valeur commerciale des logiciels sécurisés
Obtenez le livre blanc