Неопубликованная запись
Статический анализ кода (SAST). Использование Semgrep в качестве анализатора
В эпоху цифровизации безопасность приложений стала неотъемлемой частью жизненного цикла разработки.
Статический анализ безопасности приложений (SAST - Static Application Security Testing) - это методика анализа исходного кода без его выполнения для выявления уязвимостей на этапах разработки и сборки кода.
Преимущества SAST:
- Раннее обнаружение уязвимостей — проблемы находятся и устраняются до финальной сборки цифрового продукта.
- Снижение стоимости исправлений — исправить баг на этапе разработки менее трудозатратно, чем заниматься устранением уязвимостей в уже работающем ПО в составе информационной системы.
- Постоянное улучшение качества кода — разработчики учатся создавать безопасный код, повышается культура написания кода, что в свою очередь повышает скорость выявления и устранения дефектов кода.
- Интеграция в CI/CD — настройка автоматической проверки кода в зависимости от потребностей проекта , тем самым, сокращая ресурсы на ручной анализ кода и повышая эффективность выявления дефектов.
Semgrep — это современный статический анализатор кода с открытым исходным кодом, который сочетает в себе простоту использования и возможность выявления сложных уязвимостей. Обеспечивает базовые потребности при анализе кода и позволяет расширять возможности по мере зрелости проекта.
Почему именно Semgrep?
- Простой синтаксис — правила выглядят как код, который вы ищете.
- Мультиязычность — поддерживает Java, JavaScript, Python, Go, C# и другие языки.
- Высокая производительность — сканирование больших проектов за секунды.
- Гибкость — возможность создавать кастомные правила под специфику проекта.
Интеграция Semgrep в процесс CI/CD на примере TeamCity
Использование docker
При наличии докера в агенте сборки TeamCity, самый простой вариант — это сканировать код с помощью Semgrep в контейнере. Например, создать шаг сборки «Command Line» и указать в нем запуск контейнера с Semgrep:
docker run --rm -v "путь/к/каталогу" returntocorp/semgrep semgrep \
--config=r/java.security \
--config=r/java.lang \
--config=p/java \
--config=auto \
--text ./src > SAST-report.txt
Команда docker run --rm -v "путь/к/каталогу" returntocorp/semgrep — поднимает контейнер из образа returntocorp/semgrep
"путь/к/каталогу" — путь к сканируемому каталогу. Обычно в проекте каталог /src содержит код приложения.
semgrep — команда на запуск сканирования.
--config — конфигурация сканирования (указывается правила сканирования). Для начала хватает правила --config=auto
--text ./src > SAST-report.txt — параметр для вывода отчета в текстовом человеко-читаемом формате, где ./src — каталог сохранения отчета. SAST-report.txt - имя отчета.
Использование Semgrep , установленного в агент сборки кода
При отсутствии докера, Semgrep устанавливается на агент сборки, далее необходимо создать шаг сборки «Command Line» и указать в нем команду запуска сканирования:
semgrep --config auto ./src --text ./ > SAST-report.txt
Где:
semgrep — команда запуска сканирования;
--config auto — правила сканирования;
./src — каталог сканирования;
--text ./ > SAST-report.txt — формат отчета, каталог сохранения отчета, имя отчета.
Разработка собственных правил для поиска специфичных уязвимостей
Semgrep использует синтаксис, похожий на код написания правил. Правила пишутся в формате YAML. Базовая структура выглядит так:

В правиле записывается уникальный id правила, шаблон поиска, описание проблемы, которое будет выведено в сообщение, при нахождении данной уязвимости. Также указывается язык программирования, уровень угрозы, код CWE и его категория.
Рассмотрим создание правил для некоторых уязвимостей из списка CWE.
CWE-382 — использование System.exit() в веб-приложениях
Проблема: вызов System.exit() в веб-приложении может привести к остановке всего сервера. Веб-приложению никогда не следует пытаться завершить работу контейнера приложения. Доступ к функции, способной завершить работу приложения — это путь к атакам типа «отказ в обслуживании» (DoS).

В данном правиле описываются шаблоны поиска в разделе patterns. Сам шаблон поиска описывается в ключе pattern (шаблонов может быть несколько). Pattern-inside — это оператор, который ограничивает поиск паттерна внутри определенного контекста (блока кода). Он говорит: «ищи этот паттерн, но только внутри указанного внешнего блока».
CWE-778 — недостаточное журналирование
Проблема: критические операции не логируются, что затрудняет обнаружение атак и расследование инцидентов.


В данном правиле добавлен паттерн pattern-not:, который исключает совпадения записанные в нем.
CWE-390 — обнаружение ошибочных условий без действий
Проблема: ошибки перехватываются, но не обрабатываются должным образом.

Использование кастомных правил при сканировании
Для применения кастомных правил, необходимо написать правило в yaml формате и сохранить это правило в определенном каталоге. При использовании специфичных правил для проекта, целесообразно будет держать правила рядом с кодом проекта, например, около каталога /src в каталоге semgrep-rules, либо любое другое удобное место. Путь к правилу указывается в параметре config. Пример запуска сканирования с кастомными правилами:
sudo docker run --rm -v "$(pwd):/src" returntocorp/semgrep \
semgrep --config=./semgrep-rules/ --config=auto --config=r/java.lang \
--text ./src > SAST-report.txt
Где $(pwd) - текущий каталог.
Принципы использования Semgrep
- Начинайте с малого: внедряйте правила постепенно.
- Образовательный подход: используйте находки для обучения команды.
- Регулярное обновление: обновляйте правила и сам Semgrep.
- Контекстная настройка: адаптируйте правила под специфику проекта, тем самым снижая ложно-положительные срабатывания.
- Интеграция в Code Review: добавляйте автоматический анализ кода в процесс проверки кода.
Заключение
SAST с использованием Semgrep — это не просто «галочка» в процессе разработки, а мощный инструмент для создания безопасного программного продукта. Создание собственных правил позволяет адаптировать анализатор кода под конкретные требования проекта и выявлять уязвимости, специфичные для вашей кодовой базы, снижая ложно-положительные срабатывания и повышая эффективность (скорость) реагирования на дефекты кода.
Выводы и рекомендации по использованию SAST и Semgrep в частности:
- SAST должен интегрироваться в процесс разработки, а не использоваться эпизодически – от случая к случаю.
- Semgrep делает статический анализ доступным для команд любого размера, не требует больших финансовых затрат, позволяет использовать несколько решений этого класса.
- Самостоятельно разработанные правила помогают адаптировать анализатор под специфику конкретного проекта, повышая эффективность обнаружения уязвимостей и сокращая время реагирования на них.
Начните с внедрения нескольких критически важных правил и постепенно расширяйте охват. Безопасность — это процесс, а не конечное состояние.
Источники:
- Официальная документация Semgrep
- Правила для CWE TOP 25
- Открытые правила написанные сообществом
Статья подготовлена для разработчиков, желающих улучшить безопасность своих приложений. Примеры правил могут быть адаптированы под конкретные языки программирования и фреймворки.
Сергей Филиппов, ведущий разработчик программного обеспечения