// Engineering Log

Безопасная разработка: Часть 3 — SAST: статический анализ кода

Опубликовано 22.09.2026

// Быстрый маршрут

Эта статья относится к теме Безопасность и защита.

Опытный разработчик находит уязвимости в чужом коде по знакомым признакам: данные пользователя попадают прямо в SQL-запрос, пароль сравнивается обычным ==, путь к файлу собирается из параметра запроса. Но просмотреть так сто тысяч строк и ничего не упустить человек не может. Эту работу берёт на себя SAST.

Что такое SAST

SAST (Static Application Security Testing, статический анализ безопасности) — проверка исходного кода без запуска приложения. Анализатор разбирает код в синтаксическое дерево и ищет в нём опасные конструкции.

Главный приём — анализ потока данных (taint analysis). Анализатор отмечает «источники» — места, откуда приходят недоверенные данные: параметры запроса, заголовки, тело формы. Затем он прослеживает, дойдут ли эти данные до «стока» — опасной функции вроде выполнения SQL, запуска команды оболочки или записи в HTML, — не пройдя по пути через очистку или экранирование. Если дойдут, появляется предупреждение.

Тесты такой работы не заменяют. Тест проверяет, что при вводе имени Ivan в базу записывается Ivan. SAST проверяет, что произойдёт, если вместо имени придёт ' OR 1=1 --, хотя функционально код работает правильно.

Пример: SQL-инъекция

python
@app.route("/user")
def get_user():
    user_id = request.args.get("id")
    # опасно: значение из запроса подставляется в текст запроса
    query = "SELECT * FROM users WHERE id = %s" % user_id
    db.execute(query)

Правило анализатора описывает ровно эту ситуацию: значение из request через форматирование строки попадает в execute(). Исправление — параметризованный запрос: db.execute("SELECT * FROM users WHERE id = %s", (user_id,)). Драйвер базы передаёт значение отдельно от текста запроса, и инъекция становится невозможной.

Инструменты

Semgrep

Semgrep — самый распространённый лёгкий анализатор. Правила пишутся в YAML почти на языке самого кода, поэтому своё правило для проекта можно составить за несколько минут.

Важно понимать, как устроена его лицензия. Движок Semgrep Community Edition распространяется под LGPL-2.1 и бесплатен. Но возможности у него ограничены: по документации Semgrep, открытая версия анализирует взаимодействия только внутри одной функции. Анализ между функциями и между файлами есть в платном продукте Semgrep Code. Правила, которые поддерживает сама компания, распространяются под собственной лицензией: их можно использовать для внутренних задач, но нельзя встраивать в конкурирующие продукты и сервисы.

Opengrep

Когда Semgrep перенёс часть возможностей под коммерческую лицензию, группа компаний создала форк Opengrep. Он распространяется под LGPL-2.1, совместим с правилами Semgrep и развивает анализ потока данных в открытом виде. Если вам важно, чтобы инструмент оставался полностью открытым, Opengrep — естественная замена.

SonarQube Community Build

SonarQube — платформа, которая совмещает поиск уязвимостей с проверкой качества кода: дублирование, сложность, покрытие тестами. Бесплатная редакция Community Build распространяется под LGPL-3.0 и ставится на свой сервер. Для небольшой команды это удобный вариант, если нужен общий отчёт по проекту, а не только сканер в CI.

CodeQL

CodeQL от GitHub описывает код как базу данных, к которой пишутся запросы. Это один из самых глубоких анализаторов. Для публичных репозиториев на GitHub сканирование кода включено бесплатно. Для закрытых репозиториев нужен платный продукт GitHub Code Security, и его доступность и оплату для российской компании нужно проверять отдельно.

Как запустить локально

Semgrep ставится через pip или Homebrew:

bash
pip install semgrep
semgrep scan --config p/python

p/python — готовый набор правил для Python из реестра Semgrep. Для JavaScript есть p/javascript, для общих проверок — p/default. Opengrep устанавливается скриптом из репозитория проекта и принимает те же правила.

SAST в CI

Проверку имеет смысл запускать на каждом запросе на слияние: уязвимость, найденная до слияния, обходится дешевле всего. Пример задания для GitHub Actions на официальном образе Semgrep:

yaml
name: sast
on: [pull_request]

jobs:
  semgrep:
    runs-on: ubuntu-latest
    container:
      image: semgrep/semgrep
    steps:
      - uses: actions/checkout@v4
      - run: semgrep scan --config p/python --error

Ключ --error завершает команду с ошибкой, если найдены проблемы, и CI не даёт влить код. Старая обёртка semgrep-action объявлена устаревшей, поэтому Semgrep запускается напрямую, как в примере. В GitLab CI то же самое делается заданием с тем же образом.

Чтобы не утонуть в старых находках, начните с режима, в котором проверяется только изменённый код, либо сначала соберите базовый отчёт и договоритесь, что новые предупреждения запрещены, а старые разбираются постепенно.

Ложные срабатывания

Ни один анализатор не точен до конца: иногда безопасный код помечается как опасный.

  • Настройка правил. Слишком строгое правило можно отключить или уточнить под проект.
  • Подавление на месте. Комментарий # nosemgrep над строкой отключает проверку для неё. Рядом стоит объяснить, почему код безопасен, иначе через полгода никто этого не вспомнит.
  • Разбор. В команде кто-то отвечает за отчёты и помечает находки как «исправить» или «ложное».

Если подавлений становится много, это сигнал пересмотреть набор правил, а не привыкать к шуму.

С чего начать

  1. Запустите Semgrep или Opengrep на своём проекте один раз и разберите находки уровня ERROR.
  2. Добавьте проверку в CI на запросах на слияние, сначала только для новых предупреждений.
  3. Напишите одно-два собственных правила для типичных ошибок вашего проекта: это самый быстрый способ получить пользу, которую не дадут общие наборы.

// Похожая задача

Если у вас похожая ситуация

Эта статья относится к одной из рабочих тем. Можно продолжить чтение по теме, перейти на главную, чтобы понять, чем я занимаюсь, или сразу открыть услуги.

Тема статьи

Безопасность и защита

SSL, hardening, доступы, защита сервисов и безопасные конфигурации.

Часто с этим приходят

  • Настроить SSL, сертификаты и безопасные подключения
  • Ограничить доступы и закрыть лишние точки входа
  • Усилить конфигурацию сервера и сервисов

// Следующий шаг

Если вам нужна не только статья, а помощь по этой теме, удобнее сразу перейти в услугу. Главная и подборка материалов остаются рядом.

Открыть услуги

// Contact

Нужна помощь?

Свяжись со мной и я помогу решить проблему

Написать в Telegram

Отвечаю в течение рабочего дня (03:00–13:00 GMT)

Или оставьте заявку здесь:

Подтвердите, что вы не бот.

Написать и получить быстрый ответ