Aller au contenu principal
GitLabCI/CDSécuritéDevSecOpsFormation

Sécurité dans GitLab CI : SAST, DAST et scanning

30 min de lecture GitLab CI/CD — Chapitre 5

Intègre la sécurité dans tes pipelines : SAST, DAST, container scanning, dependency scanning, secret detection. Le DevSecOps en pratique avec GitLab.

La sécurité n’est pas une étape finale — c’est une partie du pipeline. Au lieu d’un audit avant chaque release (lent, cher, frustrant), tu automatises les checks dans le CI/CD. GitLab intègre une suite complète de sécurité nativement : SAST, dependency scanning, container scanning, DAST et secret detection. Pas de plugins tiers, tout se configure avec des include de templates officiels.

SAST : analyser le code source

Le SAST (Static Application Security Testing) analyse ton code source sans l’exécuter. Il détecte les injections SQL, XSS, utilisation dangereuse de crypto, et autres patterns de vulnérabilités.

L’activation tient en deux lignes :

include:
  - template: Security/SAST.gitlab-ci.yml

GitLab détecte automatiquement les langages et lance les bons analyzers. Depuis GitLab 16+, Semgrep est l’analyzer principal pour Python, JavaScript, Go, Java, Ruby et PHP. Tu peux personnaliser avec des variables :

include:
  - template: Security/SAST.gitlab-ci.yml

variables:
  SAST_EXCLUDED_PATHS: "tests/,docs/,vendor/"
  SEMGREP_RULES: "p/owasp-top-ten p/python"

💡 La vraie valeur : sur une merge request, GitLab affiche directement les nouvelles vulnérabilités introduites et celles résolues. Le reviewer voit les problèmes de sécurité dans le diff — pas besoin de parser un rapport externe.

Tu peux aussi écrire des règles Semgrep custom dans un fichier .semgrep/custom-rules.yml pour détecter des patterns spécifiques à ton projet (mots de passe hardcodés, usage de eval(), shell=True dans subprocess…). C’est un outil particulièrement efficace pour les équipes qui veulent encoder leurs propres standards de sécurité au-delà des règles génériques OWASP.

Dependency et Container Scanning

Dépendances applicatives

Le dependency scanning cherche des CVE connues dans tes dépendances. Il supporte tous les écosystèmes majeurs : requirements.txt, package-lock.json, go.sum, Cargo.lock, Gemfile.lock, composer.lock, etc.

include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml

GitLab génère un rapport avec la sévérité (Critical, High, Medium, Low), le CVE, le package vulnérable et la version qui corrige le problème. Tu peux confirmer, dismisser (faux positif avec justification) ou résoudre chaque vulnérabilité depuis le dashboard Security. Pour les mises à jour automatiques de dépendances, combine avec Renovate (open source) en pipeline schedulé.

Images Docker

Le container scanning analyse tes images Docker layer par layer avec Trivy. Il compare les packages installés avec la base de vulnérabilités :

include:
  - template: Security/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    CS_SEVERITY_THRESHOLD: "HIGH"

🔥 Bonnes pratiques images : utilise des images -slim ou -alpine (moins de surface d’attaque), des multi-stage builds (l’image finale ne contient que le nécessaire), un user non-root, et jamais de secrets dans l’image. Un pipeline schedulé qui rebuild régulièrement les images te protège des nouvelles CVE.

DAST : tester l’application en runtime

Le DAST (Dynamic Application Security Testing) teste ton application déployée en envoyant des requêtes malveillantes. C’est un pentester automatisé.

include:
  - template: DAST.gitlab-ci.yml

variables:
  DAST_WEBSITE: "https://staging.example.com"
  DAST_FULL_SCAN_ENABLED: "false"   # passif par défaut

Le scan passif observe le trafic sans modifier les requêtes — rapide et non intrusif. Le full scan envoie des payloads d’attaque (SQLi, XSS) — plus complet mais plus lent.

⚠️ Ne lance jamais un full scan DAST sur la production. Utilise staging ou un environnement de test dédié. Pour les APIs REST/GraphQL, GitLab propose un template DAST-API.gitlab-ci.yml qui scanne à partir de ton OpenAPI spec ou d’un fichier HAR.

Pour scanner derrière un login, configure les variables DAST_AUTH_URL, DAST_USERNAME, DAST_PASSWORD et les sélecteurs CSS des champs du formulaire. Le DAST est complémentaire au SAST : le SAST trouve les vulnérabilités dans le code (plus de faux positifs, couverture complète), le DAST trouve celles exploitables en runtime (moins de faux positifs, limité aux endpoints exposés).

Secret Detection

Détecte les secrets accidentellement commités : clés AWS (AKIA...), tokens GitHub/GitLab, clés SSH, mots de passe dans les URLs, tokens Slack/Stripe, service accounts GCP…

include:
  - template: Security/Secret-Detection.gitlab-ci.yml

variables:
  SECRET_DETECTION_HISTORIC_SCAN: "true"   # scanne tout l'historique Git

💡 En complément du CI, installe un hook pre-commit avec gitleaks pour attraper les secrets avant le push. C’est la première ligne de défense — le CI est le filet de sécurité.

Pipeline DevSecOps complet

Voici l’architecture type d’un pipeline qui intègre toute la suite :

stages: [build, test, security, package, dast, deploy]

include:
  - template: Security/SAST.gitlab-ci.yml
  - template: Security/Secret-Detection.gitlab-ci.yml
  - template: Security/Dependency-Scanning.gitlab-ci.yml
  - template: Security/Container-Scanning.gitlab-ci.yml
  - template: DAST.gitlab-ci.yml

build:
  stage: build
  script: [pip install -r requirements.txt, python -m py_compile src/app.py]

docker-build:
  stage: package
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

container_scanning:
  variables:
    CS_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  needs: [docker-build]

dast:
  variables:
    DAST_WEBSITE: "https://staging.example.com"
  needs: [deploy-staging]
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

Les jobs SAST, secret detection et dependency scanning sont créés automatiquement par les templates inclus — zéro configuration pour eux. Tu n’as qu’à configurer container scanning (pointer vers ton image) et DAST (URL de staging). Le tout s’intègre avec le système de needs vu au cours précédent : le container scanning attend le build Docker, le DAST attend le deploy en staging.

🎯 Sur GitLab Ultimate, tu peux définir des Security Policies qui forcent l’exécution de certains scans même si le développeur ne les inclut pas, et des Scan Result Policies qui bloquent les MR si des vulnérabilités critiques sont détectées (avec approbation requise de l’équipe sécurité).

Pièges et bonnes pratiques

🎯 Commence par monitorer : active les scans en mode observation avant de bloquer les MR. Ton équipe doit comprendre les résultats et gérer les faux positifs.

🎯 Gère les faux positifs : dismiss avec une justification, ne désactive pas le scanner. Un scanner ignoré est pire que pas de scanner.

🎯 Protège tes secrets CI : variables masked + protected. Les runners qui déploient en production ne devraient pas exécuter du code non-vérifié.

🎯 Scanne régulièrement : les bases de CVE évoluent quotidiennement. Un pipeline schedulé hebdomadaire sur tes branches principales attrape les nouvelles vulnérabilités sans attendre un commit.

🎯 Shift left : pre-commit hooks (gitleaks, semgrep) + IDE plugins pour attraper les problèmes le plus tôt possible. Le CI est le filet de sécurité, pas la première ligne de défense.

🎯 Intégration d’outils tiers : si les scanners natifs ne suffisent pas, tu peux intégrer SonarQube, Snyk, ou Checkov (pour l’IaC) comme jobs supplémentaires dans ton pipeline. GitLab supporte le format JUnit pour les rapports, ce qui permet une intégration standardisée.

Le workflow de gestion des vulnérabilités dans GitLab suit quatre étapes : DetectedConfirmed (vrai problème) → Dismissed (faux positif) ou Resolved (corrigé). Le dashboard Security agrège tout par projet ou par groupe, avec filtres par scanner, sévérité et statut.

En entreprise, l’approche qui fonctionne : commence par activer SAST + secret detection (léger, rapide), puis ajoute dependency scanning, puis container scanning une fois que tu as des images Docker, et enfin DAST quand tu as un environnement de staging stable. Chaque couche renforce la précédente.

Le prochain cours couvre le déploiement en production avec GitLab : environments, review apps et Auto DevOps. 🚀

🖥️ Pratique sur ton propre serveur

Pour suivre GitLab CI/CD en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.

Obtenir 200$

Articles liés