Recommandations pour la sécurisation d’un cycle de vie de développement

S’applique à cette recommandation de liste de contrôle azure Well-Architected Framework Security :

SE :02 Maintenez un cycle de vie de développement sécurisé à l’aide d’une chaîne d’approvisionnement logicielle renforcée, principalement automatisée et auditable. Incorporez une conception sécurisée à l’aide de la modélisation des menaces pour vous protéger contre les implémentations de protection contre la sécurité.

Guide connexe : Analyse des menaces

Ce guide décrit les recommandations pour renforcer votre code, votre environnement de développement et votre chaîne d’approvisionnement logicielle en appliquant les meilleures pratiques de sécurité tout au long du cycle de développement. Pour comprendre ces conseils, vous devez avoir connaissance de DevSecOps.

Schéma du cycle de sécurité.

DevSecOps intègre la sécurité dans les processus DevOps par :

  • Automatisation des tests de sécurité et de la validation.

  • Implémentation d’outils tels que des pipelines de sécurité pour analyser le code et l’infrastructure en tant que code (IaC) pour détecter les vulnérabilités.

Au cœur d’une charge de travail est le code d’application qui implémente la logique métier. Le code et le processus de développement du code doivent être exempts de défauts de sécurité pour garantir la confidentialité, l’intégrité et la disponibilité.

Il n’est pas suffisant de sécuriser uniquement le plan d’infrastructure en utilisant des contrôles sur l’identité et la mise en réseau et d’autres mesures. Empêchez l’implémentation incorrecte du code ou un bloc de code compromis pour renforcer votre posture de sécurité globale. Le plan d’utilisation, autrement dit, le code de l’application, doit également être renforcé. Le processus d’intégration de la sécurité dans votre cycle de vie de développement est essentiellement un processus de renforcement. Comme le renforcement des ressources, le renforcement du développement de code est également indépendant du contexte. L’accent est mis sur l’amélioration de la sécurité et non sur les exigences fonctionnelles de l’application. Pour plus d’informations sur le renforcement, consultez Recommandations pour renforcer les ressources.

Définitions

Terme Définition
Security Development Lifecycle (SDL) Ensemble de pratiques fournies par Microsoft qui prennent en charge les exigences de sécurité et de conformité.
Cycle de vie du développement logiciel (SDLC) Processus multisétage et systématique pour le développement de systèmes logiciels.

Stratégies de conception

Les mesures de sécurité doivent être intégrées à plusieurs points dans votre cycle de vie de développement logiciel (SDLC) existant pour vous assurer :

  • Les choix de conception n’entraînent pas de lacunes de sécurité.

  • Le code et la configuration de l’application ne créent pas de vulnérabilités en raison d’une implémentation exploitable et de pratiques de codage incorrectes.

  • Le logiciel acquis via la chaîne d’approvisionnement n’introduit pas de menaces de sécurité.

  • Le code d’application, la génération et les processus de déploiement ne sont pas falsifiés.

  • Les vulnérabilités révélées par les incidents sont atténuées.

  • Les ressources inutilisées sont correctement désaffectées.

  • Les exigences de conformité ne sont pas compromises ou réduites.

  • La journalisation d’audit est implémentée dans les environnements de développement.

Les sections suivantes fournissent des stratégies de sécurité pour les phases couramment pratiquées de SDLC.

Collecter et documenter les exigences de sécurité

L’objectif de la phase des exigences est de collecter et d’analyser les exigences fonctionnelles et non fonctionnelles d’une application ou d’une nouvelle fonctionnalité d’une application. Cette phase est importante, car elle facilite la création de garde-fous adaptés aux objectifs de l’application. La protection des données et de l’intégrité de votre application doit être une exigence essentielle tout au long de chaque phase du cycle de vie du développement.

Par exemple, considérez une application qui doit prendre en charge les flux utilisateur critiques qui permettent à l’utilisateur de charger et de manipuler des données. Les choix de conception de sécurité doivent couvrir les garanties d’interaction de l’utilisateur avec l’application, telles que l’authentification et l’autorisation de l’identité de l’utilisateur, l’autorisation uniquement des actions autorisées sur les données et la prévention de l’injection SQL. De même, couvrez les exigences non fonctionnelles telles que la disponibilité, la scalabilité et la maintenance. Les choix de sécurité doivent inclure les limites de segmentation, l’entrée et la sortie du pare-feu, ainsi que d’autres préoccupations de sécurité croisées.

Toutes ces décisions doivent conduire à une bonne définition de la posture de sécurité de l’application. Documentez les exigences de sécurité dans une spécification acceptée et reflètez-la dans le backlog. Il doit explicitement indiquer les investissements de sécurité et les compromis et risques que l’entreprise est disposé à prendre si les investissements ne sont pas approuvés par les parties prenantes de l’entreprise. Par exemple, vous pouvez documenter la nécessité d’utiliser un pare-feu d’applications web (WAF) devant votre application, comme Azure Front Door ou Azure Application Gateway. Si les parties prenantes de l’entreprise ne sont pas prêtes à accepter le coût supplémentaire d’exécution d’un WAF, elles doivent accepter le risque que les attaques de couche application puissent être dirigées vers l’application.

La collecte des exigences de sécurité est une partie essentielle de cette phase. Sans cet effort, les phases de conception et d’implémentation sont basées sur des choix non établis, ce qui peut entraîner des lacunes de sécurité. Vous devrez peut-être modifier l’implémentation ultérieurement pour prendre en charge la sécurité, ce qui peut être coûteux.

Traduire les exigences de sécurité en exigences techniques

Pendant la phase de conception, les exigences de sécurité sont converties en exigences techniques. Dans votre spécification technique, documentez toutes les décisions de conception pour empêcher l’ambiguïté pendant l’implémentation. Voici quelques tâches classiques :

Définir la dimension de sécurité de l’architecture système

Superposez l’architecture avec des contrôles de sécurité. Par exemple, les contrôles pratiques sur les limites d’isolation par votre stratégie de segmentation, les types d’identités nécessaires aux composants de l’application et le type de méthodes de chiffrement à utiliser. Pour obtenir des exemples d’architectures, consultez les illustrations des sections Exemples d’articles sur la gestion des identités et les accès et la mise en réseau.

Évaluer les affordances fournies par la plateforme

Il est important de comprendre la division de responsabilité entre vous et le fournisseur de cloud. Évitez de chevaucher les contrôles de sécurité natifs Azure, par exemple. Vous bénéficiez d’une meilleure couverture de sécurité et vous serez en mesure de réallouer les ressources de développement aux besoins de l’application.

Par exemple, si votre conception appelle un pare-feu d’applications web en entrée, vous pouvez décharger cette responsabilité à un équilibreur de charge comme Application Gateway ou Azure Front Door. Évitez de répliquer des fonctionnalités en tant que code personnalisé dans votre application.

Choisissez uniquement les infrastructures, bibliothèques et logiciels de chaîne logistique approuvés. Votre conception doit également spécifier le contrôle de version sécurisé. Les dépendances d’application doivent être sources à partir de parties approuvées. Les fournisseurs tiers doivent être en mesure de répondre à vos exigences de sécurité et de partager leur plan de divulgation responsable. Tout incident de sécurité doit être signalé rapidement afin que vous puissiez effectuer les actions nécessaires. En outre, certaines bibliothèques peuvent être interdites par votre organisation. Par exemple, les logiciels peuvent être sécurisés contre les vulnérabilités, mais ils ne sont toujours pas autorisés en raison de restrictions de licence.

Pour vous assurer que ces conseils sont suivis par tous les contributeurs au logiciel, conservez une liste de frameworks, bibliothèques et fournisseurs approuvés et/ou non approuvés. Si possible, placez des garde-fous dans les pipelines de développement pour prendre en charge la liste. Autant que possible, automatisez l’utilisation d’outils pour analyser les dépendances pour détecter les vulnérabilités.

Déterminez les modèles de conception de sécurité que le code de l’application doit implémenter.

Les modèles peuvent prendre en charge les problèmes de sécurité tels que la segmentation et l’isolation, l’autorisation forte, la sécurité uniforme des applications et les protocoles modernes. Certains modèles opérationnels, tels que le modèle de quarantaine, peuvent aider à vérifier et bloquer l’utilisation de logiciels susceptibles d’introduire des vulnérabilités de sécurité.

Pour plus d’informations, consultez les modèles de conception cloud qui prennent en charge la sécurité.

Stocker les secrets d’application en toute sécurité

Implémentez en toute sécurité l’utilisation des secrets d’application et des clés pré-partagées utilisées par votre application. Les informations d’identification et les secrets d’application ne doivent jamais être stockés dans l’arborescence du code source. Utilisez des ressources externes comme Azure Key Vault pour vous assurer que, si votre code source devient disponible pour un attaquant potentiel, aucun autre accès ne peut être obtenu. En général, trouvez des moyens d’éviter les secrets. L’utilisation d’identités managées, si possible, est un moyen d’atteindre cet objectif. Pour plus d’informations, consultez Recommandations pour la gestion des secrets d’application.

Définir des plans de test

Définissez des cas de test clairs pour les exigences de sécurité. Déterminez si vous pouvez automatiser ces tests dans vos pipelines. Si votre équipe a des processus de test manuel, incluez les exigences de sécurité pour ces tests.

Remarque

Effectuez une modélisation des menaces pendant cette phase. La modélisation des menaces peut confirmer que les choix de conception sont alignés sur les exigences de sécurité et exposent les lacunes que vous devez atténuer. Si votre charge de travail gère des données hautement sensibles, investissez dans des experts en sécurité qui peuvent vous aider à effectuer une modélisation des menaces.

L’exercice initial de modélisation des menaces doit se produire pendant la phase de conception lorsque l’architecture du logiciel et la conception de haut niveau sont définies. Le faire pendant cette phase vous permet d’identifier les problèmes de sécurité potentiels avant qu’ils ne soient incorporés dans la structure du système. Toutefois, cet exercice n’est pas une activité ponctuelle. Il s’agit d’un processus continu qui devrait continuer tout au long de l’évolution du logiciel.

Pour plus d’informations, consultez Recommandations pour l’analyse des menaces.

Sécuriser les pratiques de développement et de test

Pendant la phase de développement et de test, l’objectif est d’éviter les défauts de sécurité et la falsification dans le code, la génération et les pipelines de déploiement.

Être bien formé dans les pratiques de code sécurisées

L’équipe de développement doit avoir une formation formelle et spécialisée dans les pratiques de codage sécurisées. Par exemple, les développeurs web et API peuvent avoir besoin d’une formation spécifique pour se protéger contre les attaques de script intersites, et les développeurs principaux peuvent bénéficier d’une formation approfondie pour éviter les attaques au niveau de la base de données telles que les attaques par injection SQL.

Les développeurs doivent être tenus de suivre cette formation avant de pouvoir accéder au code source de production.

Vous devez également effectuer des révisions internes de code homologue pour promouvoir l’apprentissage continu.

Utiliser les outils de test de sécurité

Effectuez une modélisation des menaces pour évaluer la sécurité de l’architecture de l’application.

Utilisez des tests de sécurité d’application statiques (SAST) pour analyser le code pour les vulnérabilités. Intégrez cette méthodologie dans l’environnement de développement pour détecter les vulnérabilités en temps réel.

Utilisez des tests de sécurité des applications dynamiques (DAST) pendant l’exécution. Cette chaîne d’outils peut vérifier les erreurs dans les domaines de sécurité et simuler un ensemble d’attaques pour tester la résilience de sécurité de l’application. Si possible, intégrez cet outil dans vos pipelines de build.

Suivez les normes du secteur pour sécuriser les pratiques de codage. Pour plus d’informations, consultez la section Ressources de la communauté de cet article.

Utilisez des linters et des analyseurs de code pour empêcher les informations d’identification d’être envoyées au référentiel de code source. Par exemple, les analyseurs de la plateforme de compilateur .NET (Roslyn) inspectent le code de votre application.

Pendant le processus de génération, utilisez les modules complémentaires de pipeline pour intercepter les informations d’identification dans le code source. Analysez toutes les dépendances, telles que les bibliothèques tierces et les composants d’infrastructure, dans le cadre du processus d’intégration continue. Examinez les composants vulnérables signalés par l’outil. Associez cette tâche à d’autres tâches d’analyse de code qui inspectent l’attrition du code, les résultats des tests et la couverture.

Utilisez une combinaison de tests. Pour plus d’informations sur les tests de sécurité en général, consultez Recommandations pour les tests de sécurité.

Écrire suffisamment de code

Lorsque vous réduisez votre empreinte de code, vous réduisez également les risques de défauts de sécurité. Réutilisez du code et des bibliothèques déjà utilisées et qui ont été effectuées via des validations de sécurité au lieu de dupliquer du code.

Tirer parti des fonctionnalités Azure est un autre moyen d’éviter le code inutile. L’une des façons consiste à utiliser des services managés. Pour plus d’informations, consultez Utiliser les options PaaS (Platform as a Service).

Écrivez du code avec une approche deny-all par défaut. Créez des listes d’autorisation uniquement pour les entités qui ont besoin d’un accès. Par exemple, si vous avez du code qui doit déterminer si une opération privilégiée doit être autorisée, vous devez l’écrire afin que le résultat de refus soit le cas par défaut et que le résultat d’autorisation se produise uniquement lorsqu’il est spécifiquement autorisé par le code.

Protéger les environnements de développement

Les stations de travail des développeurs doivent être protégées avec des contrôles réseau et d’identité forts pour empêcher l’exposition. Assurez-vous que les mises à jour de sécurité sont appliquées avec diligence.

Les agents de build sont hautement privilégiés et ont accès au serveur de build et au code. Ils doivent être protégés avec la même rigueur que vos composants de charge de travail. Cela signifie que l’accès aux agents de build doit être authentifié et autorisé, qu’ils doivent être segmentés sur le réseau avec des contrôles de pare-feu, qu’ils doivent être soumis à l’analyse des vulnérabilités, et ainsi de suite. Les agents de build hébergés par Microsoft doivent être préférés aux agents de build auto-hébergés. Les agents hébergés par Microsoft offrent des avantages tels que des machines virtuelles propres pour chaque exécution d’un pipeline.

Les agents de build personnalisés ajoutent une complexité de gestion et peuvent devenir des vecteurs d’attaque. Les informations d’identification de la machine de génération doivent être stockées en toute sécurité et vous devez supprimer régulièrement les artefacts de build temporaires du système de fichiers. Vous pouvez obtenir une isolation réseau en autorisant uniquement le trafic sortant de l’agent de build, car il utilise le modèle d’extraction de communication avec Azure DevOps.

Le référentiel de code source doit également être protégé . Accordez l’accès aux référentiels de code en fonction du besoin et réduisez l’exposition des vulnérabilités autant que possible pour éviter les attaques. Effectuez un processus approfondi pour examiner le code pour connaître les vulnérabilités de sécurité. Utilisez des groupes de sécurité à cet effet et implémentez un processus d’approbation basé sur des justifications métier.

Protéger le code dans les pipelines de déploiement

Il n’est pas suffisant de sécuriser le code. S’il s’exécute dans des pipelines exploitables, tous les efforts de sécurité sont futiles et incomplets. Les environnements de génération et de mise en production doivent également être protégés , car vous souhaitez empêcher les acteurs malveillants d’exécuter du code malveillant dans votre pipeline.

Maintenir un inventaire à jour de chaque composant intégré à votre application

Chaque nouveau composant intégré à une application augmente la surface d’attaque. Pour garantir une responsabilité et une alerte appropriées lorsque de nouveaux composants sont ajoutés ou mis à jour, vous devez disposer d’un inventaire de ces composants. Stockez-le en dehors de l’environnement de build. Vérifiez régulièrement que votre manifeste correspond à ce qui se trouve dans votre processus de génération. Cela permet de s’assurer qu’aucun nouveau composant contenant des portes arrière ou d’autres programmes malveillants ne sont ajoutés de manière inattendue.

Tâches de pipeline

  • Extrayez des tâches dans votre pipeline à partir de sources approuvées, comme Place de marché Azure. Exécutez des tâches écrites par votre fournisseur de pipeline. Nous vous recommandons des tâches GitHub ou GitHub Actions. Si vous utilisez des flux de travail GitHub, préférez les tâches créées par Microsoft. Validez également les tâches, car elles s’exécutent dans le contexte de sécurité de votre pipeline.

  • Secrets de pipeline. Les ressources de déploiement qui s’exécutent à l’intérieur d’un pipeline ont accès à tous les secrets de ce pipeline. Disposer d’une segmentation appropriée pour différentes étapes du pipeline afin d’éviter toute exposition inutile. Utilisez des magasins de secrets intégrés au pipeline. N’oubliez pas que vous pouvez éviter d’utiliser des secrets dans certaines situations. Explorez l’utilisation des identités de charge de travail (pour l’authentification de pipeline) et des identités managées (pour l’authentification de service à service).

Séparer les différents environnements

Les données utilisées dans différents environnements doivent être conservées séparément. Les données de production ne doivent pas être utilisées dans des environnements inférieurs , car ces environnements peuvent ne pas avoir les contrôles de sécurité stricts dont dispose la production. Évitez de vous connecter d’une application hors production à une base de données de production et évitez de connecter des composants hors production à des réseaux de production.

Exposition progressive

Utilisez une exposition progressive aux fonctionnalités de mise en production pour un sous-ensemble d’utilisateurs en fonction des critères choisis. En cas de problème, l’impact est réduit pour ces utilisateurs. Cette approche est une stratégie courante d’atténuation des risques, car elle réduit la surface d’exposition. À mesure que la fonctionnalité mûrit et que vous avez plus de confiance dans les garanties de sécurité, vous pouvez la libérer progressivement sur un ensemble plus large d’utilisateurs.

Protéger le code en production

La phase de production présente la dernière occasion responsable de corriger les lacunes de sécurité. Conservez un enregistrement de l’image d’or publiée en production.

Conserver les artefacts avec version

Conservez un catalogue de toutes les ressources déployées et de leurs versions. Ces informations sont utiles pendant le triage des incidents, lorsque vous atténuez les problèmes et lorsque vous revenez au système en état de fonctionnement. Les ressources avec version peuvent également être comparées aux avis publiés sur les vulnérabilités et les expositions courantes (CVE). Vous devez utiliser l’automatisation pour effectuer ces comparaisons.

Correctifs d’urgence

Votre conception de pipeline automatisée doit avoir la flexibilité nécessaire pour prendre en charge les déploiements réguliers et d’urgence. Cette flexibilité est importante pour prendre en charge les correctifs de sécurité rapides et responsables.

Une version est généralement associée à plusieurs portes d’approbation. Envisagez de créer un processus d’urgence pour accélérer les correctifs de sécurité. Le processus peut impliquer la communication entre les équipes. Le pipeline doit permettre des déploiements de restauration rapide et de restauration qui traitent des correctifs de sécurité, des bogues critiques et des mises à jour de code qui se produisent en dehors du cycle de vie de déploiement normal.

Remarque

Hiérarchisez toujours les correctifs de sécurité par rapport à la commodité. Un correctif de sécurité ne doit pas introduire de régression ou de bogue. Si vous souhaitez accélérer le correctif via un pipeline d’urgence, envisagez soigneusement les tests automatisés qui peuvent être contournés. Évaluez la valeur de chaque test par rapport à la durée d’exécution. Par exemple, les tests unitaires se terminent généralement rapidement. Les tests d’intégration ou les tests de bout en bout peuvent s’exécuter pendant une longue période.

Maintenir la sécurité du code tout au long de son cycle de vie

L’objectif de cette phase est de s’assurer que la posture de sécurité ne se décompose pas au fil du temps. SDLC est un processus agile en cours. Les concepts abordés dans les phases précédentes s’appliquent à cette phase, car les exigences changent au fil du temps.

Gestion des correctifs. Conservez les logiciels, les bibliothèques et les composants d’infrastructure à jour avec les correctifs et mises à jour de sécurité.

Amélioration continue. Évaluez et améliorez en permanence la sécurité du processus de développement de logiciels en tenant compte des révisions de code, des commentaires, des leçons apprises et des menaces en constante évolution.

Désaffectez les ressources héritées obsolètes ou ne sont plus utilisées. Cela réduit la surface d’exposition de l’application.

La maintenance inclut également des correctifs d’incident. Si des problèmes sont détectés en production, ils doivent être intégrés rapidement au processus afin qu’ils ne se répètent pas.

Améliorez continuellement vos pratiques de codage sécurisées pour suivre le paysage des menaces.

Facilitation Azure

Microsoft Security Development Lifecycle (SDL) recommande des pratiques sécurisées que vous pouvez appliquer à votre cycle de vie de développement. Pour plus d’informations, consultez Cycle de vie du développement de la sécurité Microsoft.

Defender pour DevOps et les outils SAST sont inclus dans le cadre de GitHub Advanced Security ou d’Azure DevOps. Ces outils peuvent vous aider à suivre un score de sécurité pour votre organisation.

Suivez les recommandations de sécurité Azure décrites dans ces ressources :

Pour rechercher des informations d’identification dans le code source, envisagez d’utiliser des outils tels que GitHub Advanced Security et les outils d’analyse du code source OWASP.

Validez la sécurité de tout code open source dans votre application. Ces outils et ressources gratuits peuvent vous aider à effectuer votre évaluation :

Liste de contrôle de sécurité

Reportez-vous à l’ensemble complet de recommandations.