Positive Technologies
Содержание
22.09.2026

sbom-helper: набор инструментов для помощи при работе со SBOM

Термины и определения

Введение

Думаю, многие не понаслышке знают, насколько непростой может оказаться задача получения SBOM, в полной мере соответствующих требованиям ФСТЭК России (требования к SBOM описаны в приложении 1 к Методике ВУ-НДВ).

Мы в Позитиве также не раз сталкивались с трудностями на этом пути. В процессе решения проблем постепенно накопился опыт, который привел к созданию веб-приложения, призванного автоматизировать и облегчать аспекты, связанные с обогащением и валидацией SBOM.

Цель текущей статьи - рассказать про основные возможности проекта и поделиться им с сообществом.

Назначение проекта

sbom-helper — это веб-приложение и API-сервис, который может помогать решать следующие задачи:

  • поиск ссылки на репозиторий исходного кода, соответствующий указанному PURL;
  • обогащение SBOM недостающими ссылками на репозитории исходного кода (добавление в массив externalReferences подходящей ссылки с "type": "vcs"), а также валидация уже имеющихся в SBOM ссылок такого типа;
  • преобразование SBOM в "перечень образов контейнеров в машиночитаемом формате" в соответствии с требованиями ФСТЭК России (см. Приложение 2 к Методике ВУ-НДВ).

SBOM-helper - приветственное окно

Примечание: список функций проекта будет расширяться, см. раздел Планы по развитию проекта.

Алгоритм работы

Ключевой функционал sbom-helper завязан на выполнении сопоставления PURL → ссылка на репозиторий. Эта задача на момент написания статьи не имеет простого и универсального решения.

Соответствующий алгоритм в sbom-helper работает следующим образом:

  1. Алгоритм принимает на вход PURL, проверяет его корректность (соответствует ли этот PURL спецификации).
  2. Если PURL корректный, то алгоритм последовательно опрашивает несколько источников:
    • локальная БД (кеш сопоставлений PURL → ссылка на репозиторий, уже накопленных при работе с проектом sbom-helper);
    • purl2repo (open-source проект, позволяющий производить сопоставление для относительно "простых" типов PURL);
    • API-запрос к сервису ecosyste.ms;
    • API-запрос к сервису libraries.io.
  3. Если в результате опроса источников была обнаружена ссылка, то алгоритм проверяет, является ли найденная ссылка VCS-репозиторием (используются проверки наличия репозиториев нескольких типов - git, svn, hg, fossil - по аналогии с тем, как устроена проверка в sbom-checker).
  4. Если проверка прошла успешно, то результаты сопоставления кешируются в локальной БД, а ссылка возвращается в качестве результата.

Типы PURL, поддерживаемые используемыми "резолверами"

PURL Type purl2repo ecosyste.ms libraries.io
bitbucket ✓
cargo ✓ ✓ ✓
composer ✓ ✓
conda ✓ ✓
cpan ✓ ✓
cran ✓ ✓
gem ✓ ✓
generic ✓ ✓
github ✓
golang ✓ ✓ ✓
hackage ✓ ✓
hex ✓ ✓
huggingface ✓
maven ✓ ✓ ✓
mlflow ✓
npm ✓ ✓ ✓
nuget ✓ ✓ ✓
pub ✓ ✓
pypi ✓ ✓ ✓
swift ✓ ✓

Примечание: поддержка определенного типа PURL не гарантирует 100-процентную вероятность нахождения подходящей ссылки для конкретного PURL, но предполагает, что для PURL указанного типа ссылка принципиально может найтись.

Используемые технологии

Бэкенд:

  • Язык: Python
  • Компоненты: FastAPI (API-фреймворк), Pydantic v2 (для валидации данных), purl2repo (первичный резолвер), httpx (для HTTP-запросов), asyncpg (для запросов к PostgreSQL), diskcache (кеш валидации URL), packageurl-python (парсинг PURL), Uvicorn (ASGI-сервер, поддержка HTTPS), компоненты для VCS-проверок - Git, Subversion, Mercurial

Фронтенд:

  • Язык: TypeScript
  • Компоненты: Vue 3 + Vite (фронтенд-фреймворк и инструмент для сборки фронтенда), vue-i18n (en/ru), pinia (состояние)

Базовые образы:

  • Python:3.12-slim (основной компонент sbom-helper)
  • postgres:16-alpine (СУБД)
  • node:20-alpine (для сборки фронтенда)

Разработка:

  • IDE: VS Code + Kilo Code.
  • ИИ-модель: DeepSeek V4 Flash (чаще всего).
  • Скиллы (перечислены основные скиллы, набор меняется в процессе разработки):
  • Тестирование: pytest (бэкенд), vitest + @vue/test-utils (фронтенд).

Подготовка к работе

Программные требования:

  • git
  • docker + docker compose

Порядок установки:

bash
git clone https://github.com/mArTi3-github/sbom-helper.git
cd sbom-helper
docker compose up -d

После установки веб-интерфейс проекта будет доступен по адресу https://<ip-адрес>:8443.

Просмотр логов работы (диагностика)

bash
# Перед выполнением команды - перейти в папку проекта
docker compose logs --follow
# Выход из режима просмотра логов: CTRL-C

Обновление

bash
# Перед выполнением команды - перейти в папку проекта
./scripts/update.sh # можно использовать опцию `-v` для отображения более подробных логов

Разделы веб-интерфейса

Раздел "Настройки"

Раздел "Настройки"

Для повышения вероятности нахождения ссылок для компонентов рекомендуется перед началом работы добавить к проекту API-ключи публичных сервисов для поиска ссылок по PURL (это бесплатно):

Параметр Рекомендуемое значение Описание
Включить libraries.io резолвер + API ключ Включено + актуальный токен Позволяет выполнять поиск по открытой базе libraries.io. Увеличивает лимиты с 10 запросов/мин до 60 запросов/мин. Для получения токена нужен аккаунт на сайте libraries.io (можно логиниться через GitHub). Ссылка для получения токена
Включить ecosyste.ms резолвер + API ключ Включено + актуальный токен Позволяет выполнять поиск по открытой базе ecosyste.ms. Увеличивает лимиты (лимиты динамические, точные коэффициенты неизвестны). Для получения токена нужен аккаунт на сайте ecosyste.ms (можно логиниться через GitHub). Ссылка для получения токена

Прочие параметры можно настраивать в соответствии с потребностями и особенностями инфраструктуры (описание настроек представлено в веб-интерфейсе раздела). Настройки сохраняются на сервере в файле data/settings.json.

Также в настройках можно выбрать язык (русский/английский) и тему интерфейса (светлая/темная):

Браузерные настройки

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

Раздел "Найти ссылку для PURL"

Принимает PURL, возвращает ссылку на соответствующий репозиторий исходных текстов.

Раздел "Найти ссылку для PURL"

Примечание: возвращаются ссылки на репозиторий проекта в целом, а не на какую-то конкретную версию проекта.

Раздел "Обогатить SBOM"

Принимает на вход SBOM, возвращает SBOM с актуальными ссылками на репозитории исходного кода для всех элементов списка "components" (на всех уровнях вложенности).

Раздел "Обогатить SBOM"

Для уточнения механизма работы доступно 2 настройки:

  • Игнорировать компоненты с перечисленными признаками - указание списка признаков компонентов, для которых не требуется выполнять поиск/проверку ссылок (в примере на скриншоте выше исключаются компоненты, включающие подстроку "ptsecurity" в значении полей "purl" или "group", либо подстроку "ptsb" в значении поля "name"). Это позволяет не проводить поиск ссылок для компонентов, для которых заведомо известно, что для них не существует общедоступных ссылок (например, проприетарные компоненты).
  • Удалять компоненты без подкомпонентов, для которых не найдена ссылка - включение/выключение функции автоматического удаления "листьев" списка components, для которых в результате обработки не удалось найти ссылку на исходные тексты. Может применяться в случаях, когда в SBOM по ошибке попали служебные компоненты, не входящие в дистрибутив продукта (в случае "Позитива" эта опция пригождалась для удаления сборочных компонентов, не попадающих в итоговый дистрибутив, но по ошибке упоминаемых в SBOM). Внимание: требуется использовать с осторожностью, чтобы случайно не удалить те компоненты, которые действительно входят в состав продукта.

Дополнительно в разделе "Настройки" можно настроить переключатель "Валидация существующих URL из SBOM", указав, требуется ли проверять корректность ссылок, уже присутствующих в SBOM, переданном для обогащения.

Т.к. процесс поиска необходимых ссылок может занимать продолжительное время, обработка каждого поданного на вход SBOM реализуется в виде отдельной задачи. Список задач и их статусы отображаются в нижней части раздела. Каждую задачу, находящуюся в процессе выполнения, при необходимости можно остановить (чтобы освободить ресурсы в случае, если обогащение более не актуально).

Раздел "Обогатить SBOM - недавние задачи"

Длительность хранения результатов на сервере устанавливается в разделе настроек (по умолчанию - 24 часа).

Статистику по каждой выполненной задаче (количество найденных/не найденных ссылок) можно посмотреть, кликнув по выполненной задаче. Над таблицей со статистикой располагается кнопка "Скачать обогащенный SBOM", позволяющая получить результаты.

Примечание: На момент написания статьи в проекте есть небольшой баг фронтенда, из-за которого иногда некорректно работает скачивание обработанного SBOM. При возникновении такой ситуации достаточно обновить страницу, после этого кнопка скачивания начинает работать правильно. Пока не удалось установить точные причины возникновения проблемы, но рано или поздно отловлю и исправлю.

Раздел "Генерировать список образов"

Принимает на вход SBOM, возвращает перечень образов контейнеров в машиночитаемом формате в соответствии с требованиями ФСТЭК России (см. Приложение 2 к Методике ВУ-НДВ).

Алгоритм ищет в списке components (на всех уровнях вложенности) компоненты, у которых для поля type указано значение container, и формирует из этих компонентов новый список components. Также при формировании списка предусмотрена дедупликация отобранных компонентов по полю purl, чтобы в формируемый список попадали только уникальные образы.

Раздел "Генерировать список образов"

Дополнительно для генерируемого списка образов проверяется выполнение требований ФСТЭК России к полям объектов, описывающим образы контейнеров (см. Методику ВУ-НДВ, приложение 2, табл. П.13), а именно:

  • заполнено ли поле "name";
  • заполнено ли поле "version";
  • заполнено ли поле "properties";
  • заполнен ли список "components".

Раздел "Управлять БД"

Раздел для ручного управления содержимым базы данных сопоставлений PURL -> ссылка на репозиторий.

Раздел "Управлять БД"

Раздел позволяет:

  • искать/фильтровать записи в локальной БД;
  • редактировать значения PURL и Repository URL для имеющихся записей;
  • удалять лишние строки;
  • экспортировать выбранные строки таблицы в формате CSV;
  • импортировать данные в локальную БД в формате CSV (описание формата приведено в интерфейсе загрузки CSV).

API

Интерактивное описание API sbom-helper представлено по пути /docs в веб-интерфейсе (спецификация в формате OpenAPI генерируется и актуализируется автоматически средствами фреймворка FastAPI при старте приложения).

Спецификация в исходном виде в формате JSON доступна по пути /openapi.json.

Технические компромиссы

В sbom-helper на текущем этапе развития не предусмотрены механизмы аутентификации пользователей и разграничения доступа. Подразумевается, что защита обрабатываемых данных обеспечивается на уровне инфраструктуры. Проект - для внутреннего использования, не выставляйте его доступным в интернет или куда-либо еще, где к нему будет доступ у потенциального злоумышленника (понимаю, что, скорее всего, аудитории РБПО.РФ такие уточнения не требуются, проговариваю просто на всякий случай).

Планы по развитию проекта

Ниже перечислены функции/идеи, реализация которых планируется в будущем. Т.к. проект разрабатывается мной в одиночку в свободное от работы время, коммититься в конкретные сроки не получается, но рано или поздно бо́льшая часть планов, надеюсь, реализуются.

Новые возможности:

  • Обертки для инструментов sbom-checker — добавление обертки в веб-интерфейсе для консольных инструментов из комплекта sbom-checker от ИСП РАН;
  • Проверка корректности заполнения ГОСТ-полей - выявление несогласованности значений полей GOST:attack_surface и GOST:security_function между компонентами-"родителями" и их компонентами-"детьми"; дополнительно — добавление функции помощи по исправлению обнаруженных недостатков;
  • Дополнительные резолверы для различных типов PURL - расширение покрытия различных типов пакетов, ссылки для которых на момент написания статьи находятся недостаточно эффективно (например, добавление механизмов поиска для пакетов типа deb или apk, а также LLM-резолвера с поиском в интернете);
  • Добавление прямых ссылок на скачивание исходных текстов, когда нет репозитория — добавление прямой ссылки на скачивание с "type": "source-distribution" для случаев, когда нет ссылки на репозиторий, но есть ссылка на скачивание архива с исходными текстами.

Мелкие правки:

  • Добавление функции обработки списка PURL в UI — добавление возможности вставлять несколько PURL (по одному в строке) в поле ввода раздела "Найти ссылку для PURL" с возвратом таблицы с результатами по каждому запрошенному PURL;
  • Динамический UI при обогащении SBOM — отправка отчета о статистике обработки ссылок в процессе обработки и динамическое обновление информации в UI;
  • Ручное добавление записей в БД — добавление записей в БД вручную через веб-интерфейс вкладки "Управлять БД";
  • Импорт ссылок из SBOM — добавление к разделу "Управлять БД" функции "Импорт из SBOM" для импорта сопоставлений PURL -> repository_url из SBOM в локальную БД (по аналогии с функцией "Импорт из CSV");
  • Хранение списка альтернативных ссылок для PURL — хранение списка альтернативных ссылок для PURL на случай, если основная ссылка перестанет работать;
  • Кеш неудачных валидаций/резолвов — добавление настраиваемого механизма кеширования неудачных запросов резолва и/или валидации ссылок, чтобы при обработке SBOM одни и те же PURL/URL не проходили длительный процесс валидации, если на основе предыдущих запросов можно предположить, что процесс завершится неуспешно;
  • Улучшение логирования — приведение отладочной информации к единообразному, понятному и достаточному формату;
  • Информация о версии — отображение в веб-интерфейсе информации о том, какая версия проекта развернута.

Заключение

Надеюсь, кому-то sbom-helper сможет помочь в нелегком деле наведения порядка в SBOM-ах (если и правда поможет - буду рад звездочкам на GitHub).

Если вы заметили какой-то недостаток или вам нужна функция, которая не перечислена в разделе Планы по развитию проекта, можно создавать issue на странице проекта на GitHub или предлагать pull request’ы. В случае бага - чем более точно и подробно будет описан недостаток и условия его возникновения, тем выше вероятность, что он будет оперативно исправлен.

На нашем сайте мы используем cookie файлы, содержащие информацию о предыдущих посещениях веб-сайта. Данные обрабатываются для улучшения качества работы нашего веб-сайта. Если вы не хотите использовать cookie файлы, измените настройки браузера.