Aller au contenu

SAST et DAST

Analyse statique et dynamique du code — intégrer la sécurité dans le pipeline CI sans ralentir les équipes.


Vue d'ensemble

graph LR
    subgraph "SAST — avant execution"
        S1["Code source"] --> S2["Semgrep / CodeQL"]
        S2 --> S3["Rapport vulnerabilites"]
    end
    subgraph "DAST — pendant/apres execution"
        D1["Application lancee"] --> D2["ZAP / Nuclei"]
        D2 --> D3["Rapport vulns runtime"]
    end
    subgraph "SCA — dependances"
        C1["Manifest fichiers"] --> C2["Snyk / grype"]
        C2 --> C3["CVE dans deps"]
    end
Type Analyse Quand Avantages Limites
SAST Code source statique Pre-merge, CI Rapide, pas de runtime requis Faux positifs, logique métier
DAST Application en exécution Post-deploy Vulnérabilités réelles, runtime Plus lent, environnement nécessaire
SCA Dépendances CI, continu CVE connues, exhaustif Vulnérabilités connues uniquement
IAST Runtime + instrumentation Tests Précis, peu de faux positifs Nécessité agent, overhead

SAST : analyse statique

Semgrep

Outil polyvalent, très configurable, règles communautaires pour Python, JS, Go, Java, etc.

# Installation
pip install semgrep

# Scanner avec les regles de securite OWASP
semgrep --config "p/owasp-top-ten" .

# Scanner avec regles specifiques Python
semgrep --config "p/python" --config "p/secrets" .

# Ignorer des faux positifs avec commentaire inline
result = subprocess.run(cmd, shell=True)  # nosemgrep: subprocess-shell-true

Règle Semgrep personnalisee

# .semgrep/custom-rules.yml
rules:
  - id: hardcoded-jwt-secret
    patterns:
      - pattern: |
          JWT_SECRET = "..."
      - pattern-not: |
          JWT_SECRET = os.environ[...]
    message: "Secret JWT code en dur detecte"
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      cwe: "CWE-798"

CodeQL

Analyse semantique profonde du code, intégré nativement dans GitHub Advanced Security.

# .github/workflows/codeql.yml
name: CodeQL
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    strategy:
      matrix:
        language: [python, javascript]
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: security-and-quality
      - uses: github/codeql-action/autobuild@v3
      - uses: github/codeql-action/analyze@v3

SonarQube / SonarCloud

Plateforme complète : qualité de code + sécurité + dette technique.

# .github/workflows/sonar.yml
- name: SonarCloud Scan
  uses: SonarSource/sonarcloud-github-action@master
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# sonar-project.properties
sonar.projectKey=org_project
sonar.sources=src
sonar.exclusions=**/tests/**,**/node_modules/**
sonar.python.version=3.11

Voir aussi

La configuration détaillée de Semgrep et SonarQube est couverte dans le tutoriel Qualité de Code.

DAST : analyse dynamique

OWASP ZAP (Zed Attack Proxy)

Proxy d'interception qui teste une application en cours d'exécution.

# Scan rapide en ligne de commande (Docker)
docker run -t owasp/zap2docker-stable zap-baseline.py \
  -t https://myapp.staging.example.com \
  -r zap-report.html

# Scan complet (plus long, plus exhaustif)
docker run -t owasp/zap2docker-stable zap-full-scan.py \
  -t https://myapp.staging.example.com \
  -r zap-full-report.html \
  -J zap-report.json
# Integration CI — GitHub Actions
- name: ZAP Baseline Scan
  uses: zaproxy/action-baseline@v0.10.0
  with:
    target: "https://myapp.staging.example.com"
    rules_file_name: ".zap/rules.tsv"
    cmd_options: "-a"

Nuclei

Scanner de vulnérabilités base sur des templates YAML, très rapide.

# Installation
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

# Mise a jour des templates
nuclei -update-templates

# Scanner une application
nuclei -u https://myapp.staging.example.com -t cves/ -t vulnerabilities/

# Scanner avec severite minimale
nuclei -u https://myapp.staging.example.com -severity critical,high

# Template personnalise
cat > templates/custom-api-check.yaml << 'EOF'
id: api-debug-endpoint
info:
  name: Debug endpoint expose
  severity: medium
http:
  - method: GET
    path:
      - "{{BaseURL}}/debug"
      - "{{BaseURL}}/api/debug"
    matchers:
      - type: status
        status: [200]
EOF

Gestion des faux positifs

Un scan SAST typique produit 20 a 60% de faux positifs. Une gestion rigoureuse evite l'alert fatigue.

Processus de triage

flowchart TD
    A[Alerte SAST/DAST] --> B{Code reellement vulnerable ?}
    B -->|Oui| C{Exploitable en pratique ?}
    B -->|Non| D[Marquer faux positif + justification]
    C -->|Oui| E[Ouvrir ticket securite avec severite]
    C -->|Non| F[Accepted Risk + revue annuelle]
    E --> G[Corriger avant merge ou dans sprint securite]
    D --> H[Ajouter suppression commentee dans le code]

Suppressions documentees

# Semgrep — suppression inline avec justification
password = hashlib.md5(data).hexdigest()  # nosemgrep: md5-used
# Justification: utilise pour checksum non-securite (deduplication fichiers)
# Pas de donnees sensibles, pas d'usage cryptographique

# CodeQL — fichier de configuration d'exclusions
# .github/codeql/codeql-config.yml
name: "CodeQL config"
query-filters:
  - exclude:
      id: py/clear-text-logging-sensitive-data
      # Exclusion justifiee : les donnees loguees sont anonymisees en amont

Pipeline CI complet

# .github/workflows/security.yml
name: Security Pipeline
on: [push, pull_request]

jobs:
  sast:
    name: SAST (Semgrep)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: returntocorp/semgrep-action@v1
        with:
          config: >-
            p/owasp-top-ten
            p/secrets
            p/python

  secrets-scan:
    name: Secrets Detection
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2

  sca:
    name: SCA (Dependances)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Snyk vulnerability scan
        uses: snyk/actions/python@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

  dast:
    name: DAST (ZAP)
    runs-on: ubuntu-latest
    needs: [sast]
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: zaproxy/action-baseline@v0.10.0
        with:
          target: ${{ vars.STAGING_URL }}

Comparatif des outils

Outil Type Points forts Limites
Semgrep SAST Rapide, règles custom simples, multi-lang Moins profond que CodeQL
CodeQL SAST Analyse semantique, intégration GitHub Lent sur gros projets, GitHub only
SonarQube SAST Dashboard riche, tendances, qualité+secu Complexe a hoster, licence pro chere
OWASP ZAP DAST Open source, complet, CI-friendly Lent, configuration initiale
Nuclei DAST Très rapide, templates communautaires Moins adapté aux apps custom
Snyk SCA Intégration IDE, remédiation auto Freemium, coûteux en scale
grype/trivy SCA Gratuit, Docker-native, SBOM support Moins de contexte que Snyk

Chapitre suivant : Bonnes pratiques — secure by design, validation et headers de sécurité.