ModSecurity sous la garde de l'OWASP : choisir entre v2, v3 et Coraza, régler le CRS, corriger l'erreur Response body too large et réagir face à php2shell.
ModSecurity est le moteur de pare-feu applicatif web (WAF) open source le plus répandu : il s'insère dans Apache, Nginx ou IIS, inspecte chaque requête et chaque réponse HTTP, puis applique des règles écrites en langage SecLang, le plus souvent celles de l'OWASP CRS (Core Rule Set). Repris par l'OWASP en 2024 après le retrait de Trustwave, le projet est bien vivant en 2026, avec les versions 2.9.15 et 3.0.17 publiées le 29 septembre. Il reste pourtant souvent mal exploité : erreurs « Response body too large », faux positifs jamais traités, mode détection oublié en production. La crise php2shell d'octobre 2026 a rappelé à la fois son utilité comme correctif virtuel et ses limites. Fonctionnement du moteur, choix entre v2, v3 et Coraza, réglage du CRS, diagnostic des erreurs courantes et intégration DevSecOps : voici l'essentiel pour l'exploiter correctement. Pour la déclinaison managée en périphérie de réseau, consultez notre article pilier sur les règles et la configuration du WAF Cloudflare.
Résumé exécutif : ModSecurity est un moteur WAF open source maintenu par l'OWASP, décliné en module Apache (v2) et en bibliothèque libModSecurity (v3) pour Nginx. Sa protection repose sur l'OWASP CRS, qui additionne un score d'anomalie et bloque dès qu'un seuil est atteint, avec quatre niveaux de paranoïa. Les difficultés courantes viennent des limites de mise en mémoire tampon, comme l'erreur « Response body too large », et des faux positifs mal traités. Face à php2shell, ModSecurity a pu servir de patch virtuel, sans jamais remplacer la mise à jour de PHP.
Points clés de cet article :
- Maintenez le moteur et le CRS à jour : les versions 2.9.15 et 3.0.17 de septembre 2026 corrigent plusieurs vulnérabilités du WAF lui-même.
- Démarrez en DetectionOnly ou avec des seuils très élevés, puis fixez une date de passage en blocage avec un seuil entrant de 5.
- Traitez chaque faux positif par une exclusion étroite (une règle, un paramètre, une URL), documentée et versionnée.
- Corrigez l'erreur « Response body too large » par ProcessPartial et une liste de types MIME réduite, plutôt qu'en multipliant la limite.
- Face à une faille comme php2shell, utilisez le WAF pour gagner du temps, mais appliquez le correctif et redémarrez les workers sans attendre.
ModSecurity : définition, origine et statut en 2026
ModSecurity : moteur de pare-feu applicatif web open source, sous licence Apache 2.0, qui analyse le trafic HTTP en plusieurs phases et exécute des règles SecLang permettant de journaliser, de détecter ou de bloquer des requêtes et des réponses malveillantes, sans modifier le code de l'application protégée.
Le projet est né en 2002 sous la forme d'un module Apache écrit par Ivan Ristić. Il est passé chez Breach Security, qui a publié la version 2.0 en 2006, puis chez Trustwave à partir de 2010. Trustwave l'a placé sous licence Apache 2.0, ce qui a permis à de nombreux éditeurs de l'intégrer à leurs produits, puis l'a porté vers IIS et Nginx en 2012.
La page du projet OWASP ModSecurity le décrit comme le moteur WAF open source de référence, utilisé par des entreprises, des administrations, des hébergeurs et des éditeurs de WAF commerciaux. Le moteur fournit le langage de règles et l'analyse du trafic ; la détection proprement dite vient du jeu de règles qui lui est associé, presque toujours l'OWASP CRS.
De Trustwave à l'OWASP
Trustwave avait annoncé l'arrêt de son support du code open source au 1er juillet 2024. Pour éviter l'abandon du projet, l'OWASP en a pris la garde, avec une transition commencée le 25 janvier 2024. Ce transfert réunit sous la même fondation le moteur et le CRS, avec des responsables de projet communs, une gouvernance ouverte et une documentation désormais publiée sur modsecurity.org.
Cette période d'incertitude a laissé des traces. F5 a retiré son module commercial NGINX ModSecurity WAF, arrivé en fin de vie le 31 mars 2024, et une partie de la communauté s'est tournée vers Coraza, un moteur compatible écrit en Go. Beaucoup d'articles de 2022 ou 2023 annoncent encore la disparition de ModSecurity : ces analyses sont aujourd'hui dépassées et ne doivent plus guider un choix d'architecture.
Versions de ModSecurity maintenues en 2026
Deux lignées de ModSecurity coexistent. La branche v2, ou mod_security2, reste le module natif d'Apache httpd et existe aussi pour IIS. La branche v3, appelée libModSecurity, est une bibliothèque autonome reliée au serveur web par des connecteurs, principalement pour Nginx. Les deux ont reçu une mise à jour le 29 septembre 2026, en 2.9.15 et 3.0.17, détaillée sur la page des versions du dépôt OWASP ModSecurity.
Le rythme des correctifs justifie une veille active. En 2025, les versions 2.9.9 à 2.9.12 ont corrigé quatre vulnérabilités, dont trois dénis de service. En 2026, les versions 3.0.15 et 3.0.16 ont traité des dépassements de tampon et des défauts de l'analyseur multipart, et la 3.0.17 un contournement de l'inspection des réponses lié à la casse de l'en-tête Content-Type. Un WAF non mis à jour devient lui-même une surface d'attaque.
Un changement structurel mérite aussi l'attention : depuis la version 2.9.13, publiée en avril 2026, la branche v2 ne contient plus l'ancien module Nginx. Sous Nginx, seule la combinaison libModSecurity et connecteur ModSecurity-nginx reste pertinente. Les tutoriels qui compilent encore le module v2 pour Nginx décrivent donc une configuration obsolète, à ne pas reproduire.
Comment fonctionne le moteur : les cinq phases
ModSecurity découpe chaque transaction HTTP en cinq phases successives. Une règle déclare la phase dans laquelle elle s'exécute et ne voit que les données disponibles à ce moment-là. Comprendre ce découpage évite la plupart des règles inopérantes, comme une règle de phase 1 qui chercherait un paramètre POST encore inaccessible.
- Phase 1, en-têtes de requête : méthode, URI, en-têtes et cookies, avant la lecture du corps.
- Phase 2, corps de requête : paramètres de formulaire, JSON, XML et fichiers téléversés, une fois le corps analysé.
- Phase 3, en-têtes de réponse : code de statut et en-têtes renvoyés par l'application.
- Phase 4, corps de réponse : contenu de la page, à condition qu'il soit mis en mémoire tampon.
- Phase 5, journalisation : écriture du journal d'audit, sans possibilité de bloquer.
Ce découpage a des conséquences pratiques. Bloquer en phase 1 évite de lire un corps volumineux, mais empêche d'inspecter les paramètres envoyés en POST. Inspecter en phase 4 permet de repérer une fuite de données ou un message d'erreur SQL dans une page, mais impose de mettre la réponse en mémoire tampon, ce qui consomme de la mémoire et allonge le temps de réponse.
Règles SecLang : variables, opérateurs et actions
Écrite en SecLang, le langage de règles de ModSecurity, une règle combine quatre éléments. Les variables désignent ce qui est inspecté : ARGS pour les paramètres, REQUEST_HEADERS, REQUEST_COOKIES, FILES_NAMES ou RESPONSE_BODY. L'opérateur décrit le test : @rx pour une expression régulière, @pm pour une liste de mots, @streq pour une égalité stricte, @detectSQLi pour la bibliothèque libinjection. Les transformations, comme t:lowercase ou t:urlDecodeUni, normalisent la donnée avant le test.
Les actions précisent le comportement en cas de correspondance : pass, deny ou block, log, setvar pour incrémenter un score, ctl pour modifier la configuration le temps d'une transaction. Chaque règle porte un identifiant unique. La plage de 1 à 99 999 est réservée à l'usage local, ce qui évite toute collision avec les règles du CRS, numérotées entre 900 000 et 999 999.
ModSecurity v2, libModSecurity v3 ou Coraza : quel moteur choisir ?
Le choix du moteur dépend d'abord du serveur web et de l'architecture. Les trois options exécutent des règles SecLang et peuvent charger le CRS, mais elles diffèrent par leur forme, leur maturité et leur couverture des directives. La documentation officielle de ModSecurity signale par exemple plusieurs directives de la v2 rejetées ou ignorées par la v3, ce qui empêche de partager tel quel un fichier de configuration.
| Critère | ModSecurity v2 | libModSecurity v3 | OWASP Coraza |
|---|---|---|---|
| Forme | Module Apache (mod_security2), version IIS | Bibliothèque C++ et connecteurs, surtout Nginx | Bibliothèque Go et connecteurs (Caddy, Envoy, HAProxy) |
| Version de référence | 2.9.15 (septembre 2026) | 3.0.17 (septembre 2026) | Branche v3 du module Go |
| Couverture SecLang | Référence historique, la plus complète | Large, mais certaines directives v2 rejetées ou ignorées | Large, compatibilité CRS v4 revendiquée |
| Usage typique | Apache, hébergement mutualisé, Plesk ou cPanel | Nginx en frontal ou en reverse proxy | Architectures cloud natives, passerelles, maillage de services |
| Point d'attention | Lié à Apache ou IIS ; plus de module Nginx depuis la 2.9.13 | Parties I et K du journal d'audit absentes | Écosystème plus jeune, intégration propre à chaque connecteur |
En pratique, un parc Apache existant reste naturellement sur la v2, la plus éprouvée. Un frontal Nginx s'appuie sur la v3, en vérifiant chaque directive utilisée. Un nouveau projet fondé sur Envoy, Caddy ou des conteneurs gagne à évaluer Coraza. Dans tous les cas, le CRS reste commun, ce qui permet de conserver la même politique de détection et les mêmes exclusions d'un moteur à l'autre.
OWASP CRS : score d'anomalie et seuils de blocage
ModSecurity sans règles ne protège rien. Le moteur fournit le langage ; la détection vient du jeu de règles, presque toujours l'OWASP CRS, distribué sous licence Apache 2.0. Il couvre les grandes familles d'attaques web : injections SQL, XSS, inclusion de fichiers, exécution de commandes, violations de protocole. Pour revoir ces catégories, consultez notre guide sur l'OWASP Top 10 des vulnérabilités web.
Le principe du score d'anomalie
Le CRS ne bloque pas dès qu'une règle correspond. Selon la documentation du CRS sur le score d'anomalie, chaque détection ajoute des points selon sa gravité : 5 pour CRITICAL, 4 pour ERROR, 3 pour WARNING et 2 pour NOTICE. Une fois les règles de requête exécutées, le total est comparé au seuil entrant, fixé à 5 par défaut ; pour les réponses, le seuil sortant vaut 4.
Ce mécanisme dissocie la détection du blocage et permet de journaliser des requêtes « presque bloquées », très utiles pour le réglage. La documentation met en garde contre le relèvement durable des seuils : un seuil entrant supérieur à 5 laisse passer les attaques détectées par une seule règle critique, typiquement certaines inclusions de fichiers ou exécutions de commandes à distance.
Niveaux de paranoïa et cycle de vie du CRS
Choisir le niveau de paranoïa
Le niveau de paranoïa, ou PL, règle l'agressivité de l'OWASP CRS (Core Rule Set). Le PL1, par défaut, vise un taux de faux positifs quasi nul. Les PL2 et PL3 ajoutent des règles qui détectent davantage d'attaques au prix de fausses alertes plus nombreuses, et le PL4 signale presque tout, y compris beaucoup de trafic légitime. Le niveau se règle dans crs-setup.conf, par la règle 900000 et la variable tx.paranoia_level.
Une bonne pratique consiste à aligner le niveau sur la sensibilité de l'application : PL1 pour un site vitrine sans données personnelles, PL2 dès que des données personnelles sont traitées, PL3 pour des données financières ou de santé. Le niveau de paranoïa de détection, tx.detection_paranoia_level dans le CRS 4, permet aussi d'observer les règles du niveau supérieur sans les rendre bloquantes.
Versions du CRS et cycle de support
Le CRS suit son propre calendrier, distinct de celui du moteur. La branche 3.3 est arrivée en fin de vie au troisième trimestre 2026 ; la branche 4.25.x bénéficie d'un support long (LTS) jusqu'au troisième trimestre 2027, en parallèle des deux dernières versions stables. La migration vers le CRS 4 modifie le modèle de journalisation et introduit les greffons, qui remplacent les anciennes exclusions propres à chaque application.
Installer et configurer une base saine sous Apache et Nginx
Environnement de test : configurations préparées pour un lab isolé composé d'une machine virtuelle Debian 13 « Trixie » avec Apache 2.4 et les paquets libapache2-mod-security2 et modsecurity-crs, d'une seconde machine virtuelle avec Nginx, libModSecurity 3 et le connecteur ModSecurity-nginx, et d'une application PHP-FPM 8.4 de démonstration. Les versions disponibles dans votre distribution peuvent différer : vérifiez-les et prévoyez une période d'observation avant toute transposition en production.
Sous Debian ou Ubuntu, le module Apache et le CRS s'installent depuis les dépôts. Le fichier modsecurity.conf-recommended fourni par le projet sert de point de départ : il fixe le mode du moteur, les limites de corps, la journalisation et les répertoires de travail. La documentation de la configuration de base recommandée en commente chaque directive, pour la v2 comme pour la v3.
- Installer le module et le CRS, puis copier modsecurity.conf-recommended en modsecurity.conf.
- Laisser SecRuleEngine en DetectionOnly pendant la période d'observation.
- Vérifier SecRequestBodyAccess On, sans quoi les paramètres POST échappent à toute inspection.
- Déplacer SecTmpDir et SecDataDir de /tmp vers un répertoire privé, accessible au seul compte du serveur web.
- Choisir le niveau de paranoïa et les seuils d'anomalie dans crs-setup.conf.
- Tester la syntaxe avec apachectl configtest ou nginx -t avant chaque rechargement.
sudo apt install libapache2-mod-security2 modsecurity-crs
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
sudo apachectl configtest
sudo systemctl reload apache2Sous Nginx, libModSecurity est chargée par le connecteur ModSecurity-nginx sous forme de module dynamique. La configuration tient en deux directives, déclarées dans le bloc http, server ou location, et en un fichier principal qui inclut la configuration du moteur puis celle du CRS. La directive modsecurity_rules permet en outre d'ajuster un emplacement précis sans dupliquer toute la configuration.
load_module modules/ngx_http_modsecurity_module.so;
http {
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
}Le fichier main.conf se contente d'enchaîner, dans cet ordre, la configuration du moteur, celle du CRS et ses règles. L'ordre compte : le moteur doit être configuré avant le chargement du CRS, et crs-setup.conf lu avant les fichiers de règles qui en dépendent.
Include /etc/nginx/modsec/modsecurity.conf
Include /etc/nginx/modsec/crs/crs-setup.conf
Include /etc/nginx/modsec/crs/rules/*.confLe WAF n'inspecte que ce qu'il voit en clair : placé sur le serveur qui termine TLS, il analyse le trafic déchiffré, ce qui suppose une gestion rigoureuse des certificats de ces serveurs. Pour les infrastructures qui s'appuient sur une PKI Microsoft, voir notre méthode de génération d'un certificat TLS AD CS pour Apache et Nginx.
Déployer sans casser la production : DetectionOnly et réglage
Le déploiement classique de ModSecurity commence en DetectionOnly : les règles sont évaluées et journalisées, sans action bloquante. Dans ce mode, le rejet des corps de requête trop volumineux est automatiquement remplacé par un traitement partiel, pour éviter toute perturbation. Après une observation couvrant les usages réels, y compris les traitements mensuels, les exports et les interfaces d'administration, on passe le moteur en mode On.
La documentation du CRS décrit une variante efficace : activer le blocage dès le départ avec des seuils très élevés, par exemple 10 000, puis les abaisser par paliers à mesure que les faux positifs sont traités. Cette méthode, popularisée par Christian Folini, oblige à traiter les alertes au lieu de laisser un mode détection tourner indéfiniment sans que personne ne lise les journaux.
Conseil d'expert : fixez une date de sortie du mode détection dès le lancement du projet et suivez chaque semaine deux indicateurs simples : le nombre de requêtes légitimes qui auraient été bloquées et le nombre d'exclusions ajoutées. Un WAF laissé des mois en DetectionOnly produit des journaux, mais ne bloque rien ; c'est une fausse sécurité qu'un audit doit signaler.
Écrire des exclusions ciblées contre les faux positifs
Un faux positif du CRS se traite par une exclusion aussi étroite que possible : une règle, un paramètre, une URL. Désactiver une règle entière, voire le CRS sur tout un site, crée un angle mort durable. ModSecurity propose deux familles d'exclusions : celles appliquées à l'exécution par l'action ctl, placées avant le chargement du CRS, et celles appliquées à la configuration, comme SecRuleRemoveById ou SecRuleUpdateTargetById, placées après.
SecRule REQUEST_URI "@beginsWith /admin/editeur/" \
"id:10100,\
phase:1,\
pass,\
nolog,\
t:none,\
ctl:ruleRemoveTargetByTag=attack-xss;ARGS:contenu"
SecRuleUpdateTargetById 942100 "!ARGS:recherche_avancee"La première règle retire le seul paramètre « contenu » de l'inspection XSS sur l'éditeur d'administration ; la seconde exclut un paramètre de la règle 942100, qui s'appuie sur libinjection pour détecter les injections SQL. Documentez chaque exclusion avec l'identifiant de la règle, le motif métier et le ticket associé : c'est ce qui permettra de la réexaminer lors des revues suivantes.
Retour terrain : Cas typique rencontré en mission — la phase de réglage du CRS dure généralement quelques semaines au niveau de paranoïa initial, davantage dès qu'on le relève. Les faux positifs se concentrent presque toujours sur les mêmes familles : éditeurs riches qui envoient du HTML, API JSON transportant du code ou des requêtes, champs de recherche avancée et cookies volumineux d'outils marketing. Après revue, seule une poignée d'exclusions par application reste nécessaire ; les autres masquaient un défaut applicatif ou une règle mal comprise.
Erreur « ModSecurity: Output filter: Response body too large » : diagnostic et correction
Pourquoi le serveur renvoie une erreur 500
Ce message apparaît dans le journal d'erreurs Apache lorsque ModSecurity v2 met en mémoire tampon une réponse dont le corps dépasse SecResponseBodyLimit alors que SecResponseBodyLimitAction vaut Reject. Le visiteur reçoit une erreur 500. La ligne typique mentionne « over limit of 524288 » : 524 288 octets, soit 512 Ko, la valeur retenue dans le fichier de configuration recommandé.
La mention « total not specified » signifie que le moteur a cessé de lire la réponse et ignore donc sa taille réelle. Les cas classiques sont une page d'administration très chargée, un export XML ou texte généré dynamiquement, un webmail affichant une longue liste de messages ou une extension de débogage qui gonfle les pages lorsque l'administrateur est connecté.
Le libellé cité est celui du module Apache. Avec libModSecurity v3, les mêmes directives existent, mais le message journalisé peut être formulé autrement : recherchez toute mention de limite du corps de réponse dans les journaux du connecteur, en vous aidant de l'identifiant unique de la transaction.
Quatre corrections, de la plus ciblée à la plus large
- Restreindre SecResponseBodyMimeType aux types réellement inspectés : texte, HTML et XML, et JSON seulement si vous filtrez les réponses d'API.
- Passer SecResponseBodyLimitAction à ProcessPartial, comme le fichier recommandé : la partie excédentaire est servie sans être inspectée.
- Relever SecResponseBodyLimit avec mesure, par exemple à 2 Mo, en tenant compte de la mémoire consommée par chaque réponse simultanée.
- Désactiver l'inspection des réponses sur une URL précise, comme un export, plutôt que sur tout le site.
SecResponseBodyMimeType text/plain text/html text/xml
SecResponseBodyLimit 2097152
SecResponseBodyLimitAction ProcessPartial
SecRule REQUEST_URI "@beginsWith /export/" \
"id:10200,\
phase:1,\
pass,\
nolog,\
t:none,\
ctl:responseBodyAccess=Off"L'exemple ci-dessus utilise l'action ctl:responseBodyAccess de ModSecurity v2. Sous Nginx avec la v3, le plus simple est d'écrire SecResponseBodyAccess Off dans une directive modsecurity_rules propre au bloc location concerné. Dans les deux cas, l'exclusion doit viser une URL précise et documentée, jamais l'ensemble de l'application.
Sur un serveur géré par Plesk ou cPanel, ne modifiez pas les fichiers générés par le panneau : vos changements seraient écrasés à la prochaine mise à jour. Utilisez les zones de directives personnalisées prévues, par domaine ou globales, et vérifiez que le réglage s'applique bien aux hôtes virtuels HTTP et HTTPS, une erreur fréquente lorsque seule l'une des deux zones est renseignée.
Relever la limite à plusieurs centaines de mégaoctets, comme le suggèrent certains forums, revient à autoriser autant de mémoire tampon par réponse inspectée. Sur un serveur chargé, cela ouvre la voie à l'épuisement de la mémoire, et le plafond documenté de la v2 est de 1 Go. Les autres messages de limite suivent la même logique de diagnostic, résumée ci-dessous.
| Message journalisé | Directive en cause | Correction recommandée |
|---|---|---|
| Output filter: Response body too large | SecResponseBodyLimit et SecResponseBodyLimitAction | ProcessPartial, types MIME réduits, exclusion par URL |
| Request body no files data length is larger than the configured limit | SecRequestBodyNoFilesLimit | Relever avec mesure pour les formulaires ou API légitimes |
| Request body (Content-Length) is larger than the configured limit | SecRequestBodyLimit | Aligner sur la taille maximale de fichier acceptée |
| Failed to fully parse request body due to large argument count | SecArgumentsLimit et règle 200007 | Vérifier le formulaire, conserver la règle de blocage |
ModSecurity et php2shell : rappel des faits
Avertissement : cette section décrit des mesures de détection et de protection. Elle ne contient aucun détail d'exploitation. Tout test de vulnérabilité doit être mené sur des systèmes vous appartenant ou dans un cadre contractuel explicitement autorisé.
Le 21 octobre 2026, le projet PHP a publié les versions 8.5.12, 8.4.27, 8.3.36 et 8.2.35 pour corriger deux vulnérabilités surnommées php2shell. La première, CVE-2026-109618, provient d'une corruption de l'état interne lorsque PHP manque de mémoire en plein traitement d'une requête. La seconde, CVE-2026-109619, laisse un état global pointer vers une mémoire libérée, réutilisée par la requête suivante du même processus.
Le projet PHP considère toutes les installations servant des requêtes web comme exposées, et mod_php comme la plus à risque : une requête non authentifiée peut déclencher l'attaque avant toute exécution du code applicatif. PHP 8.1 et les versions antérieures ne reçoivent plus de correctif officiel : le projet a seulement publié des rétroportages minimaux du code source pour PHP 7.4, 8.0 et 8.1, en complément des correctifs de certains distributeurs.
9,2 sur 10 : c'est le score CVSS v4.0 attribué par le projet PHP à chacune des deux vulnérabilités php2shell, dans son annonce du 20 octobre 2026, avant la publication des correctifs le lendemain (source : archives des annonces PHP 2026).
Patch virtuel php2shell : ce que ModSecurity peut faire
Face aux vulnérabilités PHP surnommées php2shell, le bulletin d'alerte CERTFR-2026-ALE-014 du CERT-FR est sans ambiguïté : seule la mise à jour protège, et les équipements affectés doivent être isolés en attendant la migration vers une version corrigée. Mis à jour le 26 octobre 2026, il signale des tentatives d'exploitation visant des déploiements spécifiques. Un WAF n'est qu'un patch virtuel : il fait gagner du temps, sans jamais remplacer le correctif.
Le bulletin PHP recommande de limiter, au niveau du serveur web ou du proxy, la taille des requêtes décodées, le nombre de champs, de parties multipart et d'en-têtes, ainsi que la profondeur d'imbrication. ModSecurity applique une partie de ces limites : SecRequestBodyLimit et SecRequestBodyNoFilesLimit pour la taille, SecArgumentsLimit et la règle 200007 pour le nombre d'arguments, la validation stricte multipart et les variables tx.max_num_args ou tx.combined_file_sizes du CRS.
Une règle de détection peut aussi signaler le champ de formulaire utilisé par le suivi de progression des téléversements de session, nommé PHP_SESSION_UPLOAD_PROGRESS par défaut. Ciblez ARGS_NAMES plutôt que REQUEST_BODY : avec ModSecurity v2, cette dernière variable n'est alimentée, par défaut, que pour les corps URL-encodés, si bien qu'une règle qui la vise ne voit jamais les requêtes multipart.
SecRule ARGS_NAMES "@streq PHP_SESSION_UPLOAD_PROGRESS" \
"id:10300,\
phase:2,\
pass,\
log,\
t:none,\
msg:'Champ de suivi de televersement de session PHP detecte (php2shell)',\
tag:'php2shell',\
severity:'CRITICAL'"Commencez en pass et log pour mesurer le trafic légitime, car certaines applications affichent réellement une barre de progression, puis passez en deny si aucune fonction ne l'utilise. Si le champ a été renommé par session.upload_progress.name, adaptez la règle. La mesure côté PHP reste prioritaire : session.upload_progress.enabled=0 dans php.ini ou le pool FPM, suivi du redémarrage de tous les workers.
Des tests partagés par la communauté CRS au moment de la publication indiquaient que les tentatives alors connues déclenchaient plusieurs règles dès le niveau de paranoïa 1. C'est encourageant, mais une variante peut contourner des signatures génériques. Combinez donc le WAF, la configuration PHP, le confinement du processus par AppArmor ou SELinux et le filtrage des connexions sortantes du compte qui exécute PHP.
Les limites du patch virtuel
Un WAF ne voit que ce qui transite par lui. Une instance PHP exposée par un autre chemin, une appliance qui embarque PHP ou un service interne accessible depuis un poste compromis échappent à sa vigilance. Il ne corrige pas non plus le code vulnérable : il filtre des formes d'entrée connues. Le correctif de PHP et le redémarrage des workers restent la seule fin de traitement acceptable.
Retour terrain : Cas typique rencontré en mission — face à ces vulnérabilités, la mise à jour de PHP prend souvent plusieurs semaines sur les applications métier figées sur une ancienne branche ou embarquées dans une appliance. Dans l'intervalle, je fais déployer la règle sur le champ de suivi de téléversement, d'abord en journalisation puis en blocage, avec des limites multipart resserrées. Les faux positifs viennent surtout d'un formulaire de dépôt affichant une barre de progression et de gros formulaires légitimes : une exclusion par URL suffit, en attendant le correctif.
Journalisation, supervision et intégration SIEM
Le journal d'audit est la principale source d'information de ModSecurity. Avec SecAuditEngine RelevantOnly, il enregistre les transactions marquées par une règle et les réponses d'erreur 4xx et 5xx, hors 404. SecAuditLogParts choisit les sections conservées : en-têtes, corps de requête, en-têtes de réponse, règles déclenchées. Le format JSON, disponible si le moteur a été compilé avec YAJL, facilite l'ingestion par un SIEM.
Attention au contenu de ces journaux : les parties C et I contiennent les corps de requête, donc potentiellement des mots de passe, des numéros de carte ou des données personnelles. Limitez les parties journalisées, masquez les champs sensibles lorsque le moteur le permet, restreignez les droits d'accès et définissez une durée de conservation cohérente avec le RGPD.
En production chargée, préférez le mode concurrent, avec un fichier par transaction, ou l'envoi vers un collecteur : le mode série convient surtout à un usage ponctuel. Côté supervision, quelques indicateurs suffisent pour démarrer :
- le volume de requêtes bloquées par règle et par application ;
- la part des blocages sur les URL critiques, comme l'authentification ou le paiement ;
- le nombre d'adresses sources distinctes concernées ;
- les requêtes proches du seuil, qui orientent le réglage ;
- les erreurs internes du moteur, comme le dépassement des limites PCRE.
Le champ unique_id, présent dans le journal d'erreurs comme dans le journal d'audit, relie une plainte utilisateur à la transaction exacte. Pour une détection plus large, croisez ces données avec les journaux du serveur web et des processus PHP : un processus shell lancé par PHP-FPM est, par exemple, un signal bien plus fiable qu'une simple alerte WAF isolée.
Intégrer ModSecurity dans une chaîne DevSecOps
Les règles et les exclusions sont du code : elles doivent vivre dans un dépôt Git, passer par une revue et être testées avant déploiement. Une exclusion trop large peut ouvrir une brèche aussi sûrement qu'une vulnérabilité applicative, et une règle mal écrite peut bloquer une fonction métier un vendredi soir. Le pipeline CI/CD est le bon endroit pour attraper ces erreurs.
- Versionner modsecurity.conf, crs-setup.conf et les fichiers d'exclusion, avec un identifiant de ticket par modification.
- Valider la syntaxe dans la CI, avec apachectl -t ou nginx -t dans un conteneur éphémère.
- Rejouer des requêtes légitimes et malveillantes avec go-ftw, l'outil de test du projet CRS, pour vérifier qu'aucune exclusion n'ouvre de trou.
- Déployer d'abord en préproduction ou sur une fraction du trafic, en mode détection pour les nouvelles règles.
- Suivre le moteur et le CRS comme n'importe quelle dépendance, avec une alerte sur leurs avis de sécurité.
Les images de conteneur maintenues par le projet CRS, déclinées pour Apache et Nginx, facilitent ces tests : elles se paramètrent par variables d'environnement, comme le niveau de paranoïa, les seuils ou le mode du moteur, et permettent de reproduire la production dans un pipeline. Chaque faux positif corrigé devient alors un cas de test, qui empêche sa réapparition lors de la mise à jour suivante du CRS.
Limites de ModSecurity et place dans une défense en profondeur
ModSecurity détecte des formes d'attaque génériques, mais ne comprend pas la logique métier. Un contrôle d'accès défaillant, une IDOR (référence directe non sécurisée à un objet) ou une fraude au panier passent généralement sans alerte, car les requêtes restent syntaxiquement normales. Le WAF ne remplace donc ni le développement sécurisé, ni la revue de code, ni les tests d'intrusion.
Les attaques volumétriques posent un autre problème : un WAF hébergé sur le serveur consomme les mêmes ressources que l'application. Face à un déni de service distribué, une protection en amont reste nécessaire. Notre guide sur la sécurité réseau cloud, des VPC au WAF et à la protection DDoS détaille cette répartition, et notre présentation de la plateforme Cloudflare, du CDN au Zero Trust illustre l'approche managée.
Beaucoup de WAF cloud reprennent des règles inspirées du CRS, sans toujours exposer le niveau de paranoïa ni les seuils. La documentation du CRS rappelle qu'un seuil d'anomalie relevé par défaut chez un fournisseur réduit la protection. Le choix n'est pas binaire : un WAF managé en périphérie et ModSecurity au plus près de l'application se complètent, chacun couvrant les angles morts de l'autre.
Enfin, les API d'IA générative posent des problèmes que les signatures classiques couvrent mal : une injection de prompt est un texte en langage naturel, sans motif syntaxique stable. Le WAF reste utile pour limiter la taille des requêtes et le débit, mais la protection se joue surtout dans l'application, comme le détaille notre guide de remédiation du Top 10 OWASP pour les LLM.
À lire aussi : tester les règles WAF en non-régression.
Questions fréquentes
ModSecurity est-il toujours maintenu en 2026 ?
Oui. Après l'annonce du retrait de Trustwave, l'OWASP a repris la garde du projet en 2024 et l'a placé sous une gouvernance ouverte, avec des responsables communs au CRS. Les deux branches restent actives : la v2, module natif d'Apache, et la v3, ou libModSecurity, utilisée avec Nginx. Toutes deux ont reçu une nouvelle version le 29 septembre 2026, respectivement 2.9.15 et 3.0.17, avec plusieurs correctifs de sécurité. Ce qui a disparu, c'est l'offre commerciale de F5 pour NGINX Plus, en fin de vie depuis le 31 mars 2024. Si un article affirme qu'il faut abandonner ModSecurity, vérifiez sa date : la situation a nettement changé depuis 2022.
Quelle est la différence entre ModSecurity et l'OWASP CRS ?
ModSecurity est le moteur : il analyse le trafic HTTP, découpe chaque transaction en phases et exécute des règles écrites en SecLang. L'OWASP CRS est un jeu de règles génériques qui s'exécute sur ce moteur pour détecter les injections SQL, le XSS, l'inclusion de fichiers, l'exécution de commandes ou les violations de protocole. Sans règles, ModSecurity ne bloque rien ; sans moteur compatible, le CRS ne fait rien. Le CRS fonctionne aussi avec Coraza et avec certains WAF commerciaux ou cloud qui en reprennent tout ou partie. Les deux projets appartiennent désormais à l'OWASP, mais suivent chacun leur propre calendrier de versions, à surveiller séparément.
ModSecurity fonctionne-t-il avec Nginx ?
Oui, grâce à libModSecurity, la branche v3, et au connecteur ModSecurity-nginx, chargé comme module dynamique. La configuration repose sur les directives modsecurity on et modsecurity_rules_file, déclarées dans les blocs http, server ou location. La branche v2 ne contient plus l'ancien module Nginx depuis la version 2.9.13 : ignorez les tutoriels qui l'utilisent encore. Le module commercial proposé par F5 pour NGINX Plus a atteint sa fin de vie le 31 mars 2024. Avec la v3, vérifiez la prise en charge de chaque directive, car certaines directives de la v2 sont rejetées ou ignorées. Pour un nouveau projet cloud natif, Coraza constitue une alternative sérieuse à évaluer.
Comment corriger l'erreur « Response body too large » de ModSecurity ?
Le message « ModSecurity: Output filter: Response body too large » indique que la réponse dépasse SecResponseBodyLimit alors que SecResponseBodyLimitAction vaut Reject : le visiteur reçoit une erreur 500. Commencez par limiter SecResponseBodyMimeType aux types que vous inspectez réellement. Passez ensuite SecResponseBodyLimitAction à ProcessPartial, comme dans le fichier de configuration recommandé : la partie excédentaire est servie sans être inspectée. Si nécessaire, relevez la limite avec mesure, car chaque réponse inspectée est mise en mémoire tampon. Pour un export volumineux, désactivez l'inspection des réponses sur cette seule URL. Sur Plesk ou cPanel, passez par les zones de directives personnalisées pour que le réglage survive aux mises à jour.
ModSecurity protège-t-il contre php2shell ?
Partiellement et temporairement. Le projet PHP et le CERT-FR sont clairs : seule la mise à jour vers PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, suivie du redémarrage des workers, corrige CVE-2026-109618 et CVE-2026-109619. ModSecurity peut réduire l'exposition en limitant la taille et la complexité des requêtes multipart et en signalant le champ PHP_SESSION_UPLOAD_PROGRESS dans ARGS_NAMES. Des tests communautaires indiquaient que les tentatives connues le jour de la publication déclenchaient des règles du CRS dès le niveau de paranoïa 1, sans garantie face à une variante. Combinez ces règles avec session.upload_progress.enabled=0, un confinement AppArmor ou SELinux et une surveillance des processus lancés par PHP.
Conclusion
ModSecurity n'a rien d'une technologie du passé. Sous la garde de l'OWASP, le moteur reçoit des correctifs réguliers et reste, associé au CRS, la référence des WAF open source. Sa valeur dépend pourtant entièrement de son exploitation : une version à jour, un niveau de paranoïa adapté aux données protégées, des exclusions étroites et documentées, des journaux réellement lus et exploités.
L'actualité de 2026 l'a illustré : des limites mal comprises produisent des erreurs 500 inutiles, alors qu'un CRS correctement déployé a pu offrir un délai précieux face à php2shell. Traitez vos règles comme du code, testez-les dans la CI et articulez ce filtre local avec une protection en périphérie, comme le décrit notre article pilier sur la configuration des règles du WAF Cloudflare.
Auditer et régler votre WAF ModSecurity
Ayi NEDJIMI accompagne les équipes dans l'audit de configuration de ModSecurity et du CRS, le réglage des faux positifs, l'intégration des règles dans la chaîne CI/CD et la réponse aux vulnérabilités critiques comme php2shell.
Demander un audit de votre WAFÀ propos de l'auteur
Ayi NEDJIMI
Auditeur Senior Cybersécurité & Consultant IA
Expert Judiciaire — Cour d'Appel de Paris
Habilitation Confidentiel Défense
ayi@ayinedjimi-consultants.fr
Ayi NEDJIMI est un vétéran de la cybersécurité avec plus de 25 ans d'expérience sur des missions critiques. Ancien développeur Microsoft à Redmond sur le module GINA (Windows NT4) et co-auteur de la version française du guide de sécurité Windows NT4 pour la NSA.
À la tête d'Ayi NEDJIMI Consultants, il réalise des audits Lead Auditor ISO 42001 et ISO 27001, des pentests d'infrastructures critiques, du forensics et des missions de conformité NIS2 / AI Act.
Conférencier international (Europe & US), il a formé plus de 10 000 professionnels.
Domaines d'expertise
Ressources & Outils de l'auteur
Testez vos connaissances
Mini-quiz de certification lié à cet article — propulsé par CertifExpress
Articles connexes
Test de non-régression : stratégie, outils et CI/CD en 2026
Comment concevoir et automatiser un test de non-régression fiable : définition, stratégie par le risque, outils, pipeline CI/CD, sécurité et exigences du CRA.
SBOM SCA CI/CD sécurité 2026 : intégration complète
SBOM et SCA intégrés dans vos pipelines CI/CD en 2026 : inventoriez, analysez et sécurisez vos dépendances open source contre les attaques supply chain.
API Security 2026 : Sécuriser GraphQL, REST et Serverless
Les APIs GraphQL, REST et Serverless concentrent en 2026 les principales brèches de sécurité applicative. Découvrez comment les sécuriser efficacement.
Un projet cybersécurité ? Parlons-en.
Pentest, conformité NIS 2, ISO 27001, audit IA, RSSI externalisé… nos experts répondent sous 24h pour évaluer votre besoin et vous proposer un accompagnement sur mesure.
Commentaires
Aucun commentaire pour le moment. Soyez le premier à commenter !
Laisser un commentaire