Назад к списку

Статический анализ кода (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

  1. Начинайте с малого: внедряйте правила постепенно.
  2. Образовательный подход: используйте находки для обучения команды.
  3. Регулярное обновление: обновляйте правила и сам Semgrep.
  4. Контекстная настройка: адаптируйте правила под специфику проекта, тем самым снижая ложно-положительные срабатывания.
  5. Интеграция в Code Review: добавляйте автоматический анализ кода в процесс проверки кода.

Заключение

SAST с использованием Semgrep — это не просто «галочка» в процессе разработки, а мощный инструмент для создания безопасного программного продукта. Создание собственных правил позволяет адаптировать анализатор кода под конкретные требования проекта и выявлять уязвимости, специфичные для вашей кодовой базы, снижая ложно-положительные срабатывания и повышая эффективность (скорость) реагирования на дефекты кода.
Выводы и рекомендации по использованию SAST и Semgrep в частности:
  • SAST должен интегрироваться в процесс разработки, а не использоваться эпизодически – от случая к случаю.
  • Semgrep делает статический анализ доступным для команд любого размера, не требует больших финансовых затрат, позволяет использовать несколько решений этого класса.
  • Самостоятельно разработанные правила помогают адаптировать анализатор под специфику конкретного проекта, повышая эффективность обнаружения уязвимостей и сокращая время реагирования на них.
Начните с внедрения нескольких критически важных правил и постепенно расширяйте охват. Безопасность — это процесс, а не конечное состояние.
Источники:

  1. Официальная документация Semgrep
  2. Правила для CWE TOP 25
  3. Открытые правила написанные сообществом

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