Date de la publication : 2 janvier 2025
Lecture : 20 min
Découvrez les principes de base, les configurations, ainsi que les avantages et les inconvénients des scans de sécurité.

L'intégration de scans de sécurité dans votre pipeline CI/CD est cruciale pour maintenir des applications robustes et sécurisées. Mais qui est responsable de ces scans ? Qui doit s'assurer de leur intégration dans chaque pipeline CI/CD pour tous les projets ? Et qui décide d'accepter ou de corriger les vulnérabilités identifiées ? Pour les organisations qui évoluent dans des secteurs réglementés, ces questions sont primordiales.
Dans cet article, vous découvrirez comment GitLab CI/CD permet à chaque membre du cycle de développement logiciel d'intégrer des scans de sécurité. Vous découvrirez également les avantages et inconvénients des différentes options pour ajouter des scans aux pipelines de projets GitLab. Des exemples de code vous aideront aussi à lancer rapidement des scans de sécurité sur la plateforme DevSecOps de GitLab.
→ Essayez GitLab Ultimate et GitLab Duo Enterprise gratuitement.
GitLab utilise des personas fictifs pour décrire le membre d'une équipe qui utiliserait généralement une fonctionnalité ou une approche de sécurité donnée. En vous mettant dans la peau d'un Software Developer (Sasha), d'une Application Security Engineer (Amy), ou d'une Platform Engineer (Priyanka), vous pourrez mieux comprendre les besoins de chaque personne dans votre équipe.
GitLab suit un principe de « pipeline par projet », stocké dans le fichier nommé .gitlab-ci.yml. Ce fichier contient la définition du pipeline CI/CD du projet et est géré par contrôle de version comme n'importe quel autre fichier du projet. Vous découvrirez ces pipelines de projet, ainsi que les pipelines de conformité et les pipelines de politiques. Bien que les pipelines de conformité et les pipelines de politiques fassent également référence aux fichiers YAML dans les projets GitLab, ils ont généralement un nom de fichier différent et servent à des fins différentes.
Si vous connaissez déjà les scans de sécurité dans GitLab, les pipelines de sécurité disponibles vous paraîtront clairs. Nous aborderons chacune des approches en fonction des critères suivants :
includeLes mots-clés include des pipelines de projet GitLab permettent d'intégrer des pipelines externes dans le pipeline de projet .gitlab-ci.yml. Ce mécanisme est similaire à l'inclusion d'une bibliothèque dans de nombreux langages de programmation. Cette fonctionnalité puissante permet d'intégrer de façon transparente vos propres templates, ainsi que des templates fournis par GitLab, pour servir d'éléments de base dans vos pipelines. Les mots-clés include peuvent être utilisés dans les pipelines de projet ou d'autres fichiers de pipeline. Les pipelines de scan de sécurité sont des pipelines externes souvent inclus dans les pipelines de projet GitLab.
Voici les types courants de mots-clés include, qui utilisent l'exemple du scanner de sécurité.
GitLab propose des templates prêts à l'emploi qui peuvent être inclus dans un pipeline de projet pour faciliter l'ajout de divers éléments préconçus par les équipes. Voici un exemple de code :
include:
- template: Jobs/Secret-Detection.gitlab-ci.yml
- template: Jobs/SAST.gitlab-ci.yml
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
- template: Jobs/Container-Scanning.gitlab-ci.yml
Ce code inclut les templates GitLab pour la détection des secrets, les tests statiques de sécurité des applications (SAST), l'analyse des dépendances, et l'analyse des conteneurs, le tout en seulement cinq lignes de code.
Pour modifier le comportement des jobs inclus via des templates, vous pouvez soit utiliser des variables, soit utiliser les capacités de merge de propriétés de GitLab.
Vous trouverez ci-dessous un exemple de modification du pipeline d'analyse des conteneurs de GitLab à l'aide de variables. Le template d'analyse des conteneurs doit connaître l'emplacement de l'image et utilise la variable CS_IMAGE pour ce faire, comme documenté dans le code du template ci-dessus.
variables:
CS_IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
include:
- template: Jobs/Container-Scanning.gitlab-ci.yml
Les variables du pipeline de projet sont disponibles pour les template de jobs inclus en définissant la variable CS_IMAGE avant le template de pipeline inclus. Le template d'analyse des conteneurs hérite de la valeur de la variable CS_IMAGE.
Si nous voulions apporter des modifications à la propriété allow_failure définie, nous devrions fusionner les propriétés, car les templates de jobs n'utilisent aucune variable pour la valeur. (La propriété allow_failure est une propriété généralement disponible pour chaque job de pipeline GitLab. Consultez notre documentation pour plus de détails.)
Dans cet exemple, allow_failure est défini sur false, ce qui signifie que l'ensemble du pipeline s'arrête en cas d'échec de l'analyse des conteneurs : tout conteneur non scanné ne peut avancer dans le pipeline.
include:
# Includes a job called "container_scanning"
- template: Jobs/Container-Scanning.gitlab-ci.yml
# Define a job with same name for merging
container_scanning:
allow_failure: false
GitLab charge le template de job et, comme défini dans le code du template, enregistre le job container_scanning. Comme la définition du pipeline déclare un autre job avec ce nom, GitLab fusionne cette spécification avec le job déjà enregistré.
Bien que cette fonctionnalité offre de nombreuses possibilités, elle empêche également de protéger certaines propriétés contre l'écrasement. Nous n'en sommes qu'au point de modification du pipeline de projet, et nous ne pouvons contrôler ce paramètre. Mais vous verrez plus tard que cela peut poser problème lorsque la sécurité doit être appliquée sur un projet.
Les templates constituent un excellent point de départ pour partager des pipelines GitLab réutilisables. Pour abstraire davantage le code réutilisable dans l'ensemble d'une organisation ou d'une instance GitLab, GitLab a introduit les composants. Les composants sont la prochaine étape logique dans l'évolution des pipelines de GitLab. Ils sont conçus pour simplifier la création et l'utilisation de blocs fonctionnels dans les pipelines, ou même pour empaqueter et livrer des pipelines entiers si nécessaire. Ils offrent une interface bien définie, qui accepte des « intrants » pour la configuration. Les composants sont complètement isolés, ce qui en fait d'excellents candidats pour partager le travail au sein d'une organisation et pour servir d'éléments de base consultables et réutilisables.
Les équipes de développement peuvent utiliser le catalogue CI/CD pour parcourir et rechercher la collection de composants GitLab disponibles pour le public. Ces composants sont officiellement créés et maintenus par GitLab. GitLab utilise le catalogue CI/CD pour publier nos composants livrés tels que les scanners de sécurité aux côtés des composants fournis par la communauté.
Les composants sont consommés de manière similaire aux templates via le mot-clé include. Dans un exemple ci-dessus, nous avons montré comment le job d'analyse des conteneurs avait besoin de connaître l'emplacement de l'image. Cet « intrant » utilise le composant cs_image pour l'analyse des conteneurs. La configuration équivalente à l'exemple précédent est la suivante :
include:
- component: $CI_SERVER_FQDN/components/sast/[email protected]
- component: $CI_SERVER_FQDN/components/dependency-scanning/[email protected]
- component: $CI_SERVER_FQDN/components/secret-detection/[email protected]
- component: $CI_SERVER_FQDN/components/container-scanning/[email protected]
inputs:
cs_image: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
Dans cet exemple, le composant SAST est épinglé à la version 2.0.2, le composant d'analyse des dépendances à la version 0.2.0, le composant de détection des secrets à la version 1.1.2 et le composant d'analyse des conteneurs à la version 4.1.0. ~latest et d'autres tags sont disponibles pour une utilisation de composants de pointe et d'autres besoins de développement.
Que vous utilisiez des templates ou des composants, votre pipeline pourrait ressembler à l'image ci-dessous. Les quatre premiers jobs de l'étape de test sont le résultat des quatre instructions avec include dans le code ci-dessus.

includeL'un des avantages de l'utilisation du mot-clé include de pipeline dans GitLab est sa facilité d'utilisation. Avec seulement six lignes de code, nous avons inclus quatre scanners de sécurité couramment utilisés. Toute la logique et la configuration complexes sont gérées au sein des templates ou des composants. Ainsi, Sasha gagne du temps grâce à une solution prête à l'emploi.
Bien que les templates offrent une flexibilité maximale (variables et merge), il est important de ne pas oublier qu'elles impliquent de grandes responsabilités. La flexibilité des templates permet une personnalisation étendue, mais nécessite une gestion et une supervision minutieuses pour éviter des résultats inattendus.
En revanche, les composants fournissent un mécanisme plus structuré pour la création, le partage et la maintenance d'éléments de base pour un public plus large. Même s'ils sont moins personnalisables, les composants améliorent la stabilité et la fiabilité, et constituent une fonctionnalité précieuse, réutilisable et reproductible.
Comme le nom include le suggère, le pipeline de projet GitLab doit inclure des templates ou des composants. Bien que les templates soient simples à utiliser, Amy et Priyanka ne peuvent pas être sûres que Sasha les a inclus (correctement). Il est donc nécessaire d'appliquer une utilisation des scanners.
GitLab a identifié l'écart entre l'application des scans de sécurité dans les pipelines de projet et le besoin de respecter les frameworks de conformité réglementaire tels que PCI DSS, NIST et bien d'autres. L'introduction des frameworks de conformité en tant que fonctionnalité répond précisément à ce défi.
À première vue, un framework de conformité dans GitLab n'est qu'un label attaché à un projet et serait généralement nommé d'après le framework réglementaire qu'il est censé implémenter. Tout prend forme avec le lien entre ce label et le fichier YAML de pipeline de conformité, qui est responsable de la mise en œuvre des étapes nécessaires pour assurer la conformité.
Le mécanisme est simple : chaque fois que le pipeline de projet est déclenché, GitLab exécute le pipeline de conformité à la place. Ce dernier s'exécute avec les variables CI/CD et les variables CI/CD prédéfinies du pipeline de projet.
Deux principaux modèles de conception émergent : un « pipeline englobant », où le pipeline de conformité inclut le pipeline de projet, et un « pipeline de remplacement », où il ne l'inclut pas.
Remarque : les pipelines de conformité ont été dépréciés dans la version 17.3 de GitLab et devraient être supprimés dans la version 19.0. À ce stade, nous ne recommandons pas d'implémenter cette approche pour les nouvelles plateformes de développement. Cependant, si vous les utilisez déjà, ne manquez pas de consulter les sections ci-dessous.
Dans cette approche, le pipeline de conformité définit ses propres jobs selon des besoins de conformité spécifiques. Il inclut le pipeline de projet de la même manière que les templates dans la section précédente. Cette configuration est possible car les variables CI/CD prédéfinies proviennent du pipeline de projet et permettent au système d'identifier l'emplacement de la définition du pipeline pour l'inclure.
Voici un exemple de ce à quoi pourrait ressembler un pipeline de conformité simple.
include:
- component: $CI_SERVER_FQDN/components/sast/[email protected]
- component: $CI_SERVER_FQDN/components/dependency-scanning/[email protected]
- component: $CI_SERVER_FQDN/components/secret-detection/[email protected]
- component: $CI_SERVER_FQDN/components/container-scanning/[email protected]
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
Les trois dernières lignes incluent le pipeline de projet basé sur les variables disponibles.
Contrairement aux pipelines englobants, qui incluent le pipeline de projet, les pipelines de remplacement l'ignorent entièrement et n'exécutent que leurs propres jobs. Ce type de pipeline définit chaque étape et englobe tous les jobs nécessaires pour construire, tester et déployer l'application.
Voici un pipeline de conformité fictif qui illustre cette approche.
stages: ["build", "test", "deploy"]
include:
- component: $CI_SERVER_FQDN/components/sast/[email protected]
- component: $CI_SERVER_FQDN/components/dependency-scanning/[email protected]
- component: $CI_SERVER_FQDN/components/secret-detection/[email protected]
- component: $CI_SERVER_FQDN/components/container-scanning/[email protected]
build-job:
stage: build
script: echo "Building the container image"
test-job:
stage: test
script: echo "Running unit tests"
deploy-job:
stage: deploy
script: echo "Deploying app"
Bien que les frameworks de conformité ne soient pas très compliqués, ils ne sont pas aussi simples et directs que les mots-clés include. Ils sont destinés à être écrits et attribués aux projets par Amy et Priyanka, qui doivent maintenant interagir avec le code YAML du pipeline. Un framework doit être déclaré dans l'espace de nommage principal, des pipelines de conformité doivent être créés et maintenus, et les frameworks de conformité doivent être attachés aux bons projets.
Amy et Priyanka sont les auteures des pipelines de conformité. Comme Sasha dans la section précédente sur les mots-clés include, elles ont un contrôle total sur ce qu'elles incluent et comment elles l'incluent : elles peuvent personnaliser les jobs de conformité comme les scanners de sécurité.
L'application des pipelines soulève la question de savoir si les équipes de développement peuvent altérer les jobs de sécurité. Dans un environnement avec une forte séparation des tâches, cette nuance nécessite une attention supplémentaire. Pour répondre à cette question, nous devons examiner chaque modèle séparément :
Comme nous l'avons vu précédemment, les pipelines de projet sont inclus dans les pipelines de conformité. En plus des variables CI/CD au niveau du groupe ou du projet, chaque élément de ce pipeline de projet doit être considéré comme une menace potentielle pour le pipeline de conformité, en particulier les variables et les jobs. Ces derniers peuvent et vont influencer le comportement des jobs de sécurité s'ils sont utilisés de manière malveillante.
Voici un exemple simple pour illustrer le problème.
Pipeline de conformité :
include:
- template: Jobs/SAST.gitlab-ci.yml
- template: Jobs/Secret-Detection.gitlab-ci.yml
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
Pipeline de projet :
variables:
SECRET_DETECTION_DISABLED: true
semgrep-sast:
rules:
- when: never
Ce pipeline de projet déclare la variable SECRET_DETECTION_DISABLED (également possible via des variables CI/CD au niveau du projet ou du groupe), qui est évaluée dans le template de détection de secrets inclus. De plus, les trois dernières lignes utilisent le mécanisme de merge vu précédemment, qui n'exécute pas le job.
Les deux remplacements pourraient être évités en utilisant des composants. Ces derniers peuvent être sujets à de telles attaques en raison des valeurs par défaut de leurs intrants, qui utilisent aussi souvent des variables. Voyons comment cette vulnérabilité pourrait être exploitée.
Pipeline de conformité :
include:
- component: $CI_SERVER_FQDN/components/sast/[email protected]
- component: $CI_SERVER_FQDN/components/secret-detection/[email protected]
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
Pipeline de projet :
variables:
CI_TEMPLATE_REGISTRY_HOST: "docker.io"
Pour comprendre ce fonctionnement, regardez la ligne 6 du composant du scanner SAST :
spec:
inputs:
stage:
default: test
image_prefix:
default: "$CI_TEMPLATE_REGISTRY_HOST/security-products"
L'intrant image_prefix utilise CI_TEMPLATE_REGISTRY_HOST pour construire la valeur par défaut. En définissant cette variable sur une fausse valeur de la même manière que nous avons défini SECRET_DETECTION_DISABLED sur true auparavant, Sasha peut faire en sorte que le job charge une mauvaise image et casse les SAST.
Pour empêcher cette capacité de remplacement par une personne ayant un rôle de développeur, privilégiez les composants au lieu des templates. Vous pourrez ainsi corriger de nombreuses failles introduites par les développeurs. Pour garantir la conformité, codez en dur les valeurs pour les intrants des composants.
Les développeurs ne peuvent pas injecter du code de pipeline réel dans le pipeline de conformité. Cependant, les pipelines de conformité s'exécutent avec les variables CI/CD du projet. Par conséquent, toute variable au niveau du groupe ou du projet pourrait modifier le comportement du pipeline de conformité. Avec SECRET_DETECTION_DISABLED défini sur true dans les variables CI/CD du projet, le pipeline de conformité suivant peut être modifié à nouveau :
stages: ["build", "test", "deploy"]
include:
- template: Jobs/SAST.gitlab-ci.yml
- template: Jobs/Secret-Detection.gitlab-ci.yml
build-job: ...
test-job: ...
deploy-job: ...
Les composants peuvent résoudre ce problème, mais, comme auparavant, les intrants des composants peuvent utiliser des variables CI/CD définies par les développeurs. Les auteurs de pipelines de conformité doivent identifier et gérer ces situations.
Les lacunes des pipelines de conformité ont entraîné la création de politiques. GitLab a introduit les politiques comme la voie à suivre en matière de gestion de la conformité. Les auteurs stockent un ensemble de politiques dans un projet séparé sous forme de fichiers YAML et les appliquent aux projets au niveau du groupe ou du projet. Amy et Priyanka peuvent cibler des projets individuels avec des exigences spécifiques, mais aussi assurer la conformité dans toute l'organisation. L'accès au projet contenant les politiques peut être contrôlé au sein du projet de politiques et audité dans GitLab.
Il existe différents types de politiques pour différents usages. Ceux qui nous intéressent sont les politiques d'exécution des scans (SEP) et les politiques d'exécution des pipelines (PEP).
Comme leur nom l'indique, les SEP exigent qu'un scan particulier, ou un ensemble de scans, soit exécuté dans le cadre du pipeline de projet et injectent les jobs de scan respectifs dans les pipelines des projets associés. Elles incluent le template respectif dans le pipeline selon les variables et les règles définies par Amy et Priyanka.
GitLab aide les auteurs de politiques avec une interface utilisateur complète en plus d'un workflow Git basé sur YAML. La capture d'écran et l'extrait de code suivants illustrent un exemple très basique d'une SEP :

name: Secret Scanner
description: ''
enabled: true
actions:
- scan: secret_detection
rules:
- type: pipeline
branches:
- "*"
Pour plus de détails sur les paramètres des SEP dans l'interface utilisateur et YAML, veuillez vous référer à notre documentation.
Les SEP sont un mécanisme léger et facile à utiliser qui applique la sécurité sur les pipelines CI/CD existants et nouveaux dans l'organisation ou à un niveau granulaire. Le support de l'interface utilisateur en fait un outil viable pour tous les personas pertinents.
Les SEP sont limitées aux jobs de scanner prédéfinis, et il n'est pas possible d'étendre cette liste avec des jobs personnalisés à ce stade. Cette limitation peut être restrictive pour les équipes avec des exigences de scan uniques.
Une fois qu'une SEP est appliquée à un projet (directement ou indirectement), Sasha n'a aucun moyen de se débarrasser de ce job de scan. Cependant, il peut y avoir des moyens (intentionnels ou non) de manipuler le comportement du job de scan.
Les jobs injectés via les SEP sont généralement réceptifs aux variables CI/CD et respectent les règles générales de précédence des variables. Pour cette injection, les politiques intègrent une logique qui refuse les modifications de certaines variables prédéfinies comme décrit ici et refuse généralement la configuration de variables qui suivent certains templates tels que _DISABLED ou _EXCLUDED_PATHS.
Malgré ces mesures de sécurité, une utilisation inconsidérée des politiques peut entraîner des falsifications: dans notre test, nous avons pu définir une variable CI/CD au niveau du projet SECURE_ANALYZERS_PREFIX sur une mauvaise valeur (un emplacement inexistant). Comme vous pouvez le voir ici, le template de détection des secrets l'utilise pour construire l'emplacement de l'image du scanner.
Bien que le job de scan soit inclus dans l'exécution du pipeline, il échoue très tôt et, par conséquent, ne fournit aucun résultat. En raison de la configuration allow_failure: true, le pipeline continuera à s'exécuter et finira par exécuter un job de déploiement.
Étant donné que les variables SEP ont la plus haute précédence parmi les variables, il existe une solution facile pour réduire la surface d'attaque de la politique : codez simplement en dur la valeur correcte dans votre fichier YAML de politique ou via l'interface utilisateur :
- name: Secret Scanner
actions:
- scan: secret_detection
variables:
SECURE_ANALYZERS_PREFIX: registry.gitlab.com/security-products
Les SEP permettent l'injection d'un ensemble de jobs liés à la sécurité dans n'importe quel pipeline de projet. En revanche, les PEP appliquent des configurations de pipeline entières aux projets et offrent beaucoup plus de flexibilité en ce qui concerne la personnalisation des contraintes de sécurité.
Il existe deux méthodes pour implémenter ces politiques, appelées « actions » : inject et override. Ces actions fonctionnent de manière similaire aux templates que nous avons vus dans la section des frameworks de conformité et fournissent des moyens flexibles d'améliorer et d'appliquer les normes de sécurité au sein du workflow de développement.
L'injection de pipelines implique l'ajout des jobs et autres éléments définis dans le pipeline de politique dans le pipeline de projet. Actuellement, les jobs ne doivent être injectés que dans des étapes réservées, à savoir .pipeline-policy-pre et .pipeline-policy-post pour éviter des résultats imprévisibles.
GitLab gère en toute efficacité les conflits de nommage entre les jobs ou les variables dans les pipelines de politique et de projet en construisant chaque pipeline de manière isolée avant de les combiner. Cette approche garantit la transparence du processus d'intégration et n'impacte pas les workflows ou les configurations existants.

La capture d'écran ci-dessus montre un exemple de pipeline de politique injecté. Les jobs du pipeline de projet contiennent le préfixe prj- pour faciliter l'identification.
Dans cette approche, le pipeline de projet est entièrement remplacé par le pipeline de politique. Cette méthode est similaire aux pipelines de conformité qui n'incluent pas le fichier .gitlab-ci.yml du projet. Malgré le remplacement, les pipelines s'exécutent en utilisant les variables CI/CD du projet et maintiennent la cohérence avec les configurations spécifiques au projet. Le pipeline de conformité que nous avons utilisé précédemment peut également servir de pipeline de politique :
stages: ["build", "test", "deploy"]
include:
- component: $CI_SERVER_FQDN/components/sast/[email protected]
- component: $CI_SERVER_FQDN/components/dependency-scanning/[email protected]
- component: $CI_SERVER_FQDN/components/secret-detection/[email protected]
- component: $CI_SERVER_FQDN/components/container-scanning/[email protected]
build-job:
stage: build
script: echo "Building the container image"
test-job:
stage: test
script: echo "Running unit tests"
deploy-job:
stage: deploy
script: echo "Deploying app"
L'image ci-dessous montre un pipeline légèrement plus complet que le pipeline fictif ci-dessus :

Remarque : cette approche ne fonctionne actuellement pas avec les SEP.
Cependant, l'existence d'un Dockerfile n'est pas toujours un indicateur valide, car les équipes peuvent développer sans Dockerfile en utilisant Cloud Native Buildpacks, Heroku Buildpacks, Kaniko ou d'autres outils. Les pipelines gérés ne rencontrent pas ce défi, car ils sont plus contrôlés et centralisés.
Pour les projets qui produisent plusieurs images de conteneurs, plusieurs jobs de scan de conteneurs seraient nécessaires pour une couverture adéquate. Cette approche soulève les mêmes questions qu'auparavant : « Comment savons-nous qu'il y en a plusieurs ? » et « La source de cette information est-elle digne de confiance ? ». Si nous voulions nous appuyer sur l'existence de Dockerfile, une approche dynamique avec un job de scan de conteneurs pour chaque Dockerfile détecté serait nécessaire.
Dans cet article, vous avez découvert diverses approches pour ajouter des scans de sécurité aux pipelines CI/CD et exploré leur facilité d'utilisation, leur personnalisation et leur application. Vous avez appris qu'un auteur de pipeline chargé de la conformité du projet doit garder quelques éléments à l'esprit pendant le processus pour éviter des surprises par la suite. Nous vous recommandons de créer un petit espace de test sur votre instance GitLab, puis d'exécuter quelques tests pour reproduire les principaux points de cet article.
GitLab fournit une assistance en fonction des besoins. Toutes les approches sont faciles à implémenter grâce à la fonctionnalité intégrée de la plateforme. Il existe plusieurs façons de sécuriser vos jobs de scan, et si vous avez des questions, n'hésitez pas à ouvrir un ticket auprès de notre assistance.
Testez les scans de sécurité dès aujourd'hui !
→ Essayez GitLab Ultimate et GitLab Duo Enterprise gratuitement.
Cet article de blog vous a plu ou vous avez des questions ou des commentaires ? Partagez vos réflexions en créant un sujet dans le forum de la communauté GitLab.
Donnez votre avis