Привет, меня зовут Олег Рыбченко, я работаю QA-инженером в hh.ru. Количество атак на IT-инфраструктуру сегодня растет в геометрической прогрессии — об этом свидетельствуют многочисленные упоминания во всевозможных СМИ, так что не будем в очередной раз приводить графики и статистику. Разумеется, в таких условиях все больше компаний хотят позаботиться о безопасности своих сайтов и начинают проявлять интерес к современным автоматизированным инструментам по обнаружению уязвимостей. В статье разберемся, как можно реализовать и получить полноценные отчеты динамического анализа с подробно описанными потенциальными уязвимостями с помощью DAST.
Виды анализаторов кода
Многие уже знакомы с SAST — статическими анализаторами кода. Работают они быстро, но со множеством ложных срабатываний. Некоторые уже успели их внедрить, а кто-то уже даже отказаться от них. В основном из-за шума нерелевантных срабатываний и невозможности сходу сказать о степени эксплуатируемости конкретной находки, то есть запускается ли вообще когда-нибудь найденная строка кода.
Последнее время растет интерес к DAST — динамическим анализаторам, которые умеют имитировать злоумышленников и делать запросы к работающему сайту. Существуют и другие классы анализаторов: IAST, интерактивные анализаторы, интегрируемые в код приложения — точные, но тяжелые, MobAST, анализаторы мобильных приложений и другие. Но про них мы сегодня говорить не будем и остановимся на DAST.
Как правило, DAST — это довольно дорогое решение, которое не всегда укладывается в бюджет безопасности компаний. Мы в hh.ru решили проверить, можно ли бесплатно получить работающий DAST, построенный на Open-Source продукте OWASP ZAP (Zed Attack Proxy). В этой статье мы хотим показать, как это можно реализовать и получить полноценные отчеты динамического анализа с подробно описанными потенциальными уязвимостями. Отдельно отметим, что мы не ставим цель сравнить результаты работы с другими платными и бесплатными инструментами.
Очевидные преимущества ZAP:
большие возможности для интеграции и автоматизации;
широкое комьюнити OWASP, хорошая техподдержка и исчерпывающая документация;
запуск краулеров для составления карты приложения;
пассивное (без изменения запросов) и активное (с изменением запросов) сканированием сайта на уязвимости;
генерация отчетов в разных форматах по результатам сканирования;
удобный UI, где можно легко настраивать параметры сканирования;
настройка автоматизации с помощью всего одного yaml-файла.
Об этом способе как раз и пойдет речь сегодня.
Настраиваем конфиг для сканирования
Делается это в 2 этапа и очень удобно (в том числе для новичка) через UI. Подробно про работу с ZAP UI в ручном режиме можно прочитать в этой статье.
Настраиваем скоуп, потому что если мы будем сканировать все подряд, то сканирование может занять дни, а то и недели. Затем аутентификацию — если не настроить её, то сможем тестировать наш сайт только под анонимом.
Открываем окно настройки сессии:
Добавляем эндпоинты, которые будем сканировать в рамках скоупа:
Настраиваем эндпоинты, которые вдруг решили не сканировать:
Например, это могут быть статические статьи без интерактива, метрики аналитики, или там пока ведется разработка. Также частая причина — наличие большого числа циклических ссылок, которые затянут процесс сканирования.
Заполняем учетные данные, под которыми будем ходить на сайт
Вводим логин, пароль:
Обязательно выбираем учетную запись Forced User, чтобы она всегда была в авторизованном состоянии:
Выбираем тип (мы рассмотрим на примере Form-based)
Задаем url, где происходит login
Задаем url, куда нужно пойти GET-ом для того, чтобы собрать csrf-токен (ZAP сам автоматом подставит его вместо secret)
Задаем POST-параметры для аутентификации ({%username%} и {%password%} ZAP подставит из раздела users, который мы заполнили на предыдущем шаге)
Настраиваем план автоматизации
Нажимаем + на панели снизу и выбираем Automation, нажимаем “Создать план” и выбираем FullScan. Появляется набор джоб, которые запустятся в автоматическом режиме. Для джоб можно добавлять условия и тесты, которые будут их контролировать.
Важно! Если вы не хотите, чтобы сканированирование занимало дни, а то и недели, рекомендуем ограничивать краулер (spider) по глубине поиска и активное сканирование по времени.
Как вариант можно сделать 2 плана: один для частых быстрых прогонов критической функциональности, а второй полный.
Нажимаем на env и выбираем созданный нами скоуп:
Теперь можем запустить прогон для того, чтобы удостовериться, что все работает и настроено правильно:
Последний штрих – сохранить готовый конфиг:
Получим yaml-файл, в котором будет только самое нужное. Альтернативно можно конечно же взять полный конфиг и настроить все самим по документации. Но для быстрого старта или пилота мы рекомендуем начать с конфигурации через UI — это и проще, и выглядит логично.
Запускаем сканирование
Теперь можно запускать сканирование через ZAP Automation Framework всего одной строчкой:
docker run -v $(pwd):/zap/wrk/:rw --rm -t owasp/zap2docker-stable zap.sh $1 -cmd -autorun wrk/$2 |
Тут важно отметить, что можно бы и сразу все запустить этой строкой, без указания файла конфига — тогда ZAP использовал бы все настройки по умолчанию. Но, как уже было указано ранее, мы бы не смогли сканировать под авторизованным пользователем, и в режиме "без ограничений" сканирование могло бы занять очень много времени.
В качестве параметров можно передать:
$1: --addonupdate, тогда ZAP автоматически будет скачивать и устанавливать обновления. Можно не передавать
$2: файл yaml конфига. Обязательный параметр
Как можно настроить интеграцию
Мы используем Bamboo CI/CD. Запуск там можно настроить по расписанию. Конфиги лежат на сервере, а все джобы bamboo у нас настроены по ssh:
После окончания прогона ZAP кладет отчеты в папку. В Bamboo у нас есть отдельная джоба, которая запускает на сервере скрипт выгрузки отчетов в облако. Мы, например, для этого используем Minio:
Вот как у нас
В заключение покажем, как выглядят отчеты от ZAP на примере полученного нами для hh.ru:
В каждом отчете присутствует:
Список найденных уязвимостей по OWASP Top 10
Подробные описания уязвимостей
Векторы атак, с помощью которых были найдены уязвимости и как их можно воспроизвести
Советы по устранению уязвимостей
К примеру, была найдена вот такая потенциальная SQL-инъекция:
При подстановке 1" OR "1"="1" в get-параметр исчезал блок с регионом поиска. Сам факт изменения верстки на сайте — отправная точка для проверки наличия в этом месте реальной SQL-инъекции. К счастью, срабатывание оказалось ложным, но хорошо, что оно было обнаружено при помощи ZAP.