Start Debugging

SBOM для .NET в Docker: перестаньте пытаться заставить один инструмент видеть всё

Как отслеживать зависимости NuGet и пакеты ОС контейнера для Docker-образа .NET с помощью CycloneDX, Syft и Dependency-Track -- и почему одного SBOM недостаточно.

В одном из тредов по DevOps задали вопрос, который встречается постоянно: “Как одновременно отслеживать зависимости NuGet и пакеты ОС контейнера для приложения .NET, поставляемого как Docker-образ?”. Автор уже был близок к правильному подходу: CycloneDX для графа .NET-проекта, Syft для образа, затем загрузка в Dependency-Track.

Источник: тред на Reddit.

Один SBOM часто оказывается неверной целью

Образ контейнера содержит как минимум две вселенные зависимостей:

В .NET 9 и .NET 10 любая из этих сторон может случайно исчезнуть из поля зрения:

Именно поэтому “пусть один инструмент делает всё” обычно заканчивается слепыми зонами.

Создавайте два SBOM и сохраняйте происхождение

Вот практический конвейер:

Главное — происхождение. Вы хотите уметь отвечать на вопрос: “Эта CVE в моём базовом образе или в моём графе NuGet?” — без догадок.

Минимальные команды, которые можно вставить в CI

# App SBOM (NuGet focused)
dotnet tool install --global CycloneDX
dotnet CycloneDX .\MyApp.sln -o .\sbom --json

# Image SBOM (OS packages and what the image reveals)
docker build -t myapp:ci .
syft myapp:ci -o cyclonedx-json=.\sbom\container.cdx.json

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

Стоит ли объединять BOM?

Если ваш главный вопрос — “стоит ли объединить эти BOM в один?”, мой ответ по умолчанию: по умолчанию не объединять.

В Dependency-Track это часто превращается в два проекта: myapp и myapp-image. Это не лишняя сложность. Это более чистая модель.

Почему Syft “пропускает NuGet” и что с этим делать

Syft силён в работе с образами и файловыми системами. Он сообщает то, что может опознать из того, что видит. Если нужны достоверные зависимости NuGet, генерируйте их из графа проекта средствами CycloneDX.

Можете попробовать сканировать опубликованный вывод (например syft dir:publish/), но относитесь к этому как к дополнению. Вопрос “какие пакеты и каких версий мы используем?” принадлежит графу сборки, а не сканированию слоёв.

Если вы строите сервисы на .NET 10 в контейнерах, два SBOM — честный ответ. Вы получаете лучшее покрытие, более чёткую ответственность и меньше ложных срабатываний, съедающих спринт.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад