SAST, DAST и SCA: автоматический поиск уязвимостей
Учимся отличать три вида автоматического анализа безопасности и понимать, что каждый из них находит, а что пропускает — чтобы выстроить защиту слоями в пайплайне.
SAST/DAST/SCA — три взаимодополняющих класса инструментов: статический анализ кода, динамический анализ работающего приложения и анализ состава зависимостей. Вместе они автоматизируют поиск уязвимостей в конвейере разработки.
Ручной аудит безопасности дорог и проводится редко. Между аудитами в код попадают сотни изменений, и каждое может внести уязвимость. Идея DevSecOps — заставить машину проверять безопасность на каждом коммите, как уже проверяются тесты и линтер. Этот урок — про три семейства таких сканеров, их сильные и слабые стороны. Запускать их можно только против своего кода и своих стендов: сканирование чужого приложения без разрешения владельца попадает под статью 272 УК РФ.
Зачем это знать разработчику
Стоимость исправления уязвимости растёт по мере её продвижения к продакшену. Баг, пойманный сканером на коммите, чинится за минуты; та же уязвимость, найденная в проде после инцидента, обходится в простой, расследование и репутационный ущерб. Понимая, что именно умеет каждый класс инструментов, разработчик не полагается вслепую на «зелёный отчёт» и сознательно закрывает слепые зоны. Это и есть mindset защитника: не один волшебный сканер, а продуманная комбинация.
SAST — статический анализ кода
SAST (Static Application Security Testing) читает исходный код или байт-код, не запуская его. Инструмент строит из программы граф потока данных и ищет шаблоны опасного кода: пользовательский ввод, который доходит до SQL-запроса без параметризации; конкатенация в команду оболочки; захардкоженный пароль; небезопасный криптоалгоритм. Концептуально SAST отслеживает путь от источника (source — недоверенный ввод) до стока (sink — опасная операция):
source (request.args) ──> обработка ──> sink (cursor.execute)
если по пути нет санитизации/параметризации —> находка SQLi
Сильная сторона SAST — он видит весь код, включая редкие ветки, и указывает точную строку. Запускается рано, прямо в IDE или на pull request. Слабая сторона — ложные срабатывания (false positives): инструмент не знает контекста выполнения и иногда подсвечивает безопасный код. Поэтому находки SAST нужно триажить — разбирать, реальна ли уязвимость. Примеры инструментов: Semgrep, Bandit (Python), CodeQL.
# SAST против своего репозитория: ищем антипаттерны в коде
semgrep --config=auto ./src
bandit -r ./src # специализирован под Python
DAST — динамический анализ работающего приложения
DAST (Dynamic Application Security Testing) подходит с другой стороны: он не видит код, а взаимодействует с развёрнутым приложением снаружи, как пользователь или браузер. Сканер обходит страницы и эндпоинты, подставляет в параметры пробные значения и анализирует ответы: появилась ли SQL-ошибка, отразился ли ввод в HTML без экранирования, как ведёт себя аутентификация. По сути DAST автоматизирует часть проверок, которые делает пентестер.
Сильная сторона — DAST находит проблемы, видимые только в рантайме: ошибки конфигурации сервера, отсутствие security-заголовков, проблемы сессий — то, чего нет в исходниках. Он не зависит от языка. Слабая сторона — видит только то, до чего дотянулся: непокрытый эндпоинт остаётся непроверенным, и точную строку кода DAST не укажет. Запускают его на тестовом стенде (не на проде с живыми данными):
# DAST против СВОЕГО тестового стенда (например, локальный OWASP Juice Shop)
zap.sh -cmd -quickurl http://localhost:3000 -quickout report.html
OWASP ZAP — классический бесплатный DAST. Запускать его разрешено только против стендов, которыми вы владеете или на которые есть письменное согласие.
SAST и DAST дополняют друг друга
Их часто противопоставляют, но правильнее использовать оба. SAST — «белый ящик» (white-box): видит внутренности, ловит баг рано и точечно, но не знает рантайма. DAST — «чёрный ящик» (black-box): видит поведение, ловит конфигурацию и интеграции, но не указывает строку. Уязвимость, которую пропустит один, нередко поймает другой.
SCA — анализ зависимостей
SCA (Software Composition Analysis) проверяет не ваш код, а чужой — сторонние библиотеки, которые вы подключили. Современное приложение на 80–90% состоит из зависимостей, и уязвимость в любой из них становится вашей уязвимостью. SCA сверяет список пакетов (и их версии) с базами известных уязвимостей (CVE) и сообщает: «в этой версии библиотеки есть известная дыра, обновитесь до такой-то».
# SCA: проверка зависимостей на известные CVE
npm audit # для Node.js
pip-audit # для Python
# в CI часто используют отдельные сканеры (Trivy, OWASP Dependency-Check, Snyk)
SCA критичен, потому что эта категория (уязвимые и устаревшие компоненты) — отдельный пункт в OWASP Top 10. Подробно безопасность зависимостей разбирается в следующем уроке; здесь важно запомнить место SCA в общей картине: он закрывает тот пласт риска, который SAST и DAST не видят, ведь код библиотеки вы не пишете и не сканируете построчно.
Как это работает под капотом
Все три класса сводятся к сопоставлению с шаблоном, но на разных представлениях программы. SAST матчит шаблоны на синтаксическом дереве и графе потока данных исходника. DAST матчит отклики работающего приложения на заранее заготовленные пробы. SCA матчит имена и версии пакетов против базы CVE. Отсюда и их ограничения: SAST не знает рантайм-окружения, DAST не знает код, SCA не оценивает, используется ли уязвимый участок библиотеки на самом деле. Ни один не даёт стопроцентной гарантии — поэтому защита строится слоями.
Где их место в пайплайне
Каждый инструмент включается там, где он эффективнее всего:
| Инструмент | Что анализирует | Когда в пайплайне |
| SAST | исходный код (white-box) | IDE / pre-commit / на pull request |
| SCA | зависимости (CVE) | на каждый build, при изменении lock-файла |
| DAST | работающее приложение (black-box) | на staging-стенде после деплоя |
SAST и SCA — быстрые и «сдвинуты влево» (shift-left), ближе к моменту написания кода. DAST требует развёрнутого приложения, поэтому идёт позже, на тестовом окружении. Как превратить эти проверки в обязательный гейт сборки — тема последнего урока раздела.
Как защититься
1. Используйте все три класса, а не один. Они закрывают разные слепые зоны: код, рантайм, зависимости.
2. Сдвигайте проверки влево. Чем раньше (IDE, pre-commit, PR) — тем дешевле починка.
3. Триажьте находки. Особенно у SAST много ложных срабатываний; настраивайте правила под проект и помечайте проверенные исключения, чтобы команда не привыкла игнорировать отчёты.
4. Не считайте «зелёный отчёт» доказательством безопасности. Сканеры находят известные шаблоны; логические уязвимости и бизнес-логику по-прежнему проверяет человек (код-ревью, пентест).
Итоги
- SAST читает исходный код не запуская его (white-box): ловит баг рано и точечно, но даёт ложные срабатывания.
- DAST атакует работающее приложение снаружи (black-box): ловит рантайм и конфигурацию, но не указывает строку.
- SCA сверяет зависимости с базами CVE: закрывает риск чужого кода, который вы не пишете.
- Инструменты дополняют друг друга и встраиваются в пайплайн по принципу shift-left (раньше — дешевле).
- Запускать сканеры можно только против своего кода/стендов; «зелёный отчёт» не заменяет ревью и пентест.