Mod security
| Fiche express | |
|---|---|
| Type | WAF (pare-feu applicatif web), moteur de règles |
| Génération actuelle | v3 (libModSecurity + connecteurs)
|
| Jeu de règles de référence | OWASP Core Rule Set (CRS) |
| Licence | Apache License 2.0 |
| Voir aussi | Nginx · Certbot · Securiser nginx |
ModSecurity (souvent désigné par son nom de module historique mod_security / mod_security2) est un moteur de pare-feu applicatif web (Web Application Firewall, WAF) open source, multiplateforme, qui inspecte le trafic HTTP(S) en temps réel afin de détecter et de bloquer les attaques applicatives (injection SQL, XSS, traversée de chemin, etc.). Le moteur est généralement couplé à l'OWASP Core Rule Set (CRS), le jeu de règles de référence, qui fournit la couverture de détection effective.
Le projet, créé par Ivan Ristić en 2002, a été maintenu par Breach Security puis Trustwave
SpiderLabs, avant d'être transféré à la Fondation OWASP en février 2024. Il est désormais
publié sous le nom OWASP ModSecurity (dépôt github.com/owasp-modsecurity) et
licencié sous Apache License 2.0.
Vue d'ensemble
ModSecurity ne « connaît » aucune attaque par lui-même : c'est un moteur d'exécution de règles. On lui fournit des règles écrites dans le langage SecRules (les siennes, ou plus généralement le CRS), il les applique à chaque transaction HTTP et déclenche des actions (journaliser, refuser, rediriger…) selon les correspondances.
Trois fonctions principales :
- Surveillance et contrôle d'accès en temps réel sur le trafic HTTP entrant et sortant ;
- Journalisation complète du trafic (audit logging) à des fins d'analyse et de forensic ;
- Durcissement applicatif (virtual patching) : corriger une vulnérabilité par une règle WAF sans toucher au code de l'application.
Architecture : v2 (module Apache) vs v3 (libModSecurity)
C'est le point le plus important à comprendre, car les deux générations coexistent et n'ont pas la même architecture.
| ModSecurity v2 (mod_security2) | ModSecurity v3 (libModSecurity) | |
|---|---|---|
| Nature | Module Apache natif, embarqué dans httpd |
Bibliothèque C++ autonome (libmodsecurity), indépendante du serveur
|
| Serveur web | Apache uniquement (couplage fort) | Apache, Nginx, IIS via des connecteurs séparés |
| Couplage serveur | Le module est le pont avec Apache | Le serveur dialogue avec la lib via un connecteur (ex. ModSecurity-nginx, ModSecurity-apache) |
| Statut | Maintenu (branche 2.9.x, ex. 2.9.12) | Génération recommandée (branche 3.0.x, ex. 3.0.14) |
| Réécriture | Code historique Apache-centré | Réécriture complète, multiplateforme |
Dans le modèle v3, le moteur de règles est décorrélé du serveur web. Chaque connecteur (ModSecurity-nginx, etc.) a son propre cycle de vie et n'embarque que ce qui est nécessaire.
<mermaid> flowchart LR
subgraph V2["ModSecurity v2 (Apache)"]
A2[Client HTTP] --> B2[Apache httpd]
B2 --> C2[mod_security2
moteur intégré]
C2 --> D2[Application]
end
subgraph V3["ModSecurity v3 (libModSecurity)"]
A3[Client HTTP] --> B3[Nginx / Apache / IIS]
B3 --> C3[Connecteur
ex. ModSecurity-nginx]
C3 --> E3[libmodsecurity
moteur de règles]
E3 --> C3
C3 --> D3[Application]
end
</mermaid>
Fonctionnement
Les cinq phases de traitement
ModSecurity découpe chaque transaction HTTP en cinq phases. Toute règle s'attache à une phase
via l'action phase:. C'est ce qui détermine à quel moment du cycle de vie de
la requête la règle est évaluée et quelles données sont alors disponibles.
| Phase | Nom | Données disponibles |
|---|---|---|
| 1 | Request headers | Méthode, URI, en-têtes de requête |
| 2 | Request body | Corps de la requête (formulaires, JSON, XML, fichiers) |
| 3 | Response headers | En-têtes de réponse générés par l'application |
| 4 | Response body | Corps de la réponse (fuite de données, messages d'erreur…) |
| 5 | Logging | Phase finale, non disruptive : journalisation uniquement |
L'essentiel de la détection des attaques entrantes se fait en phases 1 et 2 ; la détection de fuites et le data leakage en phases 3 et 4.
<mermaid> flowchart TD
R[Requête HTTP entrante] --> P1[Phase 1
Request Headers] P1 --> P2[Phase 2
Request Body] P2 --> APP[Application web] APP --> P3[Phase 3
Response Headers] P3 --> P4[Phase 4
Response Body] P4 --> P5[Phase 5
Logging] P5 --> RESP[Réponse au client] P1 -. blocage possible .-> BLOCK[Action disruptive
deny / redirect / drop] P2 -. blocage possible .-> BLOCK
</mermaid>
Modèles de sécurité
- Modèle négatif (blacklist) : on laisse tout passer sauf ce qui ressemble à une attaque connue. C'est l'approche du CRS. Souple, mais sujet aux contournements et aux faux positifs.
- Modèle positif (whitelist) : on n'accepte que ce qui est explicitement reconnu comme valide. Très robuste, mais coûteux à maintenir ; adapté aux applications stables et peu évolutives.
Le langage SecRules
Une règle suit la structure :
SecRule VARIABLES "OPERATEUR" "ACTIONS"
Exemple — refuser une requête contenant une balise <script> dans n'importe quel
paramètre :
SecRule ARGS "@rx <script>" \
"id:1000,\
phase:2,\
t:none,t:urlDecode,t:lowercase,\
deny,status:403,\
log,msg:'Tentative XSS détectée',\
tag:'attack-xss',severity:'CRITICAL'"
Les quatre briques :
- Variables / collections — ce que l'on inspecte :
ARGS,REQUEST_HEADERS,REQUEST_URI,REQUEST_FILENAME,REQUEST_BODY,RESPONSE_BODY,REMOTE_ADDR,FILES, ainsi que les collections persistantesTX(transaction),IP,SESSION,GEO. - Opérateurs (préfixés
@) — comment on compare :@rx(regex),@pm/@pmFromFile(recherche multi-motifs),@eq,@ge,@streq,@beginsWith,@contains,@ipMatch,@detectSQLi,@detectXSS,@validateByteRange. - Transformations (préfixées
t:) — normalisation avant comparaison, pour contrer l'évasion :t:none,t:lowercase,t:urlDecode,t:htmlEntityDecode,t:compressWhitespace,t:normalizePath. Elles s'enchaînent. - Actions — quoi faire :
- disruptives :
deny,drop,redirect,pass,allow,block; - de flux :
chain(enchaîner des conditions en ET logique),skip,skipAfter; - de métadonnée :
id(obligatoire et unique),phase,msg,tag,severity,ver; - de variable :
setvar,capture; - non disruptives :
log/nolog,auditlog/noauditlog,ctl(modifier le moteur à la volée pour la transaction en cours).
- disruptives :
OWASP Core Rule Set (CRS)
Le CRS est le jeu de règles génériques de référence pour ModSecurity. Il couvre le Top Ten OWASP (injections SQL, XSS, LFI/RFI, fixation de session…) et constitue, en pratique, ce qui rend un déploiement ModSecurity utile.
Versions à connaître :
- CRS 4.x : branche actuelle (ex. 4.27.0), architecture à plugins. La 4.25.0 est la première version LTS de la branche 4.
- CRS 3.3.x : version majeure précédente. Fin de support prévue T3 2026 — toute installation encore en 3.3 doit planifier sa migration.
Score d'anomalie (anomaly scoring)
Depuis le CRS 3, le mode par défaut n'est plus le blocage règle-par-règle mais le score d'anomalie collaboratif :
- Chaque règle qui correspond n'ajoute pas un blocage immédiat : elle incrémente un score dans
TXselon sa sévérité (CRITICAL = 5, ERROR = 4, WARNING = 3, NOTICE = 2). - À la fin de la phase, le score cumulé est comparé à un seuil (par défaut 5 en entrée, 4 en sortie).
- Si le seuil est dépassé, la transaction est bloquée.
L'intérêt : une requête qui déclenche plusieurs petites règles « suspectes » est bloquée, alors qu'une seule correspondance faible ne l'est pas — ce qui réduit fortement les faux positifs.
<mermaid> flowchart TD
REQ[Requête] --> R1[Règle CRS A
+3] REQ --> R2[Règle CRS B
+5] REQ --> R3[Règle CRS C
+2] R1 --> SUM[Score cumulé TX] R2 --> SUM R3 --> SUM SUM --> T{Score >= seuil
par défaut 5 ?} T -->|Oui| DENY[Blocage] T -->|Non| PASS[Laisser passer]
</mermaid>
Niveaux de paranoïa (paranoia levels)
Le CRS gradue son agressivité de PL1 (par défaut, peu de faux positifs) à PL4
(détection maximale, beaucoup de faux positifs, réservé aux environnements très sensibles avec
tuning poussé). En CRS 4, le réglage se fait via tx.blocking_paranoia_level et
tx.detection_paranoia_level dans crs-setup.conf.
Installation
v2 — module Apache
# Debian/Ubuntu
apt install libapache2-mod-security2
a2enmod security2
# Le fichier de recommandations sert de base de configuration
cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
systemctl restart apache2
v3 — connecteur Nginx
Sur Nginx, ModSecurity v3 s'installe via libmodsecurity + le module
ModSecurity-nginx (souvent fourni par le paquet
libnginx-mod-http-modsecurity), puis on l'active dans le bloc serveur :
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
Kubernetes — ingress-nginx
Dans un cluster (RKE2, par exemple), l'ingress-nginx controller embarque ModSecurity v3 + CRS. On l'active par annotations ou via la ConfigMap du contrôleur :
# Annotations sur l'Ingress
nginx.ingress.kubernetes.io/enable-modsecurity: "true"
nginx.ingress.kubernetes.io/enable-owasp-core-rules: "true"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleEngine On
SecAuditEngine RelevantOnly
C'est l'approche idéale pour mutualiser un WAF en frontal de plusieurs services derrière un même ingress.
Configuration de base
Le cœur de la configuration tient en quelques directives, généralement dans
modsecurity.conf :
# Activation : Off | On | DetectionOnly
SecRuleEngine DetectionOnly
# Inspection du corps de requête (indispensable pour la phase 2)
SecRequestBodyAccess On
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
# Inspection du corps de réponse (détection de fuites)
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml application/json
# Journal d'audit
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLog /var/log/modsec_audit.log
SecAuditLogParts ABIJDEFHKZ
SecAuditLogType Serial
# Action par défaut des règles
SecDefaultAction "phase:2,log,auditlog,pass"
Management et exploitation
C'est la partie qui occupe le plus de temps dans la durée. Un WAF se gère, il ne s'installe pas une fois pour toutes.
Cycle de mise en production : DetectionOnly d'abord
Ne jamais passer directement en SecRuleEngine On en production. Le déroulé
recommandé :
- Déployer en
SecRuleEngine DetectionOnly: les règles évaluent et journalisent, mais ne bloquent rien. - Laisser tourner sur du trafic réel (jours/semaines) et collecter les correspondances.
- Analyser les déclenchements : distinguer vraies attaques et faux positifs (requêtes légitimes bloquées à tort).
- Écrire les exclusions nécessaires (voir ci-dessous).
- Basculer en
SecRuleEngine Onune fois le bruit maîtrisé.
<mermaid> flowchart LR
A[DetectionOnly] --> B[Collecte
des logs] B --> C{Faux
positifs ?} C -->|Oui| D[Écrire
exclusions] D --> B C -->|Non / maîtrisés| E[SecRuleEngine On] E --> F[Supervision
continue] F --> C
</mermaid>
Tuning des faux positifs
Quatre leviers, du plus large au plus chirurgical :
- Retirer une règle entière (statique, dans la conf) :
SecRuleRemoveById 920350
SecRuleRemoveByTag "attack-protocol"
- Retirer une règle à l'exécution, conditionnée à un contexte (URL, paramètre…) :
SecRule REQUEST_URI "@beginsWith /api/upload" \
"id:10000,phase:1,pass,nolog,ctl:ruleRemoveById=920350"
- Exclure une cible précise d'une règle (le plus chirurgical, à privilégier) :
SecRuleUpdateTargetById 942100 "!ARGS:description"
- Plugins d'exclusion CRS : pour les applications connues (WordPress, Drupal, Nextcloud…), le CRS 4 fournit des plugins d'exclusion prêts à l'emploi, à déposer dans le répertoire
plugins/.
Règle d'or : préférer toujours l'exclusion la plus ciblée possible (une cible sur une URL donnée) plutôt que de désactiver une règle globalement.
Journal d'audit
Le journal d'audit est structuré en sections lettrées, sélectionnées par
SecAuditLogParts :
| Partie | Contenu |
|---|---|
| A | En-tête de l'entrée (obligatoire) |
| B | En-têtes de requête |
| C | Corps de requête |
| E | Corps de réponse |
| F | En-têtes de réponse |
| H | Pied de page (règles déclenchées, infos moteur) |
| I | Alternative compacte à C |
| J | Informations sur les fichiers téléversés |
| K | Liste de toutes les règles ayant correspondu |
| Z | Borne finale (obligatoire) |
SecAuditLogType peut être Serial (tout dans un fichier, simple mais
verrouillage sous forte charge) ou Concurrent (un fichier par transaction, requis
pour expédier vers un collecteur distant).
Supervision et intégration SIEM
En exploitation, les journaux ModSecurity ont vocation à être centralisés, pas relus à la main. Schéma type :
- Le moteur écrit l'audit log (idéalement en JSON, supporté en v3) ;
- Un agent de collecte (Fluent Bit, Promtail…) expédie les lignes ;
- Stockage et indexation (par ex. Loki) ;
- Visualisation et alerting (Grafana) ;
- Règles de détection (par ex. Sigma) pour lever des alertes sur les patterns d'attaque récurrents.
Cela permet de corréler les déclenchements WAF avec le reste de la télémétrie sécurité et de distinguer un balayage opportuniste d'une attaque ciblée.
Mises à jour
Deux composants à maintenir séparément :
- Le moteur (libmodsecurity / module) : à tenir à jour pour les CVE — plusieurs ont été corrigées sur la branche 3.0.x en 2025 (DoS, gestion d'erreur, fuites mémoire). Surveiller les releases OWASP ModSecurity.
- Le CRS : à mettre à jour régulièrement (nouvelles détections, correctifs de contournements). Attention : toute montée de version CRS peut introduire de nouveaux faux positifs → retester en
DetectionOnlyavant de rebasculer.
Pièges et bonnes pratiques
- Coût en performance : un CRS complet augmente sensiblement la consommation CPU/mémoire (évaluation des règles + journalisation). Mesurer avant/après, surtout sur les corps volumineux.
- Faux positifs : c'est le principal motif d'abandon. Les applications dynamiques (éditeurs riches, page builders, API REST) déclenchent facilement des règles. D'où le passage obligé par
DetectionOnly. - Limites de taille de corps : un corps qui dépasse
SecRequestBodyLimitn'est pas inspecté → angle mort exploitable. Accompagner d'une règle qui refuse au-delà de la limite. - Le WAF n'est pas une excuse : c'est une couche de défense en profondeur, pas un substitut au durcissement applicatif (mises à jour, authentification, validation côté serveur).
- Versionner sa configuration : conf moteur,
crs-setup.confet fichiers d'exclusions doivent vivre en Git, déployés de façon reproductible.
Voir aussi
- Nginx — serveur web pouvant être protégé par ModSecurity v3
- Certbot — TLS, complémentaire au WAF
- Securiser nginx — durcissement Nginx
Liens externes
- https://owasp.org/www-project-modsecurity/ — Projet OWASP ModSecurity
- https://coreruleset.org/ — OWASP Core Rule Set
- https://github.com/owasp-modsecurity/ModSecurity — Dépôt GitHub officiel