WAF: защита веб-приложений на периметре
Урок объясняет, как Web Application Firewall разбирает HTTP-запросы, чем помогает набор правил OWASP CRS, и как вводить WAF в работу, не ломая легитимных пользователей.
WAF (Web Application Firewall) — фильтр, который анализирует HTTP/HTTPS-запросы к веб-приложению на уровне приложения (L7) и блокирует те, что похожи на атаку: SQL-инъекции, XSS, обход путей и другие из списка OWASP.
Обычный файрвол видит «соединение на порт 443» и пропускает его целиком. Но вредоносность веб-атаки спрятана внутри HTTP-запроса — в параметре формы, заголовке, теле. WAF — специализированный инструмент, который понимает HTTP и смотрит именно туда. Для защитника это слой, выигрывающий время, пока разработчики чинят саму уязвимость в коде.
Зачем это знать защитнику
Веб-приложения — самая атакуемая поверхность современной инфраструктуры. WAF не заменяет безопасную разработку, но даёт defense in depth: ловит массовое автоматизированное сканирование, прикрывает свежую уязвимость до выхода патча (virtual patching) и даёт видимость атак на прикладной слой. Понимая, как WAF принимает решения, вы избегаете двух крайностей — «всё блокирует и ломает сайт» и «пропускает реальные атаки».
Как WAF фильтрует HTTP
WAF разбирает запрос на части: метод, URL и query-строку, заголовки, cookies, тело (form-data, JSON, XML). Каждую часть он нормализует (декодирует URL-encoding, приводит регистр, раскрывает escape-последовательности — чтобы атакующий не спрятался за кодировками) и прогоняет через правила. Правило ищет признаки атаки: например, в значении параметра встречается фрагмент, типичный для SQL-инъекции (' OR '1'='1) или для XSS (HTML-теги в пользовательском вводе).
WAF бывает разных форм-факторов: обратный прокси перед приложением (самый частый), модуль веб-сервера (ModSecurity для nginx/Apache), облачный сервис на CDN, либо встроенный в NGFW. Логика всюду похожа.
OWASP Core Rule Set (CRS)
OWASP CRS — открытый, отраслевой набор правил для WAF (исторически для ModSecurity, теперь и для других движков). Это набор универсальных сигнатур, прикрывающих типовые классы атак из OWASP Top 10: инъекции, XSS, обход путей (path traversal), включение файлов, атаки на сессии. CRS не знает специфики вашего приложения — это «обороноспособность из коробки», которую затем тюнингуют.
Anomaly scoring — как CRS принимает решение
Современный CRS работает не по принципу «одно правило сработало — блок», а через накопление баллов аномальности (anomaly scoring). Каждое сработавшее правило добавляет вес; запрос блокируется, только когда суммарный балл превышает порог. Это снижает ложные срабатывания: одиночный безобидный признак не валит запрос, а вот комбинация подозрительных признаков — да. Порог регулируется уровнем паранойи (Paranoia Level): выше уровень — больше правил активно, выше чувствительность и выше риск ложных срабатываний.
# Концепция конфигурации CRS (псевдо).
SecDefaultAction "phase:2,deny,log" # действие при блокировке
SetVar tx.paranoia_level = 1 # уровень паранойи 1..4
SetVar tx.inbound_anomaly_score_threshold = 5 # порог блокировки
# Каждое правило-сигнатура добавляет баллы в tx.anomaly_score;
# превышение порога -> запрос отклоняется.
Режимы: detection против prevention
У WAF два базовых режима, и порядок их использования критичен:
- Detection-only (мониторинг) — WAF анализирует запросы и логирует бы-блокировки, но всё пропускает. Это безопасный способ ввести WAF: вы видите, что бы заблокировалось, и оцениваете, сколько среди этого ложных срабатываний на реальном трафике.
- Prevention (блокировка) — WAF реально отклоняет запросы, превысившие порог. Включается только после того, как detection-режим показал приемлемый уровень ложных срабатываний.
Запуск WAF сразу в prevention на боевом сайте без обкатки — классическая ошибка: легитимные запросы (например, форма, куда пользователь правомерно ввёл апостроф или HTML-подобный текст) начинают блокироваться, и страдают реальные пользователи.
Как это работает под капотом
Движок (например, ModSecurity или его преемник Coraza) встраивается в обработку запроса по фазам: фаза заголовков запроса, фаза тела запроса, фаза заголовков ответа, фаза тела ответа. Правила привязаны к фазам, поэтому WAF может проверять и входящий запрос, и исходящий ответ (например, ловить утечку сообщения об ошибке БД). Нормализация (transformations) — отдельный важный слой: одна и та же инъекция может быть записана через URL-encoding, двойное кодирование, разный регистр — WAF приводит всё к канонической форме перед сопоставлением, иначе фильтр легко обходится.
Как защититься (правильно внедрить WAF)
- Сначала detection-only. Соберите статистику бы-блокировок на реальном трафике, прежде чем включать prevention.
- Тюнингуйте под приложение. Реальные ложные срабатывания закрывайте точечными исключениями (по правилу, URL, параметру), а не отключением целых категорий. Поднимайте Paranoia Level постепенно.
- WAF — это слой, а не замена. Параллельно чините саму уязвимость в коде: параметризованные запросы, валидация ввода, экранирование вывода. WAF выигрывает время, но не лечит причину.
- Обновляйте CRS. Набор правил развивается; устаревшая версия пропускает новые техники обхода.
- Логируйте и анализируйте срабатывания: всплеск блокировок одного типа — сигнал целенаправленной атаки.
Тестировать WAF атакующими запросами (juice-shop, DVWA, свой стенд) можно только на своих системах или в разрешённой лаборатории.
Итоги
- WAF понимает HTTP и фильтрует атаки, спрятанные внутри запросов (SQLi, XSS, path traversal).
- OWASP CRS — отраслевой набор правил «из коробки»; современный CRS использует anomaly scoring с порогом и Paranoia Level.
- Режим detection-only для обкатки, prevention — только после оценки ложных срабатываний.
- Нормализация ввода критична: без неё фильтр обходится кодировками.
- WAF даёт defense in depth и virtual patching, но не заменяет исправление уязвимости в коде.