Aller au contenu principal

OWASP ZAP : comment implémenter un audit DAST automatisé avec Symfony et Docker

Passer du SAST au DAST en intégrant OWASP ZAP à votre workflow local via Docker et Castor. Un guide technique pour un audit de sécurité automatisé.
Catégorie

Sécurité

Est-ce que htmlspecialchars suffit vraiment à dormir sur ses deux oreilles ? Ne laissez pas la sécurité de vos applications au hasard et adoptez les réflexes de défense des experts.

Lecture
4 min
Niveau
Intermédiaire
janv 18 2026
Partager

Du SAST au DAST

Dans l'écosystème de la sécurité applicative moderne, on distingue deux approches complémentaires :

  • SAST (Static Application Security Testing) : analyse le code source (ex: PHPStan, SonarQube). Il trouve les erreurs de logique, le code mort, ou les mauvaises pratiques de codage.
  • DAST (Dynamic Application Security Testing) : analyse l'application en cours d'exécution (ex: OWASP ZAP, Burp Suite). Il simule des attaques réelles (XSS, SQLi, Broken Access Control) en interagissant avec le serveur HTTP.

Je vais détailler l'intégration technique d'OWASP ZAP (Zed Attack Proxy) , le tout orchestrée par Castor et Docker. L'objectif est de fournir un audit de sécurité reproductible, automatisable et intégré au flux de développement local.

Architecture de l'intégration

L'intégration repose sur trois composants clés :

  1. L'image Docker officielle zaproxy/zap-stable : Un conteneur autonome contenant le moteur de scan.
  2. L'Automation Framework : Un fichier de configuration YAML (zap.yaml) qui remplace les appels CLI complexes et définit le plan de scan.
  3. L'orchestrateur Castor : Une couche d'abstraction PHP (.castor/security.php) qui gère la complexité de l'interconnexion réseau Docker.

Le pont réseau Docker

Le défi majeur lors de l'exécution d'un scanner DAST conteneurisé est l'accès à l'application cible (https://lecodeestdanslepre.local) qui tourne sur la machine hôte.

Par défaut, un conteneur Docker réside dans son propre réseau isolé. Il ne peut pas résoudre les domaines locaux de l'hôte. L'implémentation dans .castor/security.php contourne cette limitation via le flag --add-host :

PHP
// .castor/security.php

$dockerArgs = [
    'docker', 'run', '--rm',
    // ...
    '--add-host',
    parse_url($target, PHP_URL_HOST) . ':host-gateway', // 👈 Mapping DNS dynamique
    'zaproxy/zap-stable',
];

Explication technique :

  • host-gateway est une valeur spéciale reconnue par Docker qui résout vers l'IP de l'interface du pont Docker sur l'hôte.
  • J'injecte dynamiquement une entrée dans le /etc/hosts du conteneur ZAP qui mappe le domaine cible (lecodeestdanslepre.local) vers cette passerelle.
  • Cela permet au scanner d'atteindre le serveur web local sans configuration réseau complexe (bridge, host mode) qui varierait selon les OS (Mac/Linux).

L'automatisation

Plutôt que d'utiliser le script "quick scan" (zap-baseline.py) qui est difficilement configurable, j'utilise l'Automation Framework de ZAP. C'est une approche "Configuration as Code" qui définit le périmètre de l'audit.

Voici l'analyse du fichier zap.yaml du projet :

YAML
env:
  contexts:
  - name: baseline
    urls:
    - https://lecodeestdanslepre.local
    excludePaths:
    - "http(s)?://.*/_profiler.*" # Exclusion critique
    - "http(s)?://.*/_wdt.*"

Gestion du bruit

L'exclusion des chemins _profiler et _wdt est critique.

  • Pourquoi ? Le Web Profiler de Symfony expose intentionnellement des informations sensibles (configuration, requêtes SQL, variables d'environnement) pour le débogage.
  • Conséquence sans exclusion : ZAP lèverait des centaines d'alertes "Information Disclosure" (FP - Faux Positifs) qui noieraient les vraies vulnérabilités.

Les jobs

Le plan d'exécution est séquentiel :

  1. Spider (Crawler) :

    YAML
    - type: spider
      parameters:
        maxDuration: 1 # Timeout strict
    

    Explore récursivement l'application pour cartographier la surface d'attaque. Le maxDuration est fixé à 1 minute pour garantir un feedback rapide en développement.

  2. Passive Scan :

    YAML
    - type: passiveScan-wait
    

    Analyse le trafic HTTP généré par le spider sans envoyer de nouvelles requêtes malveillantes. Il détecte :

    • Absence d'en-têtes de sécurité (CSP, HSTS, X-Content-Type-Options).
    • Cookies sans indicateurs Secure ou HttpOnly.
    • Fuites d'information dans les réponses (Stack traces).
  3. Report : Génère un rapport HTML statique dans le volume monté /zap/wrk/ (mappé vers var/zap/ sur l'hôte).

Interprétation des résultats et Remédiation

Le rapport généré (var/zap/zap-report.html) classe les vulnérabilités selon le standard CVSS.

Points de vigilance

  • CSP (Content Security Policy) : ZAP détectera une policy manquante ou trop permissive. La correction se fait via security.php, nelmio_security.php ou un Listener dédié.
  • Cookies de Session : Assurez-vous que framework.session.cookie_secure: auto et cookie_httponly: true sont bien configurés.
  • Anti-CSRF Tokens : ZAP tentera de soumettre les formulaires. Si vos formulaires Symfony utilisent form_rest(), le token CSRF est inclus, mais attention aux formulaires HTML manuels.

Le mot de la fin

Intégrer OWASP ZAP directement dans l'outillage local permet de traiter la sécurité comme une composante standard du cycle de développement, et non plus comme une étape finale de validation.

Grâce à l'abstraction fournie par Castor et à la configuration déclarative de l'Automation Framework, chaque développeur dispose d'un retour immédiat sur la robustesse de son application, permettant de corriger les failles structurelles avant même le premier commit.

0 réaction

Poursuivre la lecture

Sélectionné avec soin pour vous.

Sécurité & 2FA : la forteresse numérique

Sécurisez vos utilisateurs avec une 2FA robuste (OTPHP, QrCode).

CSP : le gilet pare-balles de votre site web

Comprendre les failles des Allow-lists, implémenter les Nonces cryptographiques dans Symfony et sécuriser le DOM avec Trusted Types.

Meilisearch : l'art de la recherche instantanée

Marre du SQL LIKE ? Découvrez comment intégrer Meilisearch à Symfony pour une recherche résiliente, asynchrone et une latence inférieure à 50ms.