Тестирование безопасности: SAST, DAST и ревью

Безопасность нельзя «доказать», но её можно непрерывно проверять.

SAST анализирует исходный код без запуска. DAST проверяет работающее приложение снаружи. Вместе с ревью и SCA они образуют сито на разных этапах.

Зачем несколько видов проверок

Ни один инструмент не ловит всё. SAST видит код, но не контекст запуска; DAST видит поведение, но не исходник; ревью видит замысел, но человек устаёт; SCA видит зависимости. Их сила — в сочетании: каждый закрывает то, что пропускают другие. Это снова defense in depth, но уже на уровне процесса.

Полезно мыслить об этом как о ситах с разным размером ячейки, поставленных друг за другом. Сквозь одно сито проходит то, что оно по своей природе не способно удержать: статический анализатор не «увидит» уязвимость, которая проявляется только при определённой конфигурации сервера в рантайме, потому что он вообще не запускает приложение. Динамический сканер, наоборот, не заглянет в ветку кода, до которой не добрался по сети, и не прочитает комментарий с пометкой о временном костыле. Но проблема, проскочившая через первое сито, вполне может застрять во втором. Чем разнообразнее методы, тем меньше шансов, что дефект проскользнёт через все слои сразу.

Из этой логики следует и важное предостережение: нельзя выбирать инструменты по принципу «возьмём самый дорогой и закроем тему». Дорогой DAST не отменяет необходимости ревью, а модный SAST не заменяет проверку зависимостей. Бюджет правильнее распределять по слоям, а не вкладывать всё в один, потому что классы уязвимостей, которые каждый слой ловит, почти не пересекаются.

SAST и линтеры безопасности: на этапе кода

SAST и security-линтеры ищут опасные паттерны прямо в коде: конкатенацию SQL, вызов shell со строкой, innerHTML с переменной, использование слабого хеша, захардкоженные секреты. Их встраивают в CI и в редактор, чтобы ловить проблему до мерджа.

# Примеры проверок в пайплайне (этап кода)
semgrep --config auto        # SAST-правила для опасных паттернов
bandit -r .                  # security-линтер для Python
gitleaks detect              # поиск секретов в коде и истории

У SAST есть ложные срабатывания — это нормально: лучше разобрать лишнее предупреждение, чем пропустить реальное. Важно лишь не скатиться в крайность: если предупреждений сотни и команда привыкла их игнорировать, ценность инструмента падает до нуля. Поэтому SAST настраивают: отключают заведомо неприменимые правила точечно (а не пачкой), помечают разобранные ложные срабатывания, чтобы они не всплывали снова, и в первую очередь требуют внимания к находкам высокой критичности. Хорошо настроенный анализатор шумит редко, и тогда каждое его срабатывание воспринимается всерьёз.

Отдельно стоит выделить поиск секретов в коде и истории репозитория. Захардкоженный токен опасен вдвойне: его видно всем, у кого есть доступ к репозиторию, и он остаётся в истории git даже после удаления из текущей версии файла. Поэтому сканер секретов запускают не только по рабочему дереву, но и по истории коммитов, а найденный ключ считают скомпрометированным и немедленно ротируют, а не просто стирают строку.

DAST: по работающему приложению

DAST бьёт по запущенному приложению как «чёрный ящик»: шлёт запросы и смотрит на реакцию, выявляя то, что видно только в рантайме, — отсутствие заголовков безопасности, отражённые ошибки, доступные без авторизации эндпоинты. Запускают по стенду, а не по проду; для глубоких проверок привлекают ручной пентест.

Сильная сторона DAST в том, что он проверяет систему такой, какой её увидит атакующий: со всеми реальными настройками веб-сервера, балансировщика, заголовков и обработчиков ошибок. SAST смотрит на исходник одного сервиса, а DAST — на собранную и развёрнутую систему целиком, включая то, что в коде вообще не описано: забытый отладочный эндпоинт, неправильно настроенный CORS, утечку версии сервера в заголовке. Поэтому два метода не конкурируют, а смотрят на продукт с двух сторон — изнутри по тексту и снаружи по поведению.

Есть и ограничения, о которых важно помнить. DAST по определению проверяет только те пути, до которых смог дойти: если для глубоких сценариев нужна аутентификация или сложная последовательность шагов, сканеру надо дать валидные учётные данные и сценарии, иначе он останется на поверхности. Запускать DAST по продакшену опасно — он шлёт реальные запросы, может создавать мусорные данные и нагружать систему, поэтому его место на отдельном тестовом стенде. А там, где автоматический сканер бессилен — в сложной бизнес-логике и многошаговых атаках, — на сцену выходит ручной пентест, который дороже, но видит то, что машине недоступно.

Security code review: что искать

Автоматика не заменяет человека: логические дыры в авторизации инструменты видят плохо. На ревью проверяйте по чеклисту из всего курса:

ЗонаВопрос на ревью
вводвалидируется ли, allowlist?
запросыпараметризованы, без склейки?
выводэкранируется под контекст?
авторизацияпроверка прав на сервере, на каждый объект?
секретынет хардкода, ничего в логи?
ошибкиgeneric пользователю, без стека?

Как работает под капотом: security gate в CI

Зрелый процесс собирает проверки в гейт: на каждый pull request автоматически прогоняются SAST, SCA и тесты; сборка блокируется при находках высокой критичности; DAST идёт по тестовому стенду. Так безопасность становится частью обычного цикла, а не разовым «аудитом перед релизом». Это и есть инженерное воплощение shift-left из первого урока.

PR -> [SAST] -> [SCA] -> [тесты] -> merge -> deploy(staging) -> [DAST]
          \________ блокируют merge при high-критичности ________/

Частые ошибки

  • Один инструмент на всё. SAST, DAST, ревью и SCA дополняют друг друга.
  • Проверки «перед релизом». Дорого и поздно; встраивайте в CI на каждый PR.
  • Слепо доверять автоматике. Логику авторизации проверяет человек.
  • Игнорировать находки как «ложные». Разбирайте, а не отключайте правила скопом.
  • DAST без учётных данных и сценариев. Сканер останется на поверхности и не дойдёт до защищённых путей.
  • Запуск DAST по продакшену. Реальные запросы создают мусор и нагрузку; место сканера — на стенде.

Итоги

  • SAST (код), DAST (рантайм), ревью (замысел) и SCA (зависимости) дополняют друг друга.
  • Встраивайте проверки в CI как гейт на каждый PR — это shift-left на практике.
  • Security review по чеклисту ловит логические дыры авторизации, которые не видит автоматика.
Проверьте себя
1. Чем SAST отличается от DAST?
AНичем, это синонимы
BSAST анализирует исходный код без запуска, DAST проверяет уже работающее приложение снаружи
CSAST работает только в проде
DDAST читает исходный код построчно
2. Почему стоит использовать SAST, DAST, ревью и SCA вместе, а не один инструмент?
AЧтобы потратить больше времени
BКаждый ловит то, что пропускают другие (код, рантайм, замысел, зависимости) — это defense in depth на уровне процесса
CПотому что один инструмент запрещён
DЧтобы получить больше отчётов
3. Что лучше всего ловит человек на security code review, а не автоматика?
AОпечатки в комментариях
BЛогические дыры в авторизации (например, забытую проверку владения объектом)
CФорматирование кода
DСкорость работы запросов