SAST, DAST, IAST в разработке
Разбираемся, на каком этапе и каким способом автоматические анализаторы ловят уязвимости, как встроить их в IDE и CI, как читать находки и не утонуть в ложных срабатываниях.
SAST, DAST, IAST — три способа автоматически искать уязвимости: статический анализ исходного кода, динамический анализ работающего приложения и интерактивный анализ изнутри запущенного приложения. Они смотрят на программу с разных сторон и ловят разные классы дефектов.
Безопасность невозможно проверить одним прогоном раз в год. Между релизами в код попадают сотни изменений, и любое может внести уязвимость. Поэтому защиту автоматизируют: машина проверяет каждый коммит так же, как уже проверяет тесты и линтер. Этот урок — карта трёх подходов к такому анализу: что каждый ловит, что пропускает и куда его ставить в процессе. Важно: запускать сканеры безопасности можно только против своего кода и своих стендов — сканирование чужого приложения без письменного разрешения владельца подпадает под статью 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): инструмент не знает контекста выполнения и иногда подсвечивает безопасный код. Примеры: 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
IAST — интерактивный анализ изнутри
IAST (Interactive Application Security Testing) — гибрид. В приложение встраивается агент (инструментация рантайма), который наблюдает за выполнением изнутри, пока приложение работает под нагрузкой автотестов или DAST-сканера. Агент видит и реальный поток данных в памяти, и строку кода, где недоверенный ввод дошёл до опасной операции. Поэтому IAST совмещает преимущества: точность до строки (как SAST) и подтверждение в рантайме (как DAST), что резко снижает ложные срабатывания.
Плата за это — приложение нужно запустить с агентом и иметь набор тестов, которые «прогонят» код: IAST видит только исполненные пути. Поэтому IAST обычно ставят в QA-окружение и связывают с уже существующими функциональными или DAST-тестами.
Как это работает под капотом
Все три сводятся к сопоставлению с шаблоном, но на разных представлениях программы. SAST матчит шаблоны на синтаксическом дереве и графе потока данных исходника — без запуска. DAST матчит отклики работающего приложения на заготовленные пробы — снаружи, не зная кода. IAST через инструментацию рантайма отслеживает поток данных внутри исполняющегося процесса и связывает sink со строкой источника. Отсюда их ограничения: SAST не знает рантайма, DAST не знает кода, IAST видит только исполненные тестами пути.
Куда ставить в IDE и CI
Каждый анализ эффективнее на своём этапе:
| Подход | Что анализирует | Где в процессе | Ложные срабатывания |
| SAST | исходный код (white-box) | IDE / pre-commit / pull request | много |
| DAST | работающее приложение (black-box) | staging после деплоя | мало |
| IAST | рантайм изнутри (grey-box) | QA, вместе с автотестами | очень мало |
В IDE подключают быстрый SAST-плагин, чтобы подсветка появлялась прямо при наборе. В CI первым шагом ставят SAST на изменённые файлы pull request, чтобы сборка падала на критичных находках; DAST и IAST включают позже, на развёрнутом стенде. Пример шага CI:
sast:
stage: test
script:
- semgrep --config=auto --error ./src # ненулевой код выхода = сборка падает
Разбор находок и ложные срабатывания
Находку нельзя слепо принимать или слепо игнорировать — её нужно триажить. Алгоритм разбора: понять класс уязвимости и где source/sink; проверить, достижим ли путь реально и нет ли уже санитизации; оценить влияние. Если уязвимость реальна — завести задачу и починить; если это ложное срабатывание — пометить исключение в конфиге инструмента с комментарием почему, а не глобально отключать правило.
Главный риск — «усталость от алертов»: когда отчёт состоит на 90% из шума, команда перестаёт его читать и пропускает настоящую дыру. Поэтому правила настраивают под проект, базовый уровень фиксируют, а в гейт сборки выносят только высокоуверенные критичные находки.
Как защититься
1. Используйте все три подхода, а не один. Они закрывают разные слепые зоны: код, рантайм, исполняемые пути.
2. Сдвигайте проверки влево (shift-left). Чем раньше (IDE, pre-commit, PR) — тем дешевле починка.
3. Триажьте находки и душите шум. Помечайте проверенные исключения с комментарием, чтобы команда доверяла отчёту.
4. Не считайте «зелёный отчёт» доказательством безопасности. Сканеры ловят известные шаблоны; логические уязвимости и бизнес-логику проверяет человек — код-ревью и пентест.
Итоги
- SAST читает исходный код не запуская (white-box): рано и точно, но много ложных срабатываний.
- DAST атакует работающее приложение снаружи (black-box): ловит рантайм и конфигурацию, но не указывает строку.
- IAST наблюдает изнутри через агента (grey-box): точно до строки и почти без шума, но видит только исполненные тестами пути.
- Каждый подход встраивается на своём этапе: SAST — в IDE/PR, DAST — на staging, IAST — в QA с автотестами.
- Находки нужно триажить, гасить шум и помнить: «зелёный отчёт» не заменяет ревью и пентест.