SAST в конвейере: почему уязвимости доходят до релиза
Статический анализ кода чаще всего живёт отдельным островом: запускается по расписанию или вручную, результаты складываются в отчёт, который мало кто открывает. Сборочная линия при этом проходит полностью зелёной — ни один её шаг не смотрит на то, что за изменения в неё попали.
Поэтому уязвимости в коде всплывают не там, где появились. Непроверенный ввод, попадающий прямо в запрос, или ключ доступа, закоммиченный рядом с конфигом, спокойно доезжают до тестового контура, а иногда и до продуктивного. Находит их чаще не команда разработки, а сканер на периметре или внешний отчёт по итогам проверки.
Цена находки — не сама правка, а сопутствующая работа: выяснить, какая версия сейчас в эксплуатации, кто автор изменения, подпадает ли дефект под требования аудита, и успеть выпустить внеплановый релиз. Пока это происходит, инженеры восстанавливают контекст по чужим правкам вместо своих задач — одна находка забирает день-два работы нескольких человек. Если дефект в библиотеке, которую тянут ещё несколько сервисов, счёт идёт на релизы.
SAST меняет картину не фактом запуска, а местом проверки в процессе: статический анализ становится шагом конвейера, который останавливает сборку при находке заданного класса и оставляет след в истории изменений. Разбираем, как встроить проверку кода перед релизом, не потеряв скорость сборки.
Что меняется после встраивания проверок в сборку
Проверки кода (SAST) встраиваются в две точки: разбор изменённых файлов локально до отправки и полный проход на каждой ветке в сборке. Критичные находки блокируют слияние в основную ветку, остальные попадают в отчёт с привязкой к строке и классу дефекта из перечня OWASP. Ревьюер перестаёт быть единственным фильтром: он смотрит логику, а не ищет забытую проверку прав доступа.
Доля дефектов, найденных до ревью, растёт с четверти до 70–80%: неэкранированный ввод, секрет в конфиге и небезопасная десериализация ловятся на сборке, а не на тестировании. На ревью приходит код, уже прошедший формальный барьер, и обсуждение смещается к архитектуре.
Время разбора находки сокращается, потому что отчёт даёт контекст — файл, строка, правило, пример исправления. Разбор занимает минуты вместо получаса поисков по изменениям, если ложные срабатывания подавляются точечной настройкой, а не отключением правила целиком.
Число инцидентов после выката падает в разы: целые классы проблем не доходят до основной ветки. Единые правила анализа задают одинаковый порог строгости для всех репозиториев — новый сервис с первого дня проверяется так же, как старый, и не появляется проект с ослабленным набором правил.
Качество кода растёт без разового аврала: фиксируется базовый уровень найденных проблем, и сборка падает только на новых. Старые находки закрываются по мере правок, поэтому проверки в сборке не тормозят выпуск.
Варианты запуска SAST: сборка, изменения, расписание
SAST редко включают в одной точке конвейера: разные режимы закрывают разные риски и по-разному влияют на время сборки. Инкрементальный анализ даёт автору изменения обратную связь за минуты, полный прогон кода ловит межмодульные потоки данных, которые не видны при проверке отдельных файлов.
| Режим | Когда подходит | Ограничения |
|---|---|---|
| Проверка изменённых файлов на каждый pull request | Нужна быстрая обратная связь до ревью | Не видит связи с остальной кодовой базой, чаще даёт ложные срабатывания |
| Полный прогон кода в сборке | Небольшие репозитории, критические релизы | Удлиняет конвейер и нагружает агенты сборки |
| Ночная сборка по расписанию | Большие и многоязычные проекты | Находки приходят с задержкой, утром нужен разбор |
| Ручной запуск на ветке релиза | Подготовка к выпуску, разбор инцидента | Регулярность держится на дисциплине команды |
На практике режимы комбинируют: проверку изменённых файлов ставят обязательным шагом на каждый pull request, ночную сборку — на всю кодовую базу, а падение сборки настраивают только по находкам высокого уровня критичности. Известные срабатывания уводят в baseline-файл, иначе отчёт быстро теряет ценность и его перестают читать.
Отчёт отдаём в формате SARIF прямо в систему ревью — замечание видно в дифе, без отдельного портала. Дальше разберём, какой набор режимов уместен при вашем времени сборки и языке проекта, и зафиксируем пороги в правилах конвейера.
Внедрение по шагам: от инвентаризации до передачи
Внедрение SAST — это последовательность работ, где каждый этап опирается на результат предыдущего, а не установка одного анализатора. Начинаем с инвентаризации репозиториев: без карты сервисов, языков и веток невозможно настроить правила так, чтобы проверки не превратились в поток ложных срабатываний, который команда отключит через неделю.
- Инвентаризация репозиториев. Собираем список проектов, языков, сборщиков и активных веток, отмечаем архивные. Фиксируем, где уже работают линтеры и другие проверки, чтобы не дублировать сигналы.
- Схема интеграции. Определяем точки запуска: на каждое изменение или только перед слиянием в основную ветку. Тут же договариваемся, что делать при находке — блокировать слияние или пока предупреждать.
- Настройка профилей. Под каждый язык и тип сервиса — свой набор правил. Критичное (инъекции, утечки секретов, небезопасная работа с файлами) включаем сразу, шумные правила — в режиме наблюдения, а для старых проектов задаём базовую линию, чтобы не разбирать накопленный долг разом.
- Проверка на реальной сборке. Прогоняем анализ на нескольких боевых репозиториях: замеряем, сколько времени он добавляет к сборке, отсекаем ложные срабатывания, проверяем читаемость отчёта и ссылок на код.
- Раскатка по группам. Подключаем остальные репозитории волнами — от простых сервисов к связанным с платежами и персональными данными. Каждую волну сопровождаем разбором находок вместе с авторами кода.
- Передача команде. Отдаём регламент разбора находок, порядок обновления правил и дежурство. Отдельно фиксируем, как временно ослабить проверку — с обязательным сроком возврата.
Конфигурации, правила и регламенты: что передаём
После внедрения SAST заказчик получает не отчёт о разовой проверке, а рабочие артефакты в своём репозитории: их правят, переносят между проектами и передают новым инженерам без нашего участия. Ниже — перечень того, что остаётся у вас, с пояснением, зачем нужен каждый элемент.
- Конфигурация этапа проверки в файле конвейера: триггеры на запросы слияния и ночную сборку, порог блокировки, тайм-ауты, кэш промежуточных результатов.
- Наборы правил под ваш стек: базовый профиль плюс отдельные профили для критичных сервисов с привязкой к веткам.
- Профили анализа: глубина разбора, целевые каталоги, исключения для сгенерированного кода и внешних библиотек — каждое с обоснованием.
- Регламент реагирования: категории серьёзности, сроки устранения, кто разбирает находку, когда сборка блокируется и как оформляется мотивированный отказ.
- Схема прохождения находки: от коммита до отчёта, где хранятся результаты и как они связываются с задачами в трекере.
- Документация по проверкам: как добавить правило, как подавить ложное срабатывание, как обновлять профили при смене стека.
- Инструкция для разработчика: локальный запуск до отправки изменений, разбор отчёта, типовые сценарии исправления.
- Журнал изменений правил и матрица ответственности: кто согласует новые исключения и кто отвечает за пересмотр профилей.
Кейс: проверки в сборке сократили разбор дефектов втрое
Что было до сборочных проверок
В контуре — три продукта с общей библиотекой и раздельными репозиториями. Статический анализ запускали вручную перед релизом: находки копились месяцами и разбирались пачками, на одну волну уходило до двух недель инженерного времени. Половина замечаний относилась к коду, который всё равно переписывали, — полезный сигнал тонул в шуме, а правки после ревью тянули сроки выпуска.
Как настроили пороги
Развернули SAST прямо в конвейере сборки на базе SonarQube и зафиксировали базовую линию по текущему состоянию кода: старые находки попали в отчёт, но сборку не блокировали — иначе команды встали бы в первый же день. Порог качества распространили только на новые изменения и правки в затронутых файлах, а правила разбили на три уровня: блокирующие, предупреждения и информационные. Генераторы, миграции и тестовые заготовки вынесли в исключения, чтобы отчёт не терял доверие.
За три месяца доля дефектов, доходящих до релиза, сократилась втрое, время разбора находок на изменение — с 40 до 12 минут, а доля новых правок под проверками выросла до 90%. Отчёт в описании изменения снял отдельную стадию согласований: автор видит причину до ревью и закрывает её сам.
SAST или динамический анализ: что выбрать на старте
SAST и динамический анализ отвечают на разные вопросы. Статический разбор идёт по исходникам и не запускает приложение: он строит граф вызовов и отслеживает поток данных от точек входа до опасных операций — так находятся инъекции, обход проверок прав, небезопасная десериализация, ошибки в работе с криптографией. Он видит код, который ещё не покрыт тестами, и укладывается в минуты на этапе слияния ветки.
Динамический анализ смотрит на уже работающее приложение: подставляет данные в реальные запросы и фиксирует то, что проявилось в рантайме — ошибки конфигурации, лишние заголовки, доступ к чужим объектам. Ложных срабатываний здесь меньше, но покрытие ограничено сценариями, которые вы прогнали, и кодом, до которого эти сценарии дошли. Поэтому подходы не заменяют, а дополняют друг друга.
Третий слой — проверка зависимостей: манифесты и файлы блокировки сверяются с базами известных уязвимостей, включая транзитивные библиотеки, и отдельно проверяются лицензии. Включается быстрее остальных, не требует полной сборки проекта и даёт заметную долю реальных находок, потому что значительная часть кода приходит извне.
Начинать разумно с зависимостей: минимальная цена включения в конвейер сборки и предсказуемый результат. Дальше — SAST на изменённом коде, инкрементально, по диффу ветки, чтобы команда не тонула в срабатываниях; когда ложные помечены и порог по критичности согласован, проверку расширяют на весь репозиторий и делают блокирующей. Динамический анализ подключают, когда есть стенд со стабильными данными и повторяемые сценарии. Один настроенный инструмент с разобранной базой срабатываний полезнее трёх, включённых формально.
Частые сомнения: ложные срабатывания и скорость сборки
Сомнения инженеров вокруг SAST обычно сводятся к четырём вещам: сколько шума придёт в отчёте, что станет с порогом блокировки сборки, успеет ли проверка уложиться в конвейер и что делать с наследием в коде, где замечаний накопились тысячи. Разбираем каждое — с тем, как это закрывается на практике.
Общий принцип — не включать проверку «на всё и сразу», а сначала зафиксировать базовый срез: текущие находки помечаются как известный долг, блокирующими становятся только новые. Такой режим даёт команде чистый сигнал с первого дня и не останавливает релизы.
Сборка встанет из-за ложных срабатываний?
Порог блокировки настраивается по классу правила и уровню достоверности: сборку останавливают только подтверждённые уязвимости в изменённом коде, спорные находки уходят в отчёт без блокировки. Каждое исключение оформляется правилом с причиной и сроком пересмотра — шум не копится молча.
Насколько замедлится проверка?
Анализ идёт по изменённым файлам и их зависимостям, а не по всему коду, результаты кэшируются между сборками. Полный глубокий проход выносится в отдельное расписание. Для типовой сборки это добавляет минуты, а не десятки минут, и не блокирует параллельные задачи.
У нас тысячи старых замечаний — с чего начать?
Наследие в коде разбирается по базовому срезу: фиксируем текущий объём, раскладываем по критичности и модулям, дальше строгий порог действует только на новый код. Старые находки закрываются планово — в первую очередь на горячих путях и на периметре, где риск выше. Единые правила остаются общими для всех команд, а различия оформляются профилями и локальными политиками, а не отключением проверок.
Обсудим задачу: точки внедрения и порядок шагов
Чтобы оценка и план опирались на факты, а не на предположения, до старта работ фиксируем точки внедрения и порядок шагов. Ниже — вопросы, которые снимаем на первом разговоре: от ответов зависит объём работ и последовательность, в которой SAST встраивается в существующий конвейер сборки.
- Где ставим проверку: шаг сборки, предкоммитный хук, сканирование образа перед публикацией в реестр или комбинация точек.
- Основной язык и сборщик, есть ли генерация кода и зависимости, которые собираются только на сборочном агенте.
- Режим старта: отчёт без блокировки сборки или остановка при превышении порога по критичности.
- Кто владеет правилами исключений и как подтверждается ложное срабатывание — иначе правило отключат целиком.
- Как находки доходят до разработчика: комментарий в задаче, отчёт артефактом сборки, сводка по релизу.
- Какие ветки защищены и что происходит при падении проверки — сборка останавливается или идёт дальше с пометкой.
- Что требуется по истории находок и доступам к отчётам, нужна ли выгрузка во внешнюю систему.
- Критерии приёмки: доля проверяемых изменений, время до первой находки, сколько критичных дефектов доходит до стенда.
Опишите задачу и то, как сейчас устроен конвейер, — вернёмся с оценкой и планом: точки внедрения, порядок шагов, сроки и критерии приёмки.







