Теория
Что делает WAF
WAF (Web Application Firewall) инспектирует HTTP-запросы/ответы и применяет policy. Действия: allow, block, managed_challenge/js_challenge, log/skip. Enforcement между edge и origin.
Архитектура WAF (pipeline)
Request Parser
↓
Normalization
↓
Rule Engine
↓
Scoring
↓
Action
Где чаще всего ломаются системы:
- плохой parser (неполный разбор payload/encodings);
- неполная normalization (обходы через encoding tricks);
- слишком дорогие правила (regex CPU spike);
- агрессивные блоки без safe rollout (FP).
Normalization (обязательна)
До правил запрос приводится к каноническому виду. ModSecurity transformations (t:*):
t:urlDecode,t:urlDecodeUni— URL decoding;t:htmlEntityDecode— HTML entities;t:lowercase— case normalization;t:normalizePathWin/t:normalizePath— canonicalization;t:removeWhitespace,t:replaceComments.
Без нормализации тривиальный bypass через double encoding (%2527 → %27 → ') или mixed case.
Rule Engine модели
Signature-based: regex/паттерны. Эталон — OWASP CRS (Coraza, ModSecurity).Anomaly scoring: CRS использует threshold (tx.anomaly_score, defaultparanoia level 1, threshold 5 для inbound).Behavioral: отклонение от baseline (Cloud Armor Adaptive Protection).ML-based: classifier поверх сигнатур.
OWASP CRS покрывает A03:2021 Injection (SQLi, RCE, LFI, XSS), part of A05 (через protocol-level rules).
Trade-offs
FP(false positives): блокируем легитимных пользователей.FN(false negatives): пропускаем атаку.- regex и deep inspection увеличивают CPU cost.
- каждый дополнительный шаг может увеличивать latency.
Архитектурный принцип:
WAF не должен быть bottleneck.
Это означает: контролируемая сложность правил, staged rollout (log/count -> challenge -> block) и постоянные замеры latency/CPU.
Что нужно уметь объяснить
Почему normalization критична?
Потому что правило сравнивает «форму» запроса. Если злоумышленник меняет форму через кодирование, но смысл остаётся атакующим, без нормализации правило не сработает.
Почему просто «добавить больше regex» опасно?
Потому что сложные выражения и их количество линейно/нелинейно увеличивают стоимость обработки каждого запроса и могут сами создать деградацию.
Почему нужен scoring, а не только binary block?
Scoring снижает FP: слабые сигналы накапливаются и блокируются только при достижении порога риска.
Практика
1. Включите режим наблюдения
Стартуйте с count/log (или аналогичного режима), а не с instant block.
2. Добавьте normalization-тесты
Проверьте кейсы:
- одинарное и двойное URL-encoding;
- смешанный регистр;
- HTML entities;
- path traversal после canonicalization.
3. Замерьте latency cost правил
Сравните p95/p99 до и после подключения rule set.
4. Введите safe rollout
- этап 1:
log/count - этап 2:
challenge - этап 3:
blockдля подтверждённых сигнатур