
Tests de sécurité intégrés dans les flux de travail de développement et de test
Intégration des tests de sécurité dans les workflows de développement (tests unitaires) et de test (tests d'intégration et tests opérationnels). Rôles des développeurs et des testeurs fonctionnels.
Tests de sécurité dans le flux de travail de développement
Les tests de sécurité pendant la phase de développement du SDLC représentent la première occasion pour les développeurs de s'assurer que les composants logiciels individuels qu'ils ont développés sont testés en matière de sécurité avant d'être intégrés à d'autres composants ou intégrés à l'application. Les composants logiciels peuvent consister en des artefacts logiciels tels que des fonctions, des méthodes et des classes, ainsi que des interfaces de programmation d'application, des bibliothèques et des fichiers exécutables. Pour les tests de sécurité, les développeurs peuvent s'appuyer sur les résultats de l'analyse du code source pour vérifier statiquement que le code source développé n'inclut pas de vulnérabilités potentielles et qu'il est conforme aux normes de codage sécurisé. Les tests unitaires de sécurité peuvent en outre vérifier dynamiquement (c'est-à-dire au moment de l'exécution) que les composants fonctionnent comme prévu. Avant d'intégrer les modifications de code nouvelles et existantes dans la version de l'application, les résultats de l'analyse statique et dynamique doivent être examinés et validés.
La validation du code source avant l'intégration dans les versions d'application est généralement la responsabilité du développeur principal. Les développeurs principaux sont souvent les experts en matière de sécurité logicielle et leur rôle est de diriger la revue de code sécurisé. Ils doivent décider s'ils acceptent le code à publier dans la version de l'application ou s'ils exigent des modifications et des tests supplémentaires. Ce flux de travail de revue de code sécurisé peut être appliqué via une acceptation formelle, ainsi qu'une vérification dans un outil de gestion de flux de travail. Par exemple, en supposant le flux de travail typique de gestion des défauts utilisé pour les bogues fonctionnels, les bogues de sécurité qui ont été corrigés par un développeur peuvent être signalés sur un système de gestion des défauts ou des modifications. Le responsable de la construction peut alors examiner les résultats des tests signalés par les développeurs dans l'outil et accorder des approbations pour l'enregistrement des modifications de code dans la construction de l'application.
Tests de sécurité dans le flux de travail de test
Une fois que les composants et les modifications de code sont testés par les développeurs et enregistrés dans la construction de l'application, l'étape suivante la plus probable dans le flux de travail du processus de développement logiciel consiste à effectuer des tests sur l'application dans son ensemble. Ce niveau de test est généralement appelé test intégré et test au niveau du système. Lorsque les tests de sécurité font partie de ces activités de test, ils peuvent être utilisés pour valider à la fois la fonctionnalité de sécurité de l'application dans son ensemble, ainsi que l'exposition aux vulnérabilités au niveau de l'application. Ces tests de sécurité sur l'application incluent à la fois des tests en boîte blanche, tels que l'analyse du code source, et des tests en boîte noire, tels que les tests d'intrusion. Les tests peuvent également inclure des tests en boîte grise, dans lesquels il est supposé que le testeur a une connaissance partielle de l'application. Par exemple, avec une certaine connaissance de la gestion des sessions de l'application, le testeur peut mieux comprendre si les fonctions de déconnexion et de temporisation sont correctement sécurisées.
La cible des tests de sécurité est le système complet qui est vulnérable aux attaques. Au cours de cette phase, il est possible pour les testeurs de sécurité de déterminer si les vulnérabilités peuvent être exploitées. Celles-ci incluent les vulnérabilités courantes des applications web, ainsi que les problèmes de sécurité qui ont été identifiés plus tôt dans le SDLC avec d'autres activités telles que la modélisation des menaces, l'analyse du code source et les revues de code sécurisé.
Habituellement, les ingénieurs de test, plutôt que les développeurs de logiciels, effectuent des tests de sécurité lorsque l'application est dans le champ d'application des tests d'intégration du système. Les ingénieurs de test ont une connaissance de la sécurité des vulnérabilités des applications web, des techniques de test en boîte noire et en boîte blanche, et sont responsables de la validation des exigences de sécurité dans cette phase. Afin d'effectuer des tests de sécurité, il est nécessaire que les cas de test de sécurité soient documentés dans les directives et procédures de test de sécurité.
Un ingénieur de test qui valide la sécurité de l'application dans l'environnement système intégré peut autoriser l'application à être testée dans l'environnement opérationnel (par exemple, les tests d'acceptation par l'utilisateur). A ce stade du SDLC (c'est-à-dire la validation), les tests fonctionnels de l'application sont généralement la responsabilité des testeurs d'assurance qualité, tandis que les pirates informatiques éthiques ou les consultants en sécurité sont généralement responsables des tests de sécurité. Certaines organisations s'appuient sur leur propre équipe de piratage éthique spécialisée pour effectuer de tels tests lorsqu'une évaluation par un tiers n'est pas requise (par exemple, à des fins d'audit).
Etant donné que ces tests peuvent parfois constituer la dernière ligne de défense pour corriger les vulnérabilités avant que l'application ne soit mise en production, il est important que les problèmes soient résolus comme recommandé par l'équipe de test. Les recommandations peuvent inclure des modifications de code, de conception ou de configuration. A ce niveau, les auditeurs de sécurité et les responsables de la sécurité de l'information discutent des problèmes de sécurité signalés et analysent les risques potentiels conformément aux procédures de gestion des risques de l'information. De telles procédures peuvent exiger de l'équipe de développement qu'elle corrige toutes les vulnérabilités à haut risque avant que l'application ne puisse être déployée, à moins que ces risques ne soient reconnus et acceptés.
Tests de sécurité du développeur
Tests de sécurité dans la phase de codage : tests unitaires
Du point de vue du développeur, l'objectif principal des tests de sécurité est de valider que le code est développé conformément aux exigences des normes de codage sécurisé. Les artefacts de codage propres aux développeurs (tels que les fonctions, les méthodes, les classes, les API et les bibliothèques) doivent être validés fonctionnellement avant d'être intégrés dans la construction de l'application.
Les exigences de sécurité que les développeurs doivent suivre doivent être documentées dans des normes de codage sécurisé et validées par une analyse statique et dynamique. Si l'activité de test unitaire suit une revue de code sécurisé, les tests unitaires peuvent valider que les modifications de code requises par les revues de code sécurisé sont correctement mises en oeuvre. Les revues de code sécurisé et l'analyse du code source à l'aide d'outils d'analyse du code source peuvent aider les développeurs à identifier les problèmes de sécurité dans le code source au fur et à mesure de son développement. En utilisant des tests unitaires et une analyse dynamique (par exemple, le débogage), les développeurs peuvent valider la fonctionnalité de sécurité des composants ainsi que vérifier que les contre-mesures en cours de développement atténuent les risques de sécurité précédemment identifiés grâce à la modélisation des menaces et à l'analyse du code source.
Une bonne pratique pour les développeurs consiste à construire des cas de test de sécurité en tant que suite de tests de sécurité générique qui fait partie du cadre de test unitaire existant. Une suite de tests de sécurité générique pourrait être dérivée de cas d'utilisation et d'utilisation abusive précédemment définis pour tester les fonctions, méthodes et classes de sécurité. Une suite de tests de sécurité générique peut inclure des cas de test de sécurité pour valider les exigences positives et négatives pour les contrôles de sécurité tels que :
- Identité, authentification et contrôle d'accès
- Validation et encodage des entrées
- Cryptage
- Gestion des utilisateurs et des sessions
- Gestion des erreurs et des exceptions
- Audit et journalisation
Les développeurs disposant d'un outil d'analyse du code source intégré à leur IDE, de normes de codage sécurisé et d'un cadre de test unitaire de sécurité peuvent évaluer et vérifier la sécurité des composants logiciels en cours de développement. Des cas de test de sécurité peuvent être exécutés pour identifier les problèmes de sécurité potentiels qui ont des causes profondes dans le code source : outre la validation des entrées et des sorties des paramètres entrant et sortant des composants, ces problèmes incluent les contrôles d'authentification et d'autorisation effectués par le composant, la protection des données au sein du composant, la gestion sécurisée des exceptions et des erreurs, et l'audit et la journalisation sécurisés. Les cadres de test unitaire tels que JUnit, NUnit et CUnit peuvent être adaptés pour vérifier les exigences des tests de sécurité. Dans le cas des tests fonctionnels de sécurité, les tests au niveau de l'unité peuvent tester la fonctionnalité des contrôles de sécurité au niveau des composants logiciels, tels que les fonctions, les méthodes ou les classes. Par exemple, un cas de test pourrait valider la validation des entrées et des sorties (par exemple, l'assainissement des variables) et les vérifications des limites pour les variables en affirmant la fonctionnalité attendue du composant.
Les scénarios de menace identifiés avec les cas d'utilisation et d'utilisation abusive peuvent être utilisés pour documenter les procédures de test des composants logiciels. Dans le cas des composants d'authentification, par exemple, les tests unitaires de sécurité peuvent affirmer la fonctionnalité de définition d'un verrouillage de compte ainsi que le fait que les paramètres d'entrée de l'utilisateur ne peuvent pas être utilisés à mauvais escient pour contourner le verrouillage de compte (par exemple, en définissant le compteur de verrouillage de compte sur un nombre négatif).
Au niveau des composants, les tests unitaires de sécurité peuvent valider les assertions positives ainsi que les assertions négatives, telles que les erreurs et la gestion des exceptions. Les exceptions doivent être interceptées sans laisser le système dans un état non sécurisé, tel qu'un déni de service potentiel causé par des ressources non désallouées (par exemple, des descripteurs de connexion non fermés dans un bloc d'instructions final), ainsi qu'une élévation potentielle de privilèges (par exemple, des privilèges plus élevés acquis avant que l'exception ne soit levée et non rétablis au niveau précédent avant de quitter la fonction). La gestion sécurisée des erreurs peut valider la divulgation potentielle d'informations via des messages d'erreur informatifs et des traces de pile.
Les cas de test de sécurité au niveau de l'unité peuvent être développés par un ingénieur de sécurité qui est l'expert en matière de sécurité logicielle et qui est également responsable de la validation du fait que les problèmes de sécurité dans le code source ont été corrigés et peuvent être enregistrés dans la construction du système intégré. En règle générale, le gestionnaire des constructions d'applications s'assure également que les bibliothèques tierces et les fichiers exécutables sont évalués en matière de sécurité pour les vulnérabilités potentielles avant d'être intégrés dans la construction de l'application.
Les scénarios de menace pour les vulnérabilités courantes qui ont des causes profondes dans un codage non sécurisé peuvent également être documentés dans le guide de test de sécurité du développeur. Lorsqu'un correctif est mis en oeuvre pour un défaut de codage identifié avec l'analyse du code source, par exemple, les cas de test de sécurité peuvent vérifier que la mise en oeuvre de la modification du code suit les exigences de codage sécurisé documentées dans les normes de codage sécurisé.
L'analyse du code source et les tests unitaires peuvent valider que la modification du code atténue la vulnérabilité exposée par le défaut de codage précédemment identifié. Les résultats de l'analyse automatisée du code sécurisé peuvent également être utilisés comme portes d'enregistrement automatiques pour le contrôle de version, par exemple, les artefacts logiciels ne peuvent pas être enregistrés dans la construction avec des problèmes de codage de gravité élevée ou moyenne.
Tests de sécurité des testeurs fonctionnels
Tests de sécurité pendant la phase d'intégration et de validation : tests système intégrés et tests opérationnels
L'objectif principal des tests système intégrés est de valider le concept de « défense en profondeur », c'est-à-dire que la mise en oeuvre des contrôles de sécurité assure la sécurité à différents niveaux. Par exemple, l'absence de validation des entrées lors de l'appel d'un composant intégré à l'application est souvent un facteur qui peut être testé avec des tests d'intégration.
L'environnement de test du système d'intégration est également le premier environnement où les testeurs peuvent simuler des scénarios d'attaque réels tels qu'ils peuvent être potentiellement exécutés par un utilisateur externe ou interne malveillant de l'application. Les tests de sécurité à ce niveau peuvent valider si les vulnérabilités sont réelles et peuvent être exploitées par des attaquants. Par exemple, une vulnérabilité potentielle trouvée dans le code source peut être considérée comme un risque élevé en raison de l'exposition à des utilisateurs malveillants potentiels, ainsi que de l'impact potentiel (par exemple, l'accès à des informations confidentielles).
Des scénarios d'attaque réels peuvent être testés avec des techniques de test manuelles et des outils de test d'intrusion. Les tests de sécurité de ce type sont également appelés tests de piratage éthique. Du point de vue des tests de sécurité, il s'agit de tests axés sur les risques et qui ont pour objectif de tester l'application dans l'environnement opérationnel. La cible est la version de l'application qui est représentative de la version de l'application en cours de déploiement en production.
L'inclusion de tests de sécurité dans la phase d'intégration et de validation est essentielle pour identifier les vulnérabilités dues à l'intégration de composants, ainsi que pour valider l'exposition de ces vulnérabilités. Les tests de sécurité des applications nécessitent un ensemble de compétences spécialisées, y compris des connaissances en matière de logiciels et de sécurité, qui ne sont pas typiques des ingénieurs de sécurité. Par conséquent, les organisations sont souvent tenues de former leurs développeurs de logiciels aux techniques de piratage éthique et aux procédures et outils d'évaluation de la sécurité. Un scénario réaliste consiste à développer ces ressources en interne et à les documenter dans des guides et procédures de test de sécurité qui tiennent compte des connaissances des développeurs en matière de test de sécurité. Une « fiche ou liste de contrôle des cas de test de sécurité », par exemple, peut fournir des cas de test simples et des vecteurs d'attaque qui peuvent être utilisés par les testeurs pour valider l'exposition à des vulnérabilités courantes telles que l'usurpation d'identité, la divulgation d'informations, les dépassements de tampon, les chaînes de format, l'injection SQL et l'injection XSS, XML, SOAP, les problèmes de canonicalisation, le déni de service et les contrôles de code managé et ActiveX (par exemple, .NET). Une première série de ces tests peut être effectuée manuellement avec une connaissance très basique de la sécurité logicielle.
Le premier objectif des tests de sécurité peut être la validation d'un ensemble d'exigences de sécurité minimales. Ces cas de test de sécurité peuvent consister à forcer manuellement l'application dans des états d'erreur et d'exception et à recueillir des connaissances sur le comportement de l'application. Par exemple, les vulnérabilités d'injection SQL peuvent être testées manuellement en injectant des vecteurs d'attaque par le biais de l'entrée de l'utilisateur et en vérifiant si des exceptions SQL sont renvoyées à l'utilisateur. La preuve d'une erreur d'exception SQL peut être la manifestation d'une vulnérabilité qui peut être exploitée.
Un test de sécurité plus approfondi peut nécessiter la connaissance par le testeur de techniques et d'outils de test spécialisés. Outre l'analyse du code source et les tests d'intrusion, ces techniques incluent, par exemple : l'injection de fautes dans le code source et le code binaire, l'analyse de la propagation des fautes et la couverture du code, les tests de fuzz et l'ingénierie inverse. Le guide de test de sécurité doit fournir des procédures et recommander des outils qui peuvent être utilisés par les testeurs de sécurité pour effectuer ces évaluations de sécurité approfondies.
Le niveau suivant de test de sécurité après les tests système d'intégration consiste à effectuer des tests de sécurité dans l'environnement d'acceptation par l'utilisateur. Il existe des avantages uniques à effectuer des tests de sécurité dans l'environnement opérationnel. L'environnement de test d'acceptation par l'utilisateur (UAT) est celui qui est le plus représentatif de la configuration de la version, à l'exception des données (par exemple, les données de test sont utilisées à la place des données réelles). Une caractéristique des tests de sécurité dans l'UAT est le test des problèmes de configuration de la sécurité. Dans certains cas, ces vulnérabilités peuvent représenter des risques élevés. Par exemple, le serveur qui héberge l'application web peut ne pas être configuré avec des privilèges minimaux, un certificat HTTPS valide et une configuration sécurisée, les services essentiels désactivés et le répertoire racine web nettoyé des pages web de test et d'administration.