Латунная воронка на тёмном антистатическом коврике: из широкого горлышка хаотично рассыпаются янтарные бусины, а узкий носик пропускает лишь три — в чёрный лоток.


Ненастроенный SAST - генератор шума. На практике дефолтные правила выдают 60–90% ложных срабатываний, а после тюнинга показатель падает до 10–20%. Для команды из 10 разработчиков с 40 PR в неделю разница между этими числами - порядка 24 инженерных часов, потраченных на разбор мусора вместо фикса реальных уязвимостей. Я прошёл этот путь на трёх проектах: Python-монорепо, кластер Go-микросервисов, TypeScript-фронтенд. Во всех случаях проблема была не в инструментах - их включили с дефолтными настройками и ждали чуда.

Почему статический анализ кода в пайплайне порождает шум​

SAST-инструменты работают через паттерн-матчинг по AST (абстрактному синтаксическому дереву) или через полный семантический анализ с построением графа потока данных. Оба подхода отвечают на один вопрос: содержит ли код паттерн, ассоциированный с известным классом уязвимости? Ни один из них не скажет, эксплуатируема ли уязвимость в рантайме.

Alert fatigue возникает на стыке трёх факторов:
  • Дефолтные наборы правил покрывают максимальный спектр языков и фреймворков - за счёт точности
  • Сканирование всей кодовой базы при каждом коммите превращает pipeline в бутылочное горлышко
  • Отсутствие baseline приводит к отчёту о проблемах пятилетней давности при каждом запуске
С точки зрения модели угроз, CI/CD-пайплайн сам по себе - поверхность атаки. OWASP Top 10 CI/CD Security Risks описывает технику Poisoned Pipeline Execution (CICD-SEC-4): модификация CI-конфигурации для запуска произвольного кода в контексте сборки. T1562.001 (Disable or Modify Tools) - сценарий отключения security-сканирования в пайплайне. Если разработчики привыкли игнорировать SAST-алерты из-за шума, отключение сканера может пройти незамеченным. Прямая связь между alert fatigue и реальным снижением безопасности. Именно поэтому тюнинг SAST в DevSecOps - не опция, а необходимость, зафиксированная в OWASP DevSecOps Maturity Model (DSOMM) в категориях Build и Test.

Критерии отбора: почему Semgrep, CodeQL и SonarQube​

Три инструмента - три архитектурных подхода к автоматическому анализу безопасности кода:
  • Semgrep - паттерн-матчинг с поддержкой taint-трекинга в Pro-версии; самый быстрый в CI/CD
  • CodeQL - семантический анализ через реляционную базу кода; самый глубокий
  • SonarQube - гибрид code quality и security с mature-средой; самый распространённый
Что осталось за рамками. Snyk Code - IDE-first инструмент с сильной SCA-частью, но SAST вторичен: глубина taint-трекинга уступает CodeQL и Semgrep Pro. Checkmarx One - enterprise-платформа для команд 50+ с выделенным AppSec; при этом в марте 2025 года GitHub Action tj-actions/changed-files, используемый во многих CI/CD-пайплайнах, был скомпрометирован в рамках атаки на цепочку поставок (T1195.002, Initial Access) - наглядная иллюстрация рисков зависимости от сторонних Actions. Bandit и ESLint security-плагины - одноязычные линтеры без cross-file анализа, для production-пайплайна недостаточны как самостоятельное решение.

Архитектурные отличия трёх SAST инструментов​

Semgrep - настройка правил за минуты​

Semgrep парсит код в AST и применяет паттерн-матчинг с синтаксисом, который выглядит как целевой язык. Правило для поиска SQL-инъекции в Python визуально похоже на сам уязвимый код - порог входа в написание кастомных правил минимальный.

Open-source CLI (лицензия LGPL 2.1) анализирует в рамках одного файла и одной функции. Semgrep Pro добавляет interprocedural taint analysis и cross-file отслеживание потока данных. Diff-aware сканирование работает по умолчанию, время анализа PR - секунды, даже на крупных кодовых базах.

Ограничения:
  • Open-source версия не отслеживает data flow через границы функций и файлов - сложные taint-цепочки пропускаются
  • Community-правила неоднородны по качеству и требуют ревью перед включением (я на одном проекте нашёл три правила, которые стабильно давали false positive на стандартном Django ORM - пришлось выкинуть)
  • В 2024 году Semgrep изменил лицензирование части правил на Semgrep Rules License, ограничивающую коммерческое и SaaS-использование. Движок остаётся под LGPL 2.1. В январе 2025 появился community-форк OpenGrep без платного уровня
  • Стоимость Pro: ориентировочно от $40/dev/month, актуальные цены - semgrep.dev/pricing

CodeQL - анализ уязвимостей на уровне семантики​

CodeQL строит реляционную базу данных всей кодовой базы: каждая переменная, вызов функции и поток данных становятся queryable facts. Запрос на языке QL проследит, достигает ли user-controlled input точки SQL-выполнения через пять промежуточных функций и абстракцию базы данных. Принципиально другой подход: Semgrep ищет паттерны, CodeQL понимает семантику. Результат - самый низкий false positive rate среди инструментов в этом сравнении.

Ключевая особенность, влияющая на выбор: CodeQL требует компиляции проекта для построения базы данных (для компилируемых языков: Java, Go, C/C++). CI-джоб должен иметь доступ ко всем зависимостям и build-инструментам. Для Python и JavaScript компиляция не нужна, но для Java или Go этот шаг добавляет время и сложность. GitHub поддерживает инкрементальный анализ для PR-сканирования - точные метрики ускорения зависят от размера кодовой базы.

Ограничения:
  • Время сканирования: 20–45 минут на среднем монорепо - это выталкивает CodeQL из PR-чеков в nightly или merge-to-main
  • QL имеет крутой порог входа: написание кастомного запроса - дни, не минуты
  • Официально поддерживаемые языки: C/C++, C#, Go, Java/Kotlin, JavaScript/TypeScript, Python, Ruby, Swift - PHP отсутствует (актуальный список - в документации GitHub CodeQL)
  • Полный опыт (Copilot Autofix, PR-комментарии) привязан к GitHub
  • Стоимость: бесплатен для публичных репо; для приватных - через GitHub Advanced Security, ориентировочно от $49/committer/month - актуальные цены на github.com/pricing

SonarQube - интеграция code quality и security​

SonarQube совмещает code quality (баги, code smells, метрики сложности) с security-сканированием. Community Edition бесплатна, поддерживает 30+ языков и запускается на собственной инфраструктуре - полный контроль над исходным кодом.

Quality gates - главная сила SonarQube: PR не может быть смержен, если не проходит определённые пороги по количеству и severity уязвимостей. Для команд, которым нужен один инструмент для quality и security с compliance-отчётами (SOC 2, ISO 27001), SonarQube - логичный выбор.

Ограничения:
  • Первые две недели после внедрения уходят на включение и выключение правил, а не на фикс уязвимостей
  • Community Edition не включает taint analysis и cross-function data flow - они доступны начиная с Developer Edition
  • Время сканирования: 5–30 минут для средних проектов
  • SCA (анализ зависимостей) отсутствует в ядре - нужны плагины или платные версии
  • Требует выделенного сервера и базы данных: это операционные расходы на поддержку
  • Стоимость Developer Edition: зависит от объёма LOC, актуальные цены на sonarsource.com/plans-and-pricing

Сравнение SAST инструментов: trade-offs и ограничения​

КритерийSemgrepCodeQLSonarQube
АрхитектураПаттерн-матчинг + taint (Pro)Семантический граф (реляционная БД)Broad ruleset + taint (платные версии)
Время PR-сканированияСекунды20–45 минут5–30 минут
False positives (из коробки)Средний, быстро тюнитсяНизкийВысокий (по субъективным оценкам)
Кастомные правилаПростой синтаксис, минутыQL - высокий порог, дниXML/UI, средний порог
Diff-only сканированиеНативно, по умолчаниюIncremental (GitHub Actions)Branch analysis (платная версия)
Требует компиляцииНетДа (Java, Go, C/C++)Нет
Self-hostedДа (CLI)Да (CLI + GitHub)Да (сервер + БД)
IDE-интеграцияVS Code, IntelliJVS Code (через GHAS)SonarLint (VS Code, IntelliJ)
SCA (зависимости)Ограниченный (Supply Chain)НетЧерез плагины / платные версии
Когда использоватьPR-чеки, команды 5–50 человекГлубокий анализ, nightly, GitHub-nativeQuality + security, enterprise compliance
Когда НЕ использоватьНужен deep semantic analysisНужна скорость в PR, не GitHub, PHPБыстрая обратная связь, ограниченный бюджет

Настройка SAST правил в CI/CD без alert fatigue​

Требования к окружению​

  • Semgrep CLI: любая ОС с Python 3.8+, 2 ГБ RAM, доступ в интернет для загрузки правил (или offline с локальным реестром). Установка: pip install semgrep или Docker-образ returntocorp/semgrep
  • CodeQL CLI: Linux/macOS/Windows, 8 ГБ RAM (16 ГБ для крупных проектов), build tools для целевого языка. Установка: бинарь с GitHub или codeql-action в GitHub Actions
  • SonarQube Server: выделенный сервер 4 ГБ RAM минимум (8 ГБ рекомендуется), PostgreSQL, Java 17+. Для CI - sonar-scanner CLI

Diff-only сканирование и baseline​

Главная стратегия борьбы с alert fatigue - сканировать только изменённый код. Semgrep делает это из коробки: semgrep ci в контексте PR автоматически анализирует только diff. CodeQL в GitHub Actions поддерживает incremental analysis. SonarQube Community Edition не поддерживает branch analysis - каждый scan обрабатывает всю базу; branch analysis доступен начиная с Developer Edition.

Вторая стратегия - baseline. При первом внедрении SAST в проект с 200K+ строк сканер обнаружит сотни findings. Показывать их все разработчикам - прямой путь к тому, что на алерты перестанут смотреть через день. Создайте baseline и настройте pipeline на показ только новых findings:
YAML:
# GitLab CI - Semgrep с baseline и severity-фильтром
semgrep:
  image: returntocorp/semgrep
  variables:
    SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN  # требуется для --config=auto
  script:
    - semgrep ci --baseline-commit $CI_MERGE_REQUEST_DIFF_BASE_SHA
      --config=auto --config=.semgrep/custom-rules.yml
      --severity ERROR --json --output=results.json
  rules:
    - if: $CI_MERGE_REQUEST_ID
  # Без SEMGREP_APP_TOKEN замените --config=auto на --config=p/security-audit
  # $CI_MERGE_REQUEST_DIFF_BASE_SHA доступна только в merge_request pipeline

Снижение ложных срабатываний через severity и confidence​

На PR-чеках блокируйте мердж только при severity ERROR; WARNING пускайте в advisory-режиме. Кастомные правила под ваш стек с severity ERROR будут ломать pipeline при находке, а community-правила с WARNING - информировать без блокировки.

Пример кастомного правила Semgrep для детектирования небезопасного ГПСЧ (CWE-330, по классификации OWASP - A02:2021 Cryptographic Failures):
YAML:
rules:
  - id: insecure-random-security-context
    pattern-either:
      - pattern: random.random()
      - pattern: Math.random()
    message: "Небезопасный ГПСЧ в security-контексте"
    languages: [python, javascript]
    severity: ERROR
    metadata: { cwe: "CWE-330", owasp: "A02:2021" }
Для SonarQube аналогичная логика - через quality gate: настройте порог new_security_rating на A и отделите его от new_reliability_rating. Для CodeQL фильтрация происходит на уровне query suites: стандартный security-extended покрывает критичные классы уязвимостей с низким false positive rate; свои запросы выносите в отдельный suite с пометкой @severity error.

Какой SAST инструмент под какую задачу: decision tree​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

Такой стек детектирует инъекции (OWASP A03:2021), криптографические ошибки (A02:2021), проблемы целостности кода и зависимостей (A08:2021) и утечки credentials. Ни один из слоёв не дублирует другой и не создаёт шума.

Типичная причина жалоб на SAST - инструмент включён с дефолтами без тюнинга. Включить SonarQube с дефолтными правилами на кодовую базу в 300K строк и удивляться потоку алертов - это как включить IDS в promiscuous mode на магистральном канале и жаловаться на количество событий. Инструмент делает ровно то, что просили.

Но проблема глубже. По результатам одного из академических исследований (оценивавшего несколько инструментов на датасете реальных уязвимостей), SAST-инструменты детектировали малую долю от общего числа уязвимостей. Остальное - ручной ревью, DAST, пентест. Пока вендоры соревнуются в количестве поддерживаемых языков и AI-ассистентах для автофикса, фундаментальное ограничение никуда не делось: статический анализ видит код, а не поведение.

Мой подход за последние два года устоялся: Semgrep на каждый PR с 20–30 кастомными правилами под проект, CodeQL по ночам на main для глубокого анализа, SonarQube как dashboard для менеджмента и compliance. Три инструмента - три роли - ноль пересечений. Alert fatigue при такой расстановке исчезает не потому, что инструменты стали умнее, а потому, что каждый делает только свою работу. Кто не пробовал выстроить слоистый стек и всё ещё мучается с одним инструментом на все задачи - на форуме codeby.net есть тред с конфигами под конкретные стеки, там обсуждаем подобные схемы регулярно.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab