Sécurité
Blog
Sécurité12 min

ModSecurity WAF : Protéger vos applications web contre les attaques courantes

Mattia Eleuteri29 avril 2022

ModSecurity WAF : Protéger vos applications web contre les attaques courantes

Les attaques web n'ont jamais été aussi sophistiquées. SQL injection, XSS (Cross-Site Scripting), command injection, DDoS... Ces vulnérabilités figurent toujours dans l'OWASP Top 10 après deux décennies. Pourquoi ? Parce qu'elles fonctionnent.

La bonne nouvelle : vous n'avez pas besoin d'attendre que votre équipe développement débogue chaque ligne de code. ModSecurity, un Web Application Firewall (WAF) open-source, peut détecter et bloquer ces attaques avant qu'elles n'atteignent votre application.

Cet article couvre :

  1. Ce que ModSecurity fait réellement (et ce qu'il ne fait pas)
  2. Comment l'implémenter sur Kubernetes avec Ingress NGINX
  3. La configuration pratique du Core Rule Set (CRS)
  4. Les bonnes pratiques de déploiement

Qu'est-ce que ModSecurity ?

ModSecurity est un WAF open-source conçu à l'origine pour Nginx et Apache. Il fonctionne comme un filtre applicatif qui :

  • Inspecte chaque requête HTTP entrante
  • Applique des règles de sécurité (Core Rule Set - CRS)
  • Bloque ou log les requêtes suspectes
  • Enregistre les événements de sécurité pour audit

Contrairement à un firewall réseau (Layer 3/4), ModSecurity comprend le HTTP/HTTPS et l'application elle-même.

Ce que ModSecurity protège

ModSecurity protège contre la majorité des attaques OWASP Top 10 :

Attaque Détection
XSS (Cross-Site Scripting) Détecte les scripts inject, <script>, event handlers
SQL Injection Reconnaît les patterns SQL suspects (' OR '1'='1', UNION SELECT)
Command Injection Bloque les tentatives d'exécution de commandes shell (; rm -rf /)
Path Traversal Empêche l'accès aux répertoires parent (../../../etc/passwd)
Clickjacking Validation des headers de réponse (X-Frame-Options)
Buffer Overflow Limite la taille des uploads et des en-têtes
DDoS de couche applicative Rate limiting et détection d'anomalies

Ce que ModSecurity ne peut pas faire

Soyez réalistes :

  • Ne remplace pas la validation entrante : votre code doit toujours valider les inputs
  • Ne résout pas les vulnérabilités métier : si votre logique est défectueuse, ModSecurity ne peut pas la corriger
  • N'arrête pas les authentifications faibles : ModSecurity ne valide pas les mots de passe
  • N'est pas un DDoS complet : protège contre les attaques applicatives, pas les floods réseau bruts

ModSecurity est une couche de défense, pas une solution complète.

ModSecurity sur Kubernetes : Ingress NGINX + ModSecurity

Avec Kubernetes, vous déployez probablement vos applications derrière un Ingress Controller. Ingress NGINX (le controller Nginx le plus populaire) a un support natif pour ModSecurity.

Architecture type sur Hikube

Internet
    |
    v
Ingress NGINX (avec ModSecurity WAF)
    |
    +-- Service API (port 8080)
    +-- Service Web (port 3000)
    +-- Service Admin (port 8888)

Chaque requête passe par Ingress NGINX. ModSecurity les inspecte avant qu'elles ne touchent votre application.

Déploiement sur Hikube

Si vous utilisez Hikube (plateforme Kubernetes managée Hidora), vous pouvez activer ModSecurity directement. Voici comment :

1. Installer Ingress NGINX avec ModSecurity

Si votre cluster n'a pas Ingress NGINX avec ModSecurity, installez-le via Helm :

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.image.image=ingress-nginx/controller \
  --set controller.metrics.enabled=true

ModSecurity est souvent pré-installé. Vérifiez :

kubectl exec -it -n ingress-nginx \
  pod/ingress-nginx-controller-xxx -- \
  /usr/local/modsecurity/bin/modsec-rules-check || \
  echo "ModSecurity not installed"

2. Configuration ModSecurity dans l'Ingress

Une fois Ingress NGINX déployé, activez ModSecurity via annotations :

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    # Activer ModSecurity
    nginx.ingress.kubernetes.io/enable-modsecurity: "true"
    
    # Utiliser le Core Rule Set (OWASP)
    nginx.ingress.kubernetes.io/enable-owasp-core-rules: "true"
    
    # Mode : "Off" (désactif) | "DetectionOnly" (log seulement) | "On" (bloque)
    nginx.ingress.kubernetes.io/modsecurity-mode: "DetectionOnly"
    
    # Indiquer le fichier de config
    nginx.ingress.kubernetes.io/modsecurity-conf: |
      SecRuleEngine On
      SecAuditLogRelevantStatus "^(?:5|4(?!04))"
      SecAuditLogParts ABCIJDEFHZ
      SecAuditLogFormat JSON
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-api
            port:
              number: 8080

3. Configurer les règles ModSecurity (Core Rule Set)

ModSecurity utilise des règles. La meilleure approche est d'utiliser le Core Rule Set (CRS) officiel de l'OWASP.

Créez un ConfigMap avec les règles :

apiVersion: v1
kind: ConfigMap
metadata:
  name: modsecurity-rules
  namespace: ingress-nginx
data:
  modsecurity.conf: |
    # Règles de base
    SecRuleEngine On
    SecRequestBodyAccess On
    SecRequestBodyLimit 10485760
    SecRequestBodyNoFiles Off
    SecRequestBodyLimitAction ProcessPartial
    SecResponseBodyAccess Off
    SecResponseBodyMimeType text/plain text/html text/xml
    SecResponseBodyMimeTypesClear
    SecPcreMatchLimit 1000
    SecPcreMatchLimitRecursion 1000
    
    # Audit logging
    SecAuditEngine RelevantOnly
    SecAuditLogRelevantStatus "^(?:5|4(?!04))"
    SecAuditLogParts ABCIJDEFHZ
    SecAuditLogFormat JSON
    SecAuditLogType Serial
    SecAuditLog /var/log/modsecurity/audit.log
    
    # OWASP Core Rule Set
    IncludeOptional /etc/modsecurity/crs/crs-setup.conf
    IncludeOptional /etc/modsecurity/crs/rules/*.conf
  
  # Règles personnalisées
  custom-rules.conf: |
    # Bloquer les scans de vulnérabilité (sqlmap, nikto, etc.)
    SecRule REQUEST_HEADERS:User-Agent "@contains sqlmap" "id:1001,phase:1,log,block,msg:'SQLMap scan attempt'"
    SecRule REQUEST_HEADERS:User-Agent "@contains nikto" "id:1002,phase:1,log,block,msg:'Nikto scanner'"
    
    # Limiter les uploads de fichiers
    SecRule FILES_TMPNAMES "!@inspectFile /path/to/whitelist.txt" \
      "id:1003,phase:2,deny,status:403,msg:'File upload blocked'"
    
    # Rate limiting simple (10 requêtes/sec par IP)
    SecRule IP:excessive_requests "@gt 10" \
      "id:1004,phase:1,deny,status:429,msg:'Too many requests'"

4. Tester avec DetectionOnly d'abord

Ne mettez jamais ModSecurity directement en mode "On" (bloquant) en production.

Commencez avec DetectionOnly pour observer les faux positifs :

# Voir les requêtes bloquées
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -f | grep modsecurity

Après 1-2 semaines d'observation, passez en mode On.

5. Exclure les faux positifs

Inévitablement, certaines requêtes légales seront flaggées. Créez des exclusions :

# Exclure des chemins de ModSecurity
apiVersion: v1
kind: ConfigMap
metadata:
  name: modsecurity-exclusions
  namespace: ingress-nginx
data:
  exclusions.conf: |
    # Exclure healthchecks
    SecRule REQUEST_URI "@startsWith /health" "id:2001,phase:1,nolog,pass"
    
    # Exclure uploads légitimes (par exemple fichiers CSV)
    SecRule REQUEST_URI "@startsWith /api/import" \
      "id:2002,phase:2,nolog,pass,msg:'Allow CSV import'"
    
    # Exclure POST avec du JSON valide vers l'API
    SecRule REQUEST_METHOD "POST" \
      "id:2003,phase:1,nolog,pass,msg:'Allow POST to API'"

Implémentation pratique : Exemple complet

Voici un exemple complet pour une application web sur Hikube :

---
# 1. ConfigMap des règles ModSecurity
apiVersion: v1
kind: ConfigMap
metadata:
  name: modsecurity-rules
  namespace: default
data:
  modsecurity.conf: |
    SecRuleEngine On
    SecRequestBodyAccess On
    SecAuditEngine RelevantOnly
    SecAuditLogRelevantStatus "^(?:5|4(?!04))"
    IncludeOptional /etc/modsecurity/crs/crs-setup.conf
    IncludeOptional /etc/modsecurity/crs/rules/*.conf

---
# 2. Ingress avec ModSecurity activé
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ecommerce-ingress
  annotations:
    nginx.ingress.kubernetes.io/enable-modsecurity: "true"
    nginx.ingress.kubernetes.io/enable-owasp-core-rules: "true"
    nginx.ingress.kubernetes.io/modsecurity-mode: "DetectionOnly"  # Changer à "On" après test
spec:
  ingressClassName: nginx
  rules:
  - host: shop.example.ch
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: ecommerce-app
            port:
              number: 3000
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: ecommerce-api
            port:
              number: 8080
  tls:
  - hosts:
    - shop.example.ch
    secretName: tls-cert

---
# 3. Service
apiVersion: v1
kind: Service
metadata:
  name: ecommerce-app
spec:
  selector:
    app: ecommerce
  ports:
  - port: 3000
    targetPort: 3000

---
# 4. Pod exemple
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ecommerce
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ecommerce
  template:
    metadata:
      labels:
        app: ecommerce
    spec:
      containers:
      - name: app
        image: myregistry.azurecr.io/ecommerce:v1.0
        ports:
        - containerPort: 3000
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
        securityContext:
          runAsNonRoot: true
          readOnlyRootFilesystem: true

Monitoring et alertes

ModSecurity génère des logs. Vous devez les surveiller :

1. Logs locaux dans le controller Nginx

# Accédez au pod Ingress NGINX
kubectl exec -it -n ingress-nginx \
  pod/ingress-nginx-controller-xxx -- bash

# Consultez les logs
tail -f /var/log/modsecurity/audit.log | jq .

2. Centralisez les logs (ELK, Splunk, Datadog)

Configurez Ingress NGINX pour envoyer les logs ModSecurity à votre système centralisé :

apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-config
  namespace: ingress-nginx
data:
  modsecurity-log-format: |
    {"timestamp": "$time_iso8601", "client": "$remote_addr", "request": "$request", 
     "status": "$status", "modsecurity_action": "$modsecurity_action"}

3. Alertes sur attaques

Configurez des alertes Prometheus/Alertmanager :

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: modsecurity-alerts
spec:
  groups:
  - name: modsecurity
    rules:
    - alert: HighModSecurityBlockRate
      expr: rate(nginx_modsecurity_blocked_total[5m]) > 10
      for: 5m
      annotations:
        summary: "Taux élevé de requêtes bloquées par ModSecurity"

Bonnes pratiques de déploiement

1. Commencer en DetectionOnly

Ne bloquez jamais sans observer d'abord. Les faux positifs sont inévitables.

nginx.ingress.kubernetes.io/modsecurity-mode: "DetectionOnly"

Observez pendant 1-2 semaines, puis passez à On.

2. Mettre en place une whitelist d'exclusions

Certains chemins ne doivent pas être filtrés (healthchecks, webhooks, etc.) :

SecRule REQUEST_URI "@startsWith /health" "id:100,phase:1,pass,nolog"
SecRule REQUEST_URI "@eq /webhook/payment" "id:101,phase:1,pass,nolog"

3. Logs structurés JSON

Utilisez le format JSON pour faciliter l'analyse :

SecAuditLogFormat JSON

4. Rotation des logs

Les logs ModSecurity peuvent devenir volumineux. Configurez la rotation :

SecAuditLogStorageDir /var/log/modsecurity
SecAuditEngine RelevantOnly  # Log seulement les attaques, pas tout

5. Tester les règles régulièrement

Vérifiez que vos règles fonctionnent encore :

# Test avec XSS
curl "https://api.example.ch/search?q=<script>alert(1)</script>"
# Doit être bloqué ou logué

# Test avec SQL injection
curl "https://api.example.ch/users?id=1' OR '1'='1"
# Doit être bloqué ou logué

Intégration avec vos services managés Hidora

Chez Hidora, nous offrons deux niveaux de sécurité WAF :

1. WAF standard (inclus dans Hikube)

  • ModSecurity avec Core Rule Set
  • HTTPS/TLS automatique
  • DDoS basique (Layer 4)
  • Logs centralisés

2. WAF advanced (via Managed Services)

  • Machine learning pour anomalies
  • Règles personnalisées par application
  • 24/7 monitoring et réponse aux incidents
  • Conformité suisse (LPD) et ISO 27001

Consultez notre page Managed Services pour plus d'informations.

Conclusion

ModSecurity n'est pas une balle d'argent, mais c'est un outil extrêmement efficace pour arrêter les attaques courantes. Couplé à Kubernetes et Ingress NGINX, il offre une couche de sécurité applicative sans modification de code.

Résumé d'implémentation :

  1. Déployez Ingress NGINX avec ModSecurity sur Hikube
  2. Activez les règles OWASP Core Rule Set
  3. Commencez en mode DetectionOnly
  4. Observez et excluez les faux positifs
  5. Basculez en mode On après validation
  6. Centralisez les logs et configurez les alertes

C'est un investissement minimal pour une protection massive contre les attaques web.


À lire aussi :


Cet article vous a été utile ? Découvrez comment Hidora peut sécuriser vos applications web : Hikube Platform · Managed Services · Professional Services

Cet article vous parle ?

Hidora peut vous accompagner sur ce sujet.

Besoin d'un accompagnement ?

Parlons de votre projet. 30 minutes, sans engagement.