Au début de l'année, notre équipe a dû renforcer nos outils de sécurité existants ainsi que nos pratiques de développement et de test logiciel pour respecter les normes PCI-DSS et SOC-2. Une des priorités était d'améliorer le scan des vulnérabilités sur nos microservices basés sur K8s ainsi que sur quelques services monolithiques. Notre équipe DevOps a donc dû choisir entre plusieurs outils commerciaux et solutions open source pour mettre en place ce scan de vulnérabilités de nos logiciels. Ces outils fonctionnent de manière similaire : ils analysent les dépendances (bibliothèques du projet ou paquets du système) et les confrontent à des bases de données de vulnérabilités, comme le NVD du NIST et d’autres.
Vous pouvez utiliser quelques outils open source pour créer votre propre solution d'analyse des vulnérabilités, ou choisir un produit commercial qui offre des fonctionnalités supplémentaires à l'analyse basique pour vous faciliter le travail. Parmi les exemples :
La plupart des solutions commerciales complètent les bases de données publiques de vulnérabilités par leur propre base, ce qui élimine les faux positifs et négatifs et vous offre des résultats plus adaptés. Cependant, ces outils commerciaux deviennent rapidement coûteux à mesure que votre équipe de développeurs grandit. Vous devez donc réfléchir à ce qui vous convient le mieux : acheter une solution ou construire la vôtre avec des outils open source existants.
Au départ, nous avons choisi un outil commercial, estimant qu'il répondrait mieux à nos besoins vu nos contraintes de temps. Toutefois, après trois mois de déploiement et de tests d’un produit commercial de référence, nous avons rencontré de nombreux obstacles — support limité de Golang, sélection incorrecte des dépendances, arrêt non maîtrisé, problèmes entre conteneurs créés de zéro et ceux basés sur une image existante, etc. Face à cela, nous avons renoncé et décidé de développer notre propre outil en nous appuyant sur des technologies open source.
Dans cet article, je vous donne une base solide pour débuter si vous choisissez le logiciel libre. À la fin de l’article, vous trouverez aussi un lien vers notre dépôt open source pour bien démarrer !
Il y a essentiellement deux choses que vous souhaitez analyser pour détecter les vulnérabilités :
À l’avenir, il sera possible d’ajouter davantage de fonctionnalités telles que la vérification des licences ou l’analyse statique du code, mais cela sort du cadre de cet article.
Tout d’abord, vous devez vous assurer qu’aucune nouvelle vulnérabilité n’est introduite par votre code ou par une modification de l’image Docker. C’est donc une bonne idée d’analyser chaque demande de fusion avant sa fusion.
Vous devez aussi effectuer des analyses périodiques, car de nouvelles vulnérabilités peuvent apparaître avec le temps. Par ailleurs, la gravité peut évoluer : une faiblesse initialement mineure peut devenir critique dès lors qu'un nouveau vecteur d’attaque ou exploit se présente. Tandis que les outils commerciaux se souviennent de la dernière analyse et vous préviennent en cas de nouvelle vulnérabilité, notre solution open source effectue simplement un nouveau scan sur la branche master du projet.
De nombreux outils open source sont disponibles, mais nous avons choisi Trivy car il est facile à utiliser, en développement actif, et capable d’analyser plusieurs projets et systèmes d’exploitation.
Trivy est un scanner de vulnérabilité simple et complet pour les conteneurs et autres artefacts. Une vulnérabilité logicielle est un problème, une faille ou une faiblesse présente dans le logiciel ou dans un système d’exploitation. Trivy détecte les vulnérabilités des packages OS (Alpine, RHEL, CentOS, etc.) et des dépendances applicatives (Bundler, Composer, npm, yarn, etc.). Trivy est facile à utiliser : il suffit d’installer le binaire et vous êtes prêt à scanner ! Pour effectuer la numérisation, il vous suffit de spécifier une cible telle qu'un nom d'image du conteneur.
Il peut être facilement installé et exécuté localement sur l’image Docker construite ou sur la racine du projet. Il prend également en charge plusieurs sorties, notamment JSON et la sortie de tableau :
Malheureusement, il existe des projets que Trivy ne peut pas analyser (par exemple Golang), nous avons donc dû nous fier à OWASP Dependency-Check car une grande partie de notre code est en golang.
Dependency-Check est un outil d'analyse de composition logicielle (SCA) qui tente de détecter les vulnérabilités divulguées publiquement contenues dans les dépendances d'un projet. Pour ce faire, il détermine s’il existe un identifiant d’énumération de plateforme commune (CPE) pour une dépendance donnée. S'il est trouvé, il générera un rapport lié aux entrées CVE associées.
Il peut générer des pages HTML avec rapport, sortie JUnit et JSON (et quelques autres).
Maintenant, nous nous rapprochons de choses plus intéressantes 😊
Comme nous utilisons déjà Elasticsearch + Kibana + Fluentd dans nos équipes DevOps et SRE, il était naturel d'utiliser l'infrastructure existante pour analyser la sortie JSON de nos analyses de sécurité.
Nous devions simplement trouver un moyen d’envoyer des données d’une infrastructure non fiable (exécuteurs CI) vers notre Elasticsearch sécurisé. À cette fin, nous avons décidé d’avoir une file d’attente de messages au milieu. Fluentd dispose d'un plugin in_sqs pour lire les messages d'Amazon SQS et il est également simple à utiliser, donc l'architecture finale ressemble à ceci :
Une fois que les données atteignent Elasticsearch, il est simple de créer quelques tableaux de bord avec Kibana ou d'utiliser Discover pour interroger les vulnérabilités avec tous les détails nécessaires.
Alors maintenant que nous avons des scans et un joli tableau de bord, quelle est la prochaine étape ? Nous ne pouvons pas nous attendre à ce que les développeurs consultent ces tableaux de bord régulièrement. Au lieu de cela, nous avons décidé d'échouer le CI lorsqu'un problème de gravité élevée ou supérieure est détecté et qu'un correctif est disponible, de cette façon la responsabilité est transférée aux développeurs et aux propriétaires de projets.
Naturellement, nous avions besoin d’avoir une option pour mettre sur liste blanche certains CVE ou pour remplacer ce comportement par défaut pour chaque projet. Nous avons donc créé un référentiel avec des profils d’analyse de sécurité qui sont consommés par notre outil d’analyse qui encapsule l’exécution de Trivy et gère son comportement et sa sortie.
Désormais, tout développeur peut soumettre une demande de fusion contre ce référentiel et demander une exception. Exemple de profil pour le projet Kibana :
Cette implémentation de l’analyse de sécurité est une base solide qui peut être étendue au-delà de nos cas d’utilisation initiaux. Par exemple:
Vous pouvez trouver Dockerfile et les outils dans notre dépôt Gitlab public : https://gitlab.com/volterra.io/security-scanning
Merci à Jakub Pavlík .