Meilleures pratiques pour une chaîne d’approvisionnement logicielle sécurisée

L’open source est partout. Il se trouve dans de nombreux codebase protégé et de nombreux projets de la communauté. Pour les organisations et les individus, la question aujourd’hui n’est pas de savoir si vous utilisez ou non du code open source, mais de quel code open source vous vous servez, et en quelle quantité.

Si vous n’êtes pas au courant de ce qui se trouve dans votre chaîne d’approvisionnement logicielle, une vulnérabilité en amont située dans l’une de vos dépendances peut être fatale, vous rendant ainsi, vous et vos clients, vulnérables à une potentielle compromission. Dans ce document, nous allons approfondir ce que signifie le terme « chaîne d’approvisionnement logicielle », pourquoi cela est important et de quelle manière vous pouvez aider à sécuriser la chaîne d’approvisionnement de votre projet avec les meilleures pratiques.

The State of the Octoverse 2020 - Open Source

Dépendances

Le terme chaîne d’approvisionnement logicielle est utilisé pour faire référence à tout ce qui va dans votre logiciel et de là où il provient. Il s’agit des dépendances et des propriétés de vos dépendances dont votre chaîne d’approvisionnement logicielle dépend. Une dépendance est ce que votre logiciel doit exécuter. Il peut s’agir de code, de fichiers binaires ou d’autres composants, et de leur provenance, par exemple un référentiel ou un gestionnaire de package.

Elle inclut qui a écrit le code, quand il a été contribué, comment il a été examiné pour les problèmes de sécurité, les vulnérabilités connues, les versions prises en charge, les informations de licence et tout ce qui y touche à tout moment du processus.

Votre chaîne d’approvisionnement englobe également d’autres parties de votre pile au-delà d’une application unique. Il s’agit par exemple de scripts de génération et d’empaquetage ou du logiciel qui exécute l’infrastructure sur laquelle votre application s’appuie.

Vulnerabilities

Aujourd’hui, les dépendances logicielles sont omniprésentes. Il est très courant que vos projets utilisent des centaines de dépendances open source pour les fonctionnalités que vous n’avez pas besoin d’écrire vous-même. Cela peut signifier que vous n’avez pas écrit la majorité du code de votre application vous-même.

The State of the Octoverse 2020 - Dependencies

Les vulnérabilités possibles dans vos dépendances tierces ou open source sont probablement des dépendances que vous ne pouvez pas contrôler aussi étroitement que le code que vous écrivez vous-même. Cela peut créer des risques de sécurité potentiels dans votre chaîne d’approvisionnement.

Si l’une de ces dépendances souffre d’une vulnérabilité, il y a de grandes chances pour que vous en souffriez aussi. Cela peut être effrayant car l’une de vos dépendances peut changer que vous n’en ayez conscience. Même si une vulnérabilité existe dans une dépendance aujourd’hui, mais n’est pas encore exploitable, elle peut être l’être à l’avenir.

La possibilité de tirer profit du travail de milliers de développeurs open source et d’auteurs de bibliothèque signifie que des milliers d’étrangers peuvent contribuer directement à votre code de production. Via la chaîne d’approvisionnement logicielle, votre produit est affecté par des vulnérabilités non corrigées, des erreurs involontaires ou même des attaques malveillantes contre les dépendances.

Compromission de la chaîne d’approvisionnement

La définition traditionnelle d’une chaîne d’approvisionnement provient de l’industrie manufacturière. Il s’agit de la chaîne formée par tous les processus nécessaires pour fabriquer et fournir quelque chose. Cette chaîne part de la planification, passe l’approvisionnement de matériaux, la fabrication et se termine par la vente. Une chaîne d’approvisionnement logicielle est similaire, sauf à la place des matériaux, ion utilise du code. On ne fabrique pas, mais on développe. Au lieu de creuser le minerai du sol, le code est sourcé auprès de fournisseurs commerciaux ou open source, et, en général, le code open source provient de référentiels. L’ajout de code à partir d’un référentiel signifie que votre produit est dépendant de ce code.

Par exemple, une attaque par la chaîne d’approvisionnement logicielle se produit lorsque du code malveillant est ajouté délibérément à une dépendance, par le biais de la chaîne d’approvisionnement de cette dépendance pour distribuer le code à ses victimes. Les attaques par la chaîne d’approvisionnement sont réelles. Il existe de nombreuses méthodes pour attaquer une chaîne d’approvisionnement, de l’insertion directe de code malveillant en tant que nouvelle contributeur, en passant par le détournement du compte d’un contributeur sans que d’autres personnes s’en aperçoive. Il est même possible de compromettre une clé de signature pour distribuer des logiciels qui ne font pas officiellement partie de la dépendance.

Une attaque de chaîne d’approvisionnement logicielle est rarement une fin en soi, il s’agit plutôt d’une opportunité pour un attaquant d’insérer des programmes malveillants ou de mettre une porte dérobée pour un accès futur.

The State of the Octoverse 2020 - Vulnerability Lifecycle

Logiciels non mis à jour

Aujourd’hui, l’utilisation de code open source est importante et ne devrait pas diminuer pour le moment. Étant donné que nous n’arrêterons pas d’utiliser des logiciels open source, la menace pour la sécurité de la chaîne d’approvisionnement est principale provient des logiciels non corrigé. Sachant cela, comment pouvez-vous faire face aux risques que font porter les vulnérabilité des dépendances sur votre projet ?

  • Connaître ce qui se trouve dans votre environnement. Cela nécessite de découvrir vos dépendances ainsi que toutes les dépendances transitives afin de comprendre les risques liés à ces dépendances, tels que les vulnérabilités ou les restrictions de gestion des licences.
  • Gérer vos dépendances. Lorsqu’une nouvelle faille de sécurité est détectée, vous devez déterminer si vous êtes impacté et, le cas échéant, mettre à jour vers la dernière version et appliquer le dernier correctif de sécurité disponible. Il est particulièrement important de passer en revue les modifications qui introduisent de nouvelles dépendances ou d’auditer régulièrement les dépendances plus anciennes.
  • Surveiller votre chaîne d’approvisionnement. Il s’agit d’auditer les contrôles que vous avez en place pour gérer vos dépendances. Cela vous aidera à appliquer des conditions plus restrictives à vos dépendances.

The State of the Octoverse 2020 - Advisories

Nous aborderons différents outils et techniques fournis par NuGet et GitHub que vous pouvez utiliser dès aujourd’hui pour résoudre les risques potentiels au sein de votre projet.

Savoir ce qui se trouve dans votre environnement

Graphe des dépendances NuGet

Consommateur de packages 📦

Vous pouvez afficher vos dépendances NuGet du projet en examinant directement le fichier projet de celui-ci.

Il se trouve généralement à l’un des deux emplacement suivants :

Selon la méthode utilisée pour gérer les dépendances NuGet, vous pouvez également utiliser Visual Studio pour afficher vos dépendances directement dans Explorateur de solutions ou dans le Gestionnaire de package NuGet.

Pour les environnements CLI, vous pouvez utiliser la commande dotnet list package pour répertorier les dépendances de votre projet ou de votre solution.

Pour plus d’informations sur la gestion des dépendances NuGet, consultez la documentation suivante.

Graphique des dépendances de GitHub

Consommateur de packages 📦 | Auteur de package 📦🖊

Vous pouvez utiliser le graphe des dépendances de GitHub pour afficher les packages dont dépend votre projet et les référentiels qui dépendent de celui-ci. Ce graphe peut vous permettre de voir l’ensemble des vulnérabilités détectées dans les dépendances du projet.

Pour plus d’informations sur les référentiels des dépendances GitHub, consultez la documentation suivante.

Version des dépendances

Consommateur de packages 📦 | Auteur de package 📦🖊

Pour garantir une chaîne d’approvisionnement de dépendances sécurisée, vous devez vous assurer que tous vos outils et de dépendances sont régulièrement mis à jour vers la dernière version stable, car ils incluent souvent les dernières fonctionnalités et correctifs de sécurité aux vulnérabilités connues. Les dépendances comprennent le code dont vous dépendez, les fichiers binaires que vous consommez, les outils dont vous vous utilisez ainsi que d’autres composants. Cela peut inclure :

Gérer les dépendances

Dépendances NuGet déconseillées et vulnérables

Consommateur de packages 📦 | Auteur de package 📦🖊

Vous pouvez utiliser l’interface CLI dotnet pour répertorier les dépendances réputées déconseillées ou vulnérables qui pourraient se trouver dans votre projet ou solution. Vous pouvez utiliser la commande dotnet list package --deprecated ou dotnet list package --vulnerable pour obtenir une liste de toutes les dépréciations ou vulnérabilités connues.

Dépendances GitHub vulnérables

Consommateur de packages 📦 | Auteur de package 📦🖊

Si votre projet est hébergé sur GitHub, vous pouvez tirer profit de GitHub Security pour rechercher des failles de sécurité et des erreurs de dans votre projet. Dependabot les corrigera en ouvrant une demande de tirage (pull request) sur votre codebase.

Intercepter les dépendances vulnérables avant qu’elles ne soient introduites est l’un des buts du mouvement « Shift Left ». La possibilité d’avoir des informations sur les dépendances, comme leur licence, leurs dépendances transitives et l’âge des dépendances par exemple, vous aident à atteindre ce but.

Pour plus d’informations sur les alertes et des mises à jours de Dependabot, consultez la documentation suivante.

Flux NuGet

Consommateur de packages 📦

Lorsque vous utilisez plusieurs flux sources NuGet privés et publics, un package peut être téléchargé à partir de l’un de ces flux. Pour vous assurer que votre génération est prévisible et protégée contre les attaques connues telles que la confusion de dépendances. Le fait de savoir de quel(s) flux proviennent vos packages est une meilleure pratique. Vous pouvez utiliser un flux unique ou un flux privé avec des capacités en amont de protection.

Pour plus d’informations à propos de la protection des flux de package, consultez 3 façon d’atténuer les risques lors de l’utilisation de flux de package privés.

Lorsque vous utilisez un flux privé, reportez-vous aux meilleures pratiques de sécurité pour la gestion des informations d’identification.

Stratégies de confiance client

Consommateur de packages 📦

Il existe des stratégies que vous pouvez choisir pour lesquelles l’utilisation de packages signés est obligatoire. Cela vous permet d’approuver un auteur de package, dès lors qu’il est signé, ou d’approuver un package s’il appartient à un utilisateur ou un compte spécifique signé par NuGet.org.

Pour configurer des stratégies de confiance client, consultez la documentation suivante.

Fichier de verrouillage

Consommateur de packages 📦

Verrouiller les fichiers stocke le code de hachage du contenu du package. Si le code de hachage de contenu d’un package que vous souhaitez installer correspond au fichier de verrouillage, il garantit la reproductibilité du package.

Pour activer les fichiers de verrouillage, consultez la documentation suivante.

Mappage de source du package

Consommateur de packages 📦

Le mappage de source de package vous permet de déclarer de manière centralisée la source à partir de laquelle chaque package de votre solution doit être restauré dans votre fichier nuget.config.

Pour activer le mappage de source de package, consultez la documentation suivante.

Surveiller votre chaîne d’approvisionnement

Analyse du secret GitHub

Auteur de package 📦🖊

GitHub analyse les clés API NuGet dans les référentiels pour éviter une utilisation frauduleuse des secrets accidentellement commités.

Pour en savoir plus sur l’analyse des secrets, consultez À propos de l’analyse des secrets.

Signature d’auteur de package

Auteur de package 📦🖊

La signature de l’auteur permet à un auteur de package d’appliquer une empreinte sur un package. Cela permet au consommateur de vérifier qu’il provient bien de vous. Cela vous protège contre la falsification de contenu et sert de source unique de vérité sur l’origine et l’authenticité du package. Lorsque vous combinez des stratégies de confiance client, vous pouvez vérifier qu’un package provient d’un auteur spécifique.

Pour appliquer une signature d’auteur sur un package, consultez Signer un package.

Générations reproductibles

Auteur de package 📦🖊

Les générations reproductibles créent des fichiers binaires identiques octet-pour-octet à chaque fois que vous le générez. Ces fichiers contiennent des liens de code source et des métadonnées du compilateur qui permettent au consommateur de package de recréer directement le fichier binaire et de vérifier que l’environnement de génération n’a pas été compromis.

Pour en savoir plus sur les générations reproductibles, consultez Production de packages avec des liens source et les spécifications de Validation de génération reproductible.

Authentification à 2 facteurs (2FA)

Auteur de package 📦🖊

Tous les comptes sur nuget.org doivent activer l’A2F. L’A2F ajoute une couche de sécurité supplémentaire lors de la connexion au compte GitHub ou NuGet.org.

Réservation du préfixe d’ID de package

Auteur de package 📦🖊

Pour protéger l’identité de vos packages, vous pouvez réserver un préfixe d’ID de package à l’aide de votre espace de noms respectif pour associer un propriétaire correspondant si votre préfixe d’ID de package se trouve correctement sous les critères spécifiés.

Pour en savoir plus sur la réservation de préfixes d’ID, consultez Réservation de préfixe d’ID de package.

Dépréciation et retrait d’un package vulnérable

Auteur de package 📦🖊

Pour protéger l’écosystème de package .NET, faites de votre mieux pour déprécier et retirer votre package de la liste lorsque vous avez connaissance d’une vulnérabilité dans un package que vous avez créé. Cela le masquera aux utilisateurs qui recherchent des packages. Si vous consommez un package déconseillé et retiré de la liste, vous devez éviter d’utiliser ce package.

Pour savoir comment déprécier et retirer de la liste un package, consultez la documentation suivante sur la dépréciation et le retrait des packages.

Résumé

Votre chaîne d’approvisionnement logicielle représente tout ce qui passe ou affecte votre code. Même si les compromissions de la chaîne d’approvisionnement sont réelles et de plus en plus communes, elles restent encore rares. Ainsi, la chose la plus importante que vous pouvez faire est de protéger votre chaîne d’approvisionnement en connaissant vos dépendances et en les gérant , et en surveillant votre chaîne d’approvisionnement.

Vous avez découvert les différentes méthodes proposées par NuGet et GitHub qui sont aujourd'hui disponibles pour visualiser, gérer et contrôler plus efficacement votre chaîne d'approvisionnement.

Pour plus d’informations à propos de la sécurisation des logiciels du monde, consultez le Rapport de sécurité « The State of the Octoverse 2020 ».