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 :
- L'image Docker officielle
zaproxy/zap-stable: Un conteneur autonome contenant le moteur de scan. - L'Automation Framework : Un fichier de configuration YAML (
zap.yaml) qui remplace les appels CLI complexes et définit le plan de scan. - 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 :
// .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-gatewayest 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/hostsdu 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 :
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 :
-
Spider (Crawler) :
YAML- type: spider parameters: maxDuration: 1 # Timeout strictExplore récursivement l'application pour cartographier la surface d'attaque. Le
maxDurationest fixé à 1 minute pour garantir un feedback rapide en développement. -
Passive Scan :
YAML- type: passiveScan-waitAnalyse 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
SecureouHttpOnly. - Fuites d'information dans les réponses (Stack traces).
-
Report : Génère un rapport HTML statique dans le volume monté
/zap/wrk/(mappé versvar/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.phpou un Listener dédié. - Cookies de Session : Assurez-vous que
framework.session.cookie_secure: autoetcookie_httponly: truesont 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.