Implémenter le DevSecOps en entreprise
Introduction
Nous avons déjà parlé de plusieurs bonnes pratiques, que ce soit en matière de développement ou de cybersécurité. Le DevSecOps est large car il recouvre la mise en œuvre de la sécurité à toutes les phases du SDLC, mais également au niveau des éléments liés à l’infrastructure de votre SI.
Certaines entreprises et organisations sont parfois réfractaires à l’idée de changer ce qui fonctionnait jusqu’à présent. Lorsque vous souhaitez mettre en œuvre le DevSecOps dans votre entreprise, vous risquez probablement d’être confronté à des freins (il est question de blockers en anglais) qui peuvent être technologiques, mais qui vont surtout être organisationnels et humains.
Il est donc nécessaire d’accompagner les différentes équipes techniques, business, de direction et financières, pour leur démontrer les intérêts et les gains associés à la pratique du DevSecOps. Heureusement, il existe plusieurs manières d’initier cette mutation organisationnelle, en réalisant des actions au niveau de la gouvernance, de la gestion des risques et de la conformité.
Définir des objectifs de sécurité au sein d’une organisation
1. Utiliser le CIA en entreprise
Comme vous vous en souvenez, le CIA fait référence à Confidentiality (confidentialité), Integrity (intégrité) et Availability (disponibilité).
La confidentialité des données assure que les données ne peuvent être consultées, modifiées ou supprimées que par les personnes qui sont habilitées à la faire. Il est parfois même nécessaire de « cacher » ces données au personnel de l’entreprise qui gère l’application correspondante. Par exemple, il pourrait être « dangereux » que les personnes travaillant au service IT puissent accéder à des brevets, aux fiches de paie des autres salariés, à du code source d’une application sensible, etc.
L’intégrité des données permet d’assurer que la donnée reste fiable et sans modification inopportune durant son stockage et son transit. Ainsi, l’administrateur et l’utilisateur peuvent être assurés que la validité et l’exactitude de la donnée restent préservées durant l’ensemble de son cycle de vie.
Nous avons plusieurs fois abordé le sujet de l’importance de la disponibilité des données. En effet, elles doivent toujours être accessibles et disponibles pour les utilisateurs qui en ont besoin. Il est alors possible de mettre en œuvre une gestion des droits d’accès (lecture et écriture) en fonction des groupes auxquels appartiennent les utilisateurs concernés. Il ne faut pas non plus oublier que la disponibilité des applications et des services est également un enjeu majeur.
Il est possible d’ajouter...
Développer une culture de la cybersécurité
Comme vous l’avez compris, il est essentiel de développer une culture de la cybersécurité au sein d’une entreprise. Ce sont à la fois les personnels techniques, mais également les personnels non techniques, qui doivent s’approprier cette culture de la sécurité informatique. Grâce à cela, il devient possible de réduire la surface d’attaque « humaine » que les attaquants pourraient utiliser, notamment grâce au Social Engineering.
1. Mise à disposition d’outils d’entraînement pour les développeurs
Tout d’abord, les développeurs des applications doivent être les premiers à s’approprier cette culture de la cybersécurité. Mais pour cela, il faut leur mettre à disposition un certain nombre d’outils.
Commençons par les éléments liés à la formation des développeurs. En effet, trop souvent, durant leur cursus scolaire ou professionnel, la plupart des développeurs n’ont été que très peu sensibilisés à la cybersécurité. Leurs missions et leurs études ont tendance à se focaliser sur la partie technique et exécutante de leur périmètre d’activité. C’est pourquoi il est souvent nécessaire de leur proposer des solutions permettant une véritable montée en compétences sur ces sujets.
Plusieurs possibilités s’offrent aux entreprises. Il est possible de mettre en place des sessions de formation régulières se déroulant sur plusieurs demi-journées chaque trimestre, via un centre de formation. Cependant, cette solution est souvent coûteuse, et il est parfois difficile de trouver...
Implémenter un dépôt d’images et d’artefacts
1. Utilisation d’un dépôt d’artefacts
Un dépôt d’artefacts (artefact repository) permet de stocker les différents artefacts produits lors des processus d’intégration continue, afin qu’ils soient disponibles dans les phases suivantes pour y effectuer des tests et les déployer dans les différents environnements. Pour simplifier, imaginez qu’un artefact correspond à un élément produit lors du cycle de vie du développement après un build. Ils peuvent donc correspondre à des binaires, à des fichiers, à des logs, à des images Docker.
Ces différents artefacts peuvent être stockés directement sur le serveur d’intégration continue (comme nous l’avons déjà fait avec GitLab) ou sur un serveur externe dédié (comme JFrog ou Nexus). Ces dépôts permettent d’avoir un endroit centralisé sur lequel sont stockés les artefacts, et qui peuvent être récupérés, le plus souvent via des API, afin d’en effectuer le déploiement.
L’utilisation de ces dépôts apporte aussi un certain nombre d’intérêts :
-
Traçabilité des différents builds effectués.
-
Recherche simplifiée d’artefacts spécifiques.
-
Versionning des artefacts.
-
Mise en œuvre d’un cycle de vie des artefacts.
Parmi les différents types de dépôts existants, vous pouvez en retrouver trois principaux. Tout d’abord ceux correspondant aux images de vos conteneurs (container repository), aux builds effectués (build repository), ou aux packages des applications (application package repository).
Les dépôts ont l’avantage...
Définir les bons processus de déploiement d’une application
1. Mise en œuvre de processus de décommissionnement
Avant de parler de déploiement et des bonnes pratiques, il est nécessaire de commencer par faire un point sur les processus de décommissionnement. En effet, une application n’a pas une durée de vie illimitée. Elle est conçue pour fonctionner à un instant T mais doit également pouvoir être retirée lorsque les besoins n’existent plus, qu’une nouvelle version importante a été développée, ou lorsqu’elle présente des risques de sécurité trop importants.
Avant de décommissionner une application, vous devez tout d’abord obtenir l’aval de toutes les parties prenantes (stakeholders). Il est important de définir ensuite un plan de transition prenant en compte le décommissionnement de l’application, mais également la migration potentielle vers une nouvelle application ou version. Gardez en tête que la transparence est essentielle pour garantir une bonne transition. Soyez donc clair sur le temps pendant lequel l’application reste active et fonctionnelle, puis sur la date à partir de laquelle le support n’est plus assuré.
Lorsque la décision de décommissionner l’application est prise, l’ensemble des personnes qui travaillaient dessus doivent concentrer leurs forces sur le support à la migration des utilisateurs actuels, vers la nouvelle version ou la nouvelle application (si elle existe).
L’ensemble des microservices, fichiers de configuration, code, base de données, doivent être sauvegardés. Toutes les ressources qui étaient jusqu’alors utilisées pour cette application (serveurs, équipements réseau, licences, etc.) doivent...
Gérer de façon sécurisée le versionning du code
1. Scanner les dépôts Git à la recherche de secrets
Vous n’avez pas idée du nombre d’éléments confidentiels ou secrets qu’il est possible de retrouver sur les dépôts Git des utilisateurs.
Il existe plusieurs outils permettant de vérifier si votre dépôt Git présente des secrets « hardcodés » dans ses fichiers ou dans son historique. TruffleHog est un outil codé en Go sous licence AGPL-3.0, disponible à l’adresse https://github.com/trufflesecurity/trufflehog, permettant de faire des analyses de sécurité sur les dépôts Git.
Créez un dépôt Git appelé test_secrets permettant de tester TruffleHog :
Clonez votre dépôt pour en faire une copie locale.
git clone https://gitlab.com/devsecops-editions-eni/chapitre-7-
mettre-en-oeuvre-le-devsecops-dans-votre-entreprise/test_secrets.git
Créez un fichier appelé mysecret.conf dont le contenu est le suivant.
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuN4lMknQ7o+IUjlyIf5KhmAE7Z2QVi71DznlFcxJazGGnrt8
bffEpLRj4xkyXzGu5qNTylrO+tO5R9HoDQcBJFVZvTQctcE7b1Q4g2/cafm+dZR5
uJilBEtoObbVLMEJYhhcTrPoPifoXM5acp8RDsYbxLaCkEDO5qCTTIMeSJNzTk5d
Pm0VImzeYxISIvRiazDlJ7fAxNUnAx9AprNR+QhpokOOXTE39Cy8S6KRnlEhBtLk
om51aD2QdcXdDapxT7La2nE5sB5hyIBcwNP5hf+d5PQCgUYa8+anwgwFq8CQ4Ujw
xML5JpO6lIMT45ZLHJWIdut/HlmsuwtbOFk+SQIDAQABAoIBAQCtN8EEmLPDBAxI
dvkhLuLne8rCVlOq3T7TcHzdatgUL4ii7KuPYowHg9rgLHjNR4FJLBpTzbiIv5+o
0t6qbji8sZhvNwf7qb4l93UoesS9K7ww8dkHhUeBeaKECXM/BvTizE6Zk+r1anFH
nDaVlcPm4uub6yL1RTRYVncORwE2IBJSiN6JUeAtYHCGUWQ1VUxnOsBQc25qFTDV
flKBqBRqQ1n8Ls1mKQeuzJYkiBd3/4B3YzEoIutDA7Z2fIgx8P0j5X93fG+L5Rqb
/iH9foi5Nb/aPyweHtGRnH55kz2gQ/prEWE81LVWAw5Ofdq6DVm+Mj5/ugxXbDlY ...
Sécuriser un serveur Nginx
1. Effectuer un premier scan de serveur Nginx
En suivant le CIS Benchmark du serveur web Nginx, vous pouvez effectuer un certain nombre de vérifications propres à la sécurité de votre serveur.
Il existe cependant un outil permettant d’effectuer des scans de sites web, appelé Nikto (https://cirt.net/nikto2).
Pour tester cet outil, nous allons utiliser Docker de manière à créer deux conteneurs : un serveur nginx classique, sans configuration particulière, et un conteneur nikto qui va effectuer le scan. Cependant, ces deux conteneurs doivent être rattachés au même réseau sur Docker, de manière à pouvoir communiquer entre eux via leur nom.
Commencez par créer le réseau auquel vos conteneurs vont être attachés.
docker network create nginx
Lancez ensuite le conteneur nginx.
docker run -d --rm --name nginx_server -p 80 --network nginx
nginx:1.23.0
Avec les options utilisées, nous précisons que le nom du conteneur est : nginx_server, qu’il doit exposer son port 80 et qu’il est attaché au réseau nginx.
Lancez maintenant le conteneur nikto.
git clone https://github.com/sullo/nikto.git
cd nikto
docker build -t sullo/nikto .
docker run --network nginx sullo/nikto -h http://nginx_server
Avec les options utilisées, nous précisons que le conteneur est attaché au réseau nginx et qu’il doit effectuer un scan de l’hôte nginx_server.
Vous devriez obtenir une sortie similaire à celle-ci :
- Nikto v2.1.6
------------------------------------------------------------------------
+ Target IP: 172.18.0.2
+ Target Hostname: nginx_server
+ Target Port: 80 ...
Sécuriser un serveur web Apache
1. Effectuer un premier scan de serveur Apache
Nous allons répéter les mêmes étapes pour un serveur web Apache.
Commencez par créer le réseau auquel vos conteneurs vont être attachés.
docker network create apache
Lancez ensuite le conteneur apache.
$ docker run -d --rm --name apache_server -p 80 --network apache
httpd:2.4.54
Avec les options utilisées, nous précisons que le nom du conteneur est : apache_server, qu’il doit exposer son port 80 et qu’il est attaché au réseau apache.
Lancez maintenant le conteneur nikto.
docker run --network apache sullo/nikto -h http://apache_server
Avec les options utilisées, nous précisons que le conteneur est attaché au réseau apache et qu’il doit effectuer un scan de l’hôte apache_server.
Vous devriez obtenir une sortie similaire à celle-ci :
Nikto v2.1.6
-----------------------------------------------------------------------------
+ Target IP: 172.19.0.2
+ Target Hostname: apache_server
+ Target Port: 80
+ Start Time: 2022-12-19 21:26:33 (GMT0)
-----------------------------------------------------------------------------
+ Server: Apache/2.4.54 (Unix)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-Content-Type-Options header is not set. This could allow the user
agent to render the content of the site in a different fashion to the MIME
type.
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Allowed HTTP Methods: HEAD, GET, POST, OPTIONS, TRACE
+ OSVDB-877: HTTP TRACE method is active...
Conclusion
Nous avons donc vu qu’il était nécessaire de définir de bons objectifs de sécurité afin d’avoir une vision claire de ce qu’il faut protéger en priorité.
Le développement d’une culture globale de la cybersécurité au sein des organisations est également essentiel, car l’humain reste l’une des failles de sécurité les plus importantes. Au-delà des outils mis à disposition, l’utilisation des Security Champions est un atout de taille pour la diffusion des bonnes pratiques. Ils sont un véritable relais au sein des équipes.
Les bonnes pratiques d’utilisation de dépôts d’images et de conteneurs grâce à GitLab Container Registry permettent de mettre en place un cycle de vie des artefacts de manière à ce qu’une vulnérabilité ne reste pas trop longtemps sans être corrigée.
Le déploiement des applications est un rouage essentiel de la méthodologie DevOps, et il peut parfois être difficile de déterminer la solution de déploiement idéale à implémenter. Le bon rapport entre coût, downtime et complexité nous incite à privilégier les déploiements en Canary Release ou en Blue/Green, mais rien n’empêche de tenter l’expérience de l’A/B Testing ou du Shadow, pour renforcer un peu plus la qualité des déploiements.
Les développeurs utilisent presque tous des outils de versionning, mais commettent parfois des erreurs en uploadant du contenu sensible et qui ne devrait pas être diffusé. Heureusement, l’utilisation d’outils comme Trufflehog permet de s’assurer qu’aucun secret ne passe entre les mailles du filet et se retrouve sur Internet dans des dépôts...