WAF et protection contre les injections
1) Pourquoi WAF à l'ère de l'API
Même avec une validation et un paramétrage rigoureux, les injections sont dues à :- les « longues queues » des intégrations (code héréditaire, webhooks partenaires),
- écarts de parsing (proxy ↔ cadre),
- nouvelles techniques de contournement protocole/obfuscation.
- WAF donne la frontière de l'échec précoce (early deny) et du « patching virtuel » avant la sortie du code, mais ne remplace pas le développement sécurisé.
2) Modèle de menace : types d'injections pour API
SQLi/ORMi: classic/boolean/time-based/stacked; blind à travers les retards.
NoSQLi (Mongo/Elastic) : opérateurs '$ ne/$ gt', JSON injection, regex-DoS.
Command Injection/RCE : shell-metasimboles, échange d'arguments, unsafe deserialization → code exec.
XXE : entités externes/DTD en XML.
SSRF : accès à la '169. 254. 169. 254 '/services internes ; DNS-rebinding.
Template Injection: Jinja/Thymeleaf/Handlebars; `{{77}}`.
LDAP/EL Injection, XPath, Header injection (CRLF), Path traversal.
GraphQL est spécifique : '__ schema' introduction, profondeur/complexité des requêtes.
JSON/JS est spécifique : Prototype Pollution ('__ proto __', 'constructor').
gRPC/Protobuf : messages oversized, champ smuggling via la non-correspondance des schémas.
3) Architectures WAF
Périmètre CDN-WAF : filtration rapide geo/ASN, contrôle de base de bot, cache/anti-padding.
Périmètre L7 (NGINX/Envoy/APISIX/Kong) : parsing précis, règles profondes, intégration avec PDP/limites.
Sidkar/mash (Envoy WASM/Filter) : service de per, près des données, moins faux positif pour les API internes.
Recommandation : modèle à deux couches (CDN-WAF + L7 WAF).
4) Parsing, normalisation et anti-contournement
WAF doit voir la même représentation canonique que l'application :- La normalisation des voies ('/a / du % 2e%2e/b ' → le refus), ' UTF-8 '/Unicode confusables, NUL-octets.
- Décodage unique : URL-/HTML-/Unicode-/Base64-couches, interdiction du décodage double.
- Restrictions : 'max _ headers', 'max _ header _ size', 'max _ body _ size', 'max _ args', profondeur JSON, limite multipart, interdiction de 2x gzip/zip bombes.
- Stratégies Content-Type : 'application/json' uniquement sur les endpoints JSON ; rejeter « polyglot ».
5) Modèles de règles
Négatif (signatures) : OWASP CRS (SQLi/XSS/SSRF/Java/Node RCE, etc.). Un démarrage rapide.
Positif (allow-list) : schémas rigoureux (JSON Schema/Protobuf), types et gammes ; le long des itinéraires.
Anomalie/notation : la somme des signes « suspects » → le seuil de verrouillage.
Contextuel : différents profils pour 'POST/payments' et 'GET/status' ; moins de FP.
6) Blocs de protection (dans le ligament)
1. Schémas et types : JSON Schema/Protobuf validation à la logique d'entreprise.
2. Paramétrage : expressions préparées, bindings ORM, interdiction de concaténation.
3. Output-escaping : HTML/JS/SQL contextuellement.
4. Politiques du corps : Content-Type, taille, restrictions multipart, interdiction des binaires sur les stylos JSON.
5. Règles WAF : CRS + custom négatif/positif.
6. Taux/Quota/Concurrence : Suppression de la brute/tortue DDoS, captches/challenges de protection pour les formes publiques.
7. Isolation des réseaux : stratégies egress pour SSRF (deny RFC1918/metadata/Unix sockets).
8. Headers-hygiène : 'X-Content-Type-Options : nosniff', 'Content-Security-Policy' pour le front, 'Referer-Policy'.
9. GraphiqueQL guard : limites de profondeur/complexité, interdiction d'introduction dans la vente (ou rôle-gate).
7) Exemples de configurations
7. 1 NGINX + ModSecurity (OWASP CRS)
nginx load_module modules/ngx_http_modsecurity_module.so;
modsecurity on;
modsecurity_rules_file /etc/modsecurity/modsecurity.conf;
modsecurity_rules '
SecRuleEngine On
Подключаем CRS
Include /etc/modsecurity/crs/crs-setup.conf
Include /etc/modsecurity/crs/rules/.conf
Позитивные правила: только JSON и ограничение размера
SecRule REQUEST_HEADERS:Content-Type "!@rx ^application/json($;)" "id:10001,phase:1,deny,status:415,msg:'Only JSON allowed'"
SecRequestBodyLimit 1048576
SecRequestBodyNoFilesLimit 1048576
Блок локальных адресов (SSRF)
SecRule REQUEST_HEADERS:Host "@ipmatch 127.0.0.0/8 10.0.0.0/8 169.254.0.0/16 192.168.0.0/16" \
"id:10002,phase:1,deny,status:403,msg:'Blocked private range'"
';
server {
listen 443 ssl http2;
server_name api.example.com;
client_max_body_size 1m;
proxy_request_buffering on; # защита от slow-POST proxy_read_timeout 300ms;
proxy_connect_timeout 100ms;
location /v1/ {
proxy_pass http://app_backends;
}
}
7. 2 Envoy HTTP WAF (WASM + JSON Schema + SSRF egress-deny)
yaml http_filters:
- name: envoy.filters.http.wasm typed_config:
config:
vm_config: { vm_id: waf, code: { local: { filename: /plugins/waf.wasm } } }
configuration:
"@type": type.googleapis.com/google.protobuf.Struct value:
crs_profile: "strict"
deny_patterns: ["(?i)union.select", "(?i)(sleep benchmark)\\s\\("]
json_schema:
"/v1/payments:create": "/schemas/payments_create.json"
- name: envoy.filters.http.router
Egress SSRF guard (L4): deny private ranges from gateway filter_chains:
- filters:
- name: envoy.filters.network.tcp_proxy typed_config:
stat_prefix: egress cluster: internet access_log: [...]
tunneling_config:
hostname: "%REQ(:authority)%"
transport_socket:
name: envoy.transport_sockets.tls
7. 3 APISIX : limitation des types et anti-obstruction
yaml routes:
- uri: /v1/
plugins:
cors: { allow_origins: "https://app.example.com" }
request-validation:
body_schema:
{"type":"object","properties":{"amount":{"type":"number","minimum":1}},"required":["amount"]}
uri-blocker:
block_rules: ["..","%2e%2e","%2f..","\\x00"] # traversal/NULL proxy-rewrite:
headers:
set:
X-Content-Type-Options: "nosniff"
8) Tuning et réduction des faux positifs (FP)
Profils per-route : règles strictes uniquement lorsqu'elles sont appropriées (par exemple, '/search 'autorise '/' %').
Shadow/Report-Only : Logons les déclenchements avant l'unité ; A/B comparaison des métriques.
Listes d'allow personnalisées pour les paramètres légitimes « bruyants ».
Scoring : ne bloquer que lorsque la somme des indicateurs> seuil.
Expérimentation : faible pourcentage de trafic sur les nouvelles règles → auto-rollback.
9) Observabilité et forensisme
Метрики: `waf_block_total{rule}`, `waf_anomaly_score`, `request_body_rejected_total`, `schema_violation_total`, `ssrf_block_total`.
Logs (samplés) : règle, partie de la requête (éditée), 'trace _ id', 'tenant', 'route', cause. Masquer les PII/secrets.
Dashboards : top règles/chemins, cluster FP, dynamique après sortie.
Incidents : sauvegarde des artefacts (payload, pcap si nécessaire), des produits RCA et des « patchs virtuels ».
10) Tests et scénarios de chaos
Boîtiers WAF (SQLi/XSS/SSRF), codages double/triple, Unicode mixte.
Différences de parsing : Envoyez un payload où le proxy et le cadre peuvent diverger (prises de paramètres, tableaux, ';' vs' & ').
Slow-POST/oversize, bombes zip, formes multipartites, boundary erroné.
GraphQL : générateur de profondeur/complexité, vérification des limites et des délais.
11) Anti-modèles
« Allumez les CRS et oubliez » : pas de circuits, pas de tuning le long des itinéraires.
Logs avec corps brut de requête et PII.
Pas de normalisation/limites de taille → de contournement, DoS sur parsing.
Ignorer les contrôles « Content-Type »/charset → une attaque polyglotte.
Aucun filtre egress → SSRF à la métadonnée du nuage.
Un profil commun pour les API externes et internes.
Les exceptions incontrôlables « pour le partenaire » → les trous dans le périmètre.
12) Spécificité de l'iGaming/Finance
Profils renforcés sur les stylos de paiement/sortie : petites limites body, schémas stricts, listes deny pour les champs compte/IBAN/PAN (masquage, contrôles formatés).
Webhooks par PSP/KYC : Signature HMAC/mutuelle TLS, profils WAF séparés, anti-replay.
Filtres géo/ASN et limites comportementales pour empêcher les inscriptions de bot et les abysses bonus.
Les registres d'incidents sont immuables (vérification), stockés par pays.
13) Chèque-liste prod-prêt
- WAF à deux couches (CDN + L7), normalisation unique et limites dimensionnelles.
- OWASP CRS inclus, règles de personnalisation par route ; JSON Schema/Protobuf sur les stylos write.
- Politiques de Content-Type/charset ; interdiction du double décodage/NULL/traversal.
- Bloc SSRF-egress sur bandes privées/metadata ; Protection DNS-rebinding.
- Taux/Quota/Concurrence et anti-bot (challenges) sur les formes publiques.
- Shadow/Report-Only → canary → enforce; auto-rollback par SLO et FP.
- Métriques/logs/tracés masqués ; dashboards des « top regles »/FP.
- Pleybooks de patch virtuel et RCA ; tests réguliers de contournement.
- Profils distincts pour les webhooks PSP/KYC, stylos de paiement et API internes.
14) TL; DR
Construisez la protection par couches : normalisation et limites → schémas/types → paramétrage → WAF (CRS + caste) → rate/bot filtres → egress bloc SSRF. Tapez par route, lancez de nouvelles règles dans shadow → canary, suivez les métriques/FP et faites des « patchs virtuels » jusqu'à ce que le code soit fictif. Pour les chemins de paiement/webhook - des profils distincts rigoureux, HMAC/mTLS et des fenêtres de confiance minimales.