МГТУ им. Н.Э. Баумана
Содержание
09.09.2026

Сведения о заимствованных компонентах. Экскурс по созданию ППК (SBOM) в контексте подготовки заявки на сертификацию по требованиям ФСТЭК России

Проблематика

Одной из ключевых задач при подготовке заявки является формирование корректного файла с перечнем программных компонентов (ППК), он же Software Bill of Materials (SBOM). При кажущейся простоте на поверку эта задача на самом деле довольно нетривиальна, так как требует строгого соблюдения требований и рекомендаций ФСТЭК России. В данной статье рассмотрены основные принципы создания валидных SBOM-файлов.

1. Что такое SBOM

SBOM (Software Bill of Materials) — в общем случае это перечень программных компонентов, из которых состоит описываемый им продукт. В мире существует множество форматов для описания ППК, наиболее распространённые из них: CycloneDX и SPDX.

В рамках подготовки заявки на сертификацию по требованиям ФСТЭК России может потребоваться сформировать два ППК:

  • Перечень заимствованных программных компонентов с открытым исходным кодом — ППК, который инвентаризирует все заимствованные программные компоненты с открытым исходным, используемые в составе программного обеспечения. Этот перечень является обязательным для предоставления вместе с заявкой, даже если в составе продукта нет ни одного заимствованного программного компонента с открытым исходным кодом.
  • Перечень образов контейнеров — ППК, который инвентаризирует все образы контейнеров и все программные компоненты, входящие в состав этих образов. Данный перечень является обязательным только, если программный продукт является программным обеспечением в контейнерном исполнении, т.е. содержит в поставке хотя бы один образ контейнера, подлежащего выполнению в среде контейнеризации.

2. Поля SBOM файла

ППК представляет собой JSON-файл, соответствующий требованиям формата CycloneDX 1.6 с некоторыми уточнениями, которые зависят от вида ППК.

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

Таблица 1. Требования к полям корневого объекта перечня заимствованных программных компонентов с открытым исходным кодом в машиночитаемом формате

Имя поляТипОписаниеТребования к наличию
bomFormatJSON строкаСпецификация формата документа. Должно содержать значение «CycloneDX».Обязательно
specVersionJSON строкаВерсия спецификации документа. Должно содержать значение «1.6».Обязательно
serialNumberJSON строкаУникальный серийный номер документа, сгенерированный Разработчиком в соответствии с RFC-4122. Например, «urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79».Опционально
versionЦелое числоВерсия документа. Первоначальное значение — 1. При модификациях должна увеличиваться на 1.Обязательно
metadataJSON объектДополнительная информация о перечне и продукте. Требования к заполнению полей объекта описаны в таблице 2.Обязательно
componentsМассив объектов JSONСписок заимствованных программных компонентов с открытым исходным кодом. Если в продукте используется несколько версий одного и того же компонента, то для каждой версии компонента должна быть отдельная запись. Не допускается объединять в одну запись компоненты, исходный текст которых хранится в нескольких различных репозиториях систем управления версиями. Требования к заполнению полей объектов описаны в таблице 5.Обязательно при наличии в составе ПО заимствованных компонентов

Таблица 2. Требования к полям объекта, описывающего дополнительную информацию о перечне и продукте

Имя поляТипОписаниеТребования к наличию
timestampJSON строкаДата и время формирования перечня в формате ГОСТ Р 7.0.64-2018 (ИСО 8601:2004). Например, «2022-04-25T09:30:00».Обязательно
componentJSON объектИнформация о продукте. Требования к заполнению полей объекта описаны в таблице 3.Обязательно

Таблица 3. Требования к полям объекта, описывающего информацию о продукте

Имя поляТипОписаниеТребования к наличию
typeJSON строкаОписывает тип заимствованного компонента. Допускается использовать следующие значения: application, framework, library, container, platform, operating-system, device, device-driver, firmware, file, machine-learning-model, data, cryptographic-asset. Данное поле является обязательным для совместимости со спецификацией CycloneDX, выбор типа компонента осуществляется по усмотрению разработчика.Обязательно
nameJSON строкаНазвание продукта.Обязательно
versionJSON строкаВерсия продукта. Длина строки не должна превышать 1024 символа.Обязательно
manufacturerJSON объектИнформация об изготовителе продукта. Требования к заполнению полей объекта описаны в таблице 4.Обязательно

Таблица 4. Требования к полям объекта, описывающего информацию об изготовителе продукта

Имя поляТипОписаниеТребования к наличию
nameJSON строкаНазвание организации – изготовителя продукта.Обязательно

Таблица 5. Требования к полям объекта, описывающего заимствованный программный компонент с открытым исходным кодом

Имя поляТипОписаниеТребования к наличию
typeJSON строкаОписывает тип заимствованного компонента. Допускается использовать следующие значения: application, framework, library, container, platform, operating-system, device, device-driver, firmware, file, machine-learning-model, data, cryptographic-asset. Данное поле является обязательным для совместимости со спецификацией CycloneDX, выбор типа компонента осуществляется по усмотрению разработчика.Обязательно
nameJSON строкаНаименование компонента.Обязательно
versionJSON строкаВерсия компонента.Обязательно
purlJSON строкаОпциональный идентификатор компонента в формате Package URL.Опционально
externalReferencesМассив объектов JSONМассив объектов, описывающих источник, из которого осуществляется загрузка компонентов, исходных кодов компонента в собственный репозиторий изготовителя, а также другие внешние по отношению к документу ресурсы: документация, сайты и т.п. Требования к заполнению полей объектов описаны в таблице 6. Среди элементов массива обязательно должен присутствовать хотя бы один объект с типом vcs или source-distribution.Обязательно
propertiesМассив объектов JSONМассив объектов, описывающих свойства компонента. Требования к заполнению полей объектов описаны в таблице 8. Среди элементов массива обязательно должны присутствовать объекты со свойствами GOST:attack_surface и GOST:security_function.Обязательно
componentsМассив объектов JSONСписок подкомпонентов данного компонента. Допускается получение информации как в массиве components родительского компонента, так и в массиве components корневого объекта перечня. Требования к заполнению полей объектов описаны в таблице 5.Опционально

Таблица 6. Требования к полям объекта, описывающего источники получения и внешние ссылки заимствованного компонента с открытым исходным кодом

Имя поляТипОписаниеТребования к наличию
typeJSON строкаОписывает тип внешнего ресурса.Обязательно
urlJSON строкаЕсли поле type имеет значение vcs, то в поле url помещается унифицированный указатель ресурса (URL) для репозитория с исходными текстами компонента, из которого осуществлялось копирование исходных кодов (например выполнение команды git clone) в собственный репозиторий изготовителя.

Если поле type имеет значение source-distribution, то в поле url помещается унифицированный указатель ресурса (URL) для архива с исходным кодом компонента, который был использован для копирования исходных кодов компонента в собственный репозиторий изготовителя.
Обязательно
hashesМассив объектов JSONСодержит список хэш-архива с исходным кодом компонента, полученных при помощи различных алгоритмов. Требования к заполнению полей объекта описаны в таблице 7.

Если поле type имеет значение source-distribution, то данное поле является обязательным и среди его элементов обязательно должен присутствовать объект с идентификатором алгоритма STREEBOG-256 или STREEBOG-512.
Опционально

Таблица 7. Требования к полям объекта, описывающего источники получения и внешние ссылки заимствованного компонента с открытым исходным кодом

Имя поляТипОписаниеТребования к наличию
algJSON строкаСодержит идентификатор алгоритма, которым был вычислен хэш архива с исходным кодом компонента или другого ресурса.Обязательно
contentJSON строкаСодержит значение хэш-функции для архива с исходным кодом компонента. Если alg имеет значение STREEBOG-256 или STREEBOG-512, то поле content должно содержать хэш-сумму архива с исходным кодом компонента, посчитанный по алгоритму ГОСТ Р 34.11 – 2012, с длиной хэш-кода 256 и 512 бит соответственно.Обязательно

Таблица 8. Требования к полям объекта, описывающего источник информации об уязвимости

Имя поляТипОписаниеТребования к наличию
nameJSON строкаНазвание свойства компонента.Обязательно
valueJSON строкаЗначение свойства компонента.

Если поле name имеет значение GOST:attack_surface, то поле value должно содержать одно из трёх значений:

yes — в случае, если подпрограммы (функции) компонента реализуют программный интерфейс, который непосредственно доступен потенциальному нарушителю или входные данные которого потенциальный нарушитель способен гарантированно сформировать определенным образом.

indirect — в случае, если подпрограммы (функции) компонента реализуют программный интерфейс, на входные данные которого потенциальный нарушитель способен целенаправленно повлиять, но это влияние существенно ограничено теми или иными факторами.

no — в противном случае.

Если поле name имеет значение GOST:security_function, то поле value должно содержать одно из трёх значений:

yes — если функции компонента непосредственно реализуют функции безопасности средства защиты информации (например, принимают решение по возможности доступа субъекта к объекту; принимают решение о принадлежности анализируемого объекта к классу (например, вредоносного ПО, вредоносного трафика); формируют и осуществляют запись сведений о событиях в журнале; управляют функциями безопасности ядра ОС и процессора, предоставляющим возможности виртуализации и т. п.).

indirect — если функции компонента участвуют в реализации функций безопасности средства защиты информации, взаимодействуя с компонентами, реализующими функции безопасности средства защиты информации (например, осуществление различных вида обработок подготовки данных, выделение структур данных из массива байт, выполнение вычислений над значениями аргументов функций и т. п.), но при этом не принимают непосредственных решений о запуске, останове, изменении режимов и параметров работы компонентов, реализующих функции безопасности.

no — если функции компонента не участвуют в реализации функций безопасности средства защиты информации.
Обязательно

Перечень образов контейнеров должен соответствовать следующим требованиям.

Таблица 9. Требования к полям корневого объекта перечня образов контейнеров в машиночитаемом формате

Имя поляТипОписаниеТребования к наличию
bomFormatJSON строкаСпецификация формата документа. Должно содержать значение «CycloneDX».Обязательно
specVersionJSON строкаВерсия спецификации документа. Должно содержать значение «1.6».Обязательно
serialNumberJSON строкаУникальный серийный номер документа, сгенерированный Разработчиком в соответствии с RFC-4122. Например, «urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79».Опционально
versionЦелое числоВерсия документа. Первоначальное значение — 1. При модификациях должна увеличиваться на 1.Обязательно
metadataJSON объектДополнительная информация о перечне и продукте. Требования к заполнению полей объекта описаны в таблице 10.Обязательно
componentsМассив объектов JSONСписок образов контейнеров, входящих в состав средства. Требования к заполнению полей объектов описаны в таблице 13.Обязательно

Таблица 10. Требования к полям объекта, описывающего дополнительную информацию о перечне и продукте

Имя поляТипОписаниеТребования к наличию
timestampJSON строкаДата и время формирования перечня в формате ГОСТ Р 7.0.64-2018 (ИСО 8601:2004). Например, «2022-04-25T09:30:00».Обязательно
componentJSON объектИнформация о продукте. Требования к заполнению полей объекта описаны в таблице 11.Обязательно

Таблица 11. Требования к полям объекта, описывающего информацию о продукте

Имя поляТипОписаниеТребования к наличию
typeJSON строкаОписывает тип продукта. Допускается использовать следующие значения: application, framework, library, operating-system, device-driver, firmware. Данное поле является обязательным для совместимости со спецификацией CycloneDX, выбор типа компонента осуществляется по усмотрению разработчика.Обязательно
nameJSON строкаНазвание продукта.Обязательно
versionJSON строкаВерсия продукта. Длина строки не должна превышать 1024 символа.Обязательно
manufacturerJSON объектИнформация об изготовителе продукта. Требования к заполнению полей объекта описаны в таблице 12.Обязательно

Таблица 12. Требования к полям объекта, описывающего информацию об изготовителе продукта

Имя поляТипОписаниеТребования к наличию
nameJSON строкаНазвание организации – изготовителя продукта.Обязательно

Таблица 13. Требования к полям объекта, описывающего образ контейнера

Имя поляТипОписаниеТребования к наличию
typeJSON строкаОписывает тип компонента. Должно содержать значение "container".Обязательно
nameJSON строкаНаименование образа контейнера.Обязательно
versionJSON строкаВерсия компонента.Обязательно
purlJSON строкаОпциональный идентификатор компонента в формате Package URL.Опционально
propertiesМассив объектов JSONМассив объектов, описывающих свойства компонента. Требования к заполнению полей объектов описаны в таблице 14. Среди элементов массива обязательно должны присутствовать объекты со свойствами GOST:attack_surface и GOST:security_function.Обязательно
componentsМассив объектов JSONСписок программного обеспечения, входящего в состав образа контейнера. Требования к заполнению полей объектов описаны в таблице 15.Обязательно

Таблица 14. Требования к полям объекта, описывающего свойства компонентов

Имя поляТипОписаниеТребования к наличию
nameJSON строкаНазвание свойства компонента.Обязательно
valueJSON строкаЗначение свойства компонента.

Если поле name имеет значение GOST:attack_surface, то поле value должно содержать одно из трёх значений:

yes — в случае, если подпрограммы (функции) компонента реализуют программный интерфейс, который непосредственно доступен потенциальному нарушителю или входные данные которого потенциальный нарушитель способен гарантированно сформировать определенным образом.

indirect — в случае, если подпрограммы (функции) компонента реализуют программный интерфейс, на входные данные которого потенциальный нарушитель способен целенаправленно повлиять, но это влияние существенно ограничено теми или иными факторами.

no — в противном случае.

Если поле name имеет значение GOST:security_function, то поле value должно содержать одно из трёх значений:

yes — если функции компонента непосредственно реализуют функции безопасности средства защиты информации (например принимают решение по возможности доступа субъекта к объекту; принимают решение о принадлежности анализируемого объекта к классу (например вредоносного ПО, вредоносного трафика); формируют и осуществляют запись сведений о событиях в журнал; управляют функционалом безопасности ядра ОС и процессора, предоставляющим возможности виртуализации и т. п.).

indirect — если функции компонента участвуют в реализации функций безопасности средства защиты информации, взаимодействуя с компонентами, реализующими функции безопасности средства защиты информации (например, осуществляя различные виды обработки/подготовки данных, выделение структур данных из массива байт, выполнение вычислений над значениями аргументов функции и т. п.), но при этом не принимают непосредственных решений о запуске, остановке, изменении режимов и параметров работы компонентов, реализующих функции безопасности.

no — если функции компонента не участвуют в реализации функций безопасности средства защиты информации.

Если поле name имеет значение GOST:provided_by, то поле value должно содержать название сертифицированного средства защиты информации, из состава которого заимствован данный компонент, при условии, что изготовитель указанного средства обеспечивает поддержку безопасности этого компонента.
Обязательно

Таблица 15. Требования к полям объекта, описывающего программное обеспечение, входящее в состав образа контейнера

Имя поляТипОписаниеТребования к наличию
typeJSON строкаОписывает тип компонента. Допускается использовать следующие значения: application, framework, library, container, platform, operating-system, device, device-driver, firmware, file, machine-learning-model, data, cryptographic-asset. Данное поле является обязательным для совместимости со спецификацией CycloneDX, выбор типа компонента осуществляется по усмотрению разработчика.Обязательно
nameJSON строкаНаименование компонента.Обязательно
versionJSON строкаВерсия компонента.Обязательно
purlJSON строкаОпциональный идентификатор компонента в формате Package URL.Опционально
propertiesМассив объектов JSONМассив объектов, описывающих свойства компонента. Требования к заполнению полей объектов описаны в таблице 14. Среди элементов массива обязательно должны присутствовать объекты со свойствами GOST:attack_surface и GOST:security_function.Обязательно
componentsМассив объектов JSONСписок подкомпонентов данного компонента. Допускается перечислять подкомпоненты как в массиве components родительского компонента, так и в массиве components корневого объекта перечня. Требования к заполнению полей объектов описаны в таблице 15.Опционально

3. Создание SBOM файла

Для автоматизации процесса рекомендуется использовать следующие инструменты:

  • для инвентаризации образов контейнеров: trivy;
  • для инвентаризации компонентов ПО: cdxgen.

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

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

  1. Наличие стандартных манифестов: Проект использует стандартные пакетные менеджеры (npm, maven, pip, go mod и др.) и файлы манифестов доступны для парсинга.
  2. Отсутствие сложной обфускации: Исходный код и бинарные файлы не подвергались глубокой модификации или упаковке.
  3. Использование штатных репозиториев: Зависимости загружаются из публичных или доверенных репозиториев, имеющих стандартную метаинформацию.

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

Типовым сценарием, в котором данный стек инструментов решает задачу в полной мере, является CI/CD пайплайн микросервисной архитектуры.

Пример: Веб-сервис на базе Node.js, упакованный в Docker-образ на основе Alpine Linux.

  1. Утилита cdxgen на этапе сборки анализирует package.json и package-lock.json, формируя точный список прикладных библиотек.
  2. Утилита Trivy после сборки образа сканирует слои Alpine Linux, выявляя системные пакеты. Результатом является исчерпывающий SBOM-файл, содержащий только верифицируемые компоненты, готовый к импорту в системы управления уязвимостями (например, Dependency-Track) и соответствующий требованиям регулятора.

Пример SBOM-файла для контейнеров

{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {
"timestamp": "2024-11-25T00:00:00Z",
"component": {
"type": "application",
"name": "Самый лучший межсетевой экран",
"version": "72.15",
"manufacturer": {
"name": "ООО Ромашка"
}
}
},
"components": [
{
"type": "container",
"name": "manager",
"version": "3.0.0",
"properties": [
{ "name": "GOST:attack_surface", "value": "no" },
{ "name": "GOST:security_function", "value": "yes" }
],
"components": [
{
"type": "library",
"name": "romashka_manager",
"version": "0.07",
"properties": [
{ "name": "GOST:attack_surface", "value": "no" },
{ "name": "GOST:security_function", "value": "yes" }
]
},
{
"type": "library",
"name": "postgres",
"version": "16.4",
"properties": [
{ "name": "GOST:attack_surface", "value": "no" },
{ "name": "GOST:security_function", "value": "no" }
]
}
]
},
{
"type": "container",
"name": "gateway",
"version": "2.31.0",
"properties": [
{ "name": "GOST:attack_surface", "value": "yes" },
{ "name": "GOST:security_function", "value": "yes" }
],
"components": [
{
"type": "application",
"name": "romashka_gateway",
"version": "0.07",
"properties": [
{ "name": "GOST:attack_surface", "value": "no" },
{ "name": "GOST:security_function", "value": "yes" }
]
},
{
"type": "application",
"name": "nginx",
"version": "1.24.4",
"properties": [
{ "name": "GOST:attack_surface", "value": "yes" },
{ "name": "GOST:security_function", "value": "no" },
{ "name": "GOST:provided_by", "value": "CertifiedDistribution" }
]
}
]
}
]
}

В SBOM-файле, созданном для инвентаризации образов контейнеров, поле externalReferences указывать не требуется. Данное поле используется исключительно в SBOM-файле, который описывает компоненты целевого программного обеспечения.

Пример SBOM-файла для ПО

{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {
"timestamp": "2024-04-25T00:00:00",
"component": {
"type": "application",
"name": "Самый лучший межсетевой экран",
"version": "72.15",
"manufacturer": {
"name": "ООО Ромашка"
}
}
},
"components": [
{
"type": "library",
"name": "openssl",
"version": "3.0.0",
"externalReferences": [
{ "type": "vcs", "url": "https://github.com/openssl/openssl/commit/89cd17a" }
],
"properties": [
{ "name": "GOST:attack_surface", "value": "yes" },
{ "name": "GOST:security_function", "value": "yes" }
]
},
{
"type": "library",
"name": "requests",
"version": "2.31.0",
"externalReferences": [
{ "type": "vcs", "url": "https://github.com/psf/requests/v2.32.3" }
],
"properties": [
{ "name": "GOST:attack_surface", "value": "yes" },
{ "name": "GOST:security_function", "value": "indirect" }
]
}
]
}

Важно отметить, что при составлении SBOM для программного обеспечения, входящего в состав сертифицированной операционной системы, поле externalReferences заполнять не требуется. Для таких пакетов достаточно в разделе properties добавить информацию о базовой ОС, указав свойство: "name":"GOST:provided_by", "value": "OS_NAME".

В поле externalReferences обязательно должен присутствовать хотя бы один объект с типом vcs или source-distribution. При source-distribution ссылка в поле url должна вести непосредственно на архив с исходным кодом для скачивания.

Для приведения изначально сгенерированных SBOM-файлов в соответствие c требованиями ФСТЭК России рекомендуется использовать специализированные скрипты.

Для проверки полученного SBOM файла рекомендуется использовать скрипт sbom-checker.py с ключами: -e (максимальное число ошибок для вывода, по умолчанию – 10), --check-vcs (проверка url на git/svn/hg/fossil-репозиторий для типа vcs в поле externalReferences; требуется доступ к интернету и наличие пакетов git, subversion и mercurial), --check-source-distribution (проверка url типа source-distribution). Ошибки типа ERROR обязательны к исправлению. Большинство ошибок типа WARNING являются обязательными к исправлению, но при проверке ссылок могут быть ложные срабатывания.

Если контейнер не является средой функционирования, то SBOM необходимо составлять только для целевого программного обеспечения.

Заключение

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

  1. Выбор стандарта: Строгое соблюдение спецификации CycloneDX версии 1.6 является обязательным базовым условием (с единственным отклонением в части использования нестандартных идентификаторов алгоритмов вычисления хэш-сумм архива STREEBOG-256 или STREEBOG-512).
  2. Подход: Методика формирования SBOM должна адаптироваться под среду функционирования (разделение для контейнеров и целевого ПО) и тип операционной системы (учет пакетов из состава сертифицированных ОС).
  3. Использование инструментов trivy и cdxgen эффективно решает задачи инвентаризации в типовых проектах с явным декларированием зависимостей. Однако результаты требуют обязательной валидации и доработки (externalReferences с ссылками на исходный код и атрибуты отнесения к ПА и ФБ) для устранения избыточности и приведения формата в полное соответствие с регуляторными нормами.

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

Автор:
Алексей Галкин, руководитель направления статического анализа, РУНЦ "Безопасность" МГТУ им. Н.Э. Баумана.

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