ADG Оставить заявку
Блог Информационная безопасность 5 мин чтения

SBOM на практике: Syft + Grype для container images и интеграция в CI

EO 14028 делает SBOM обязательным для поставщиков федерального ПО США. Разбираем форматы SPDX vs CycloneDX и собираем пайплайн с Syft и Grype для своих образов.

Контекст момента

Исполнительный указ EO 14028 закрепляет SBOM как обязательное требование для поставщиков федерального ПО США - enterprise-сектор начинает перенимать практику

В мае Байден подписал Executive Order 14028 - «Improving the Nation's Cybersecurity». Документ широкий, но один пункт в нём оказался на удивление конкретным: поставщики программного обеспечения для федеральных агентств США обязаны предоставлять SBOM - Software Bill of Materials, список компонентов, из которых состоит их ПО. NIST уже готовит методические рекомендации, крупные вендоры начали шевелиться. До нас это формально не доходит, но наблюдать, как требование из регуляторного документа начинает превращаться в практику enterprise-поставок, интересно. И поучительно, если думаешь о собственных цепочках зависимостей.

Мы начали собирать SBOM для внутренних инструментов - не потому что кто-то требует, а чтобы понять, что вообще находится внутри наших образов. Оказалось, там много интересного.

Что такое SBOM и зачем он нужен

SBOM - это машиночитаемый список всех компонентов, которые входят в ПО: библиотеки, их версии, лицензии, источники. Идея не новая - производители физических товаров давно ведут bill of materials. В ПО эта концепция долго оставалась в теории.

Практический смысл простой: когда выходит CVE для какой-нибудь библиотеки, нужно понять, в каких из ваших продуктов она используется. Без инвентаризации этот вопрос решается grep-ом по репозиториям и молитвами. После атаки на Kaseya VSA разговоры про supply-chain security стали значительно более конкретными, и SBOM вписывается в ту же логику: знать, что внутри, прежде чем что-то пойдёт не так.

Два формата: SPDX и CycloneDX

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

SPDX (Software Package Data Exchange) - стандарт Linux Foundation, изначально ориентированный на управление лицензиями. Существует с 2010 года, в августе 2021 принят как ISO/IEC 5962:2021. Хорошо работает там, где нужна детализация по лицензиям и compliance: кто правообладатель, условия использования, допустимо ли в корпоративном проекте. Форматы - TV (text/value), JSON, YAML, XML, RDF.

CycloneDX - стандарт OWASP, появился в 2017 году с более чётким фокусом на безопасности: vulnerability management, анализ зависимостей. Форматы - XML и JSON. Лаконичнее SPDX в части лицензионных метаданных, зато лучше интегрируется с инструментами vulnerability scanning.

Для нашей задачи - понять состав образов и найти уязвимые компоненты - CycloneDX подходит лучше. Для задачи «убедиться, что мы не тащим компоненты с несовместимыми лицензиями» - SPDX. На практике Syft умеет оба формата, так что выбор можно откладывать.

Syft: генерация SBOM для container images

Syft от Anchore - инструмент командной строки, который анализирует container image или файловую систему и строит SBOM. Ставится как один бинарник, никаких зависимостей.

Базовый сценарий выглядит так:

# SBOM в формате CycloneDX JSON
syft nginx:1.21 -o cyclonedx-json > nginx-sbom.json

# SBOM в формате SPDX Tag-Value
syft nginx:1.21 -o spdx-tag-value > nginx-sbom.spdx

# Для локального образа
syft packages dir:/path/to/unpacked/image -o cyclonedx-json

Что Syft умеет обнаружить: пакеты операционной системы (deb, rpm, apk), Python-пакеты (pip, setup.py, requirements.txt), Node.js (package.json, node_modules), Java (jar, war, pom.xml), Go-модули (go.mod, go.sum), Ruby gems. Список нормальный для текущего состояния инструмента.

Мы прогнали несколько наших рабочих образов - и обнаружили характерную вещь: базовые образы на debian:buster-slim тащат несколько десятков системных пакетов, часть из которых в наших приложениях не используется вовсе. Это не повод для паники, но повод для разговора об alpine-based образах или distroless.

Grype: vulnerability scanning по SBOM

Grype - пара к Syft от тех же авторов. Принимает на вход SBOM (или умеет сам вызвать Syft для image) и сверяет компоненты с базами уязвимостей: NVD, GitHub Advisory Database, базы дистрибутивов (Debian, Alpine, RHEL и другие).

# Прямо по образу
grype nginx:1.21

# По готовому SBOM
grype sbom:nginx-sbom.json

# Показать только HIGH и CRITICAL
grype nginx:1.21 --fail-on high

Вывод - таблица с CVE, severity, компонентом, версией и статусом фикса (fixed/not-fixed). Параметр --fail-on делает инструмент пригодным для CI: можно настроить, при каком severity пайплайн должен упасть.

Интеграция в CI-пайплайн

Мы добавили шаг в GitLab CI после сборки образа:

sbom-scan:
  stage: security
  image: anchore/syft:latest
  script:
    - syft ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA} -o cyclonedx-json > sbom.json
  artifacts:
    paths:
      - sbom.json
    expire_in: 30 days

vulnerability-scan:
  stage: security
  image: anchore/grype:latest
  needs: [build, sbom-scan]
  script:
    - grype sbom:sbom.json --fail-on high
  allow_failure: false

Несколько наблюдений из практики. Первое - время работы Syft на образ в 500-600 МБ составляет 30-60 секунд, это приемлемо. Второе - база уязвимостей Grype обновляется при каждом запуске (или можно кешировать), что добавляет к времени ещё несколько секунд. Третье - false negatives есть: Grype не поймает уязвимости в коде приложения, только в известных компонентах с CVE. Это не замена SAST, это дополнение.

Отдельный вопрос - что делать с результатами. Автоматически блокировать любой HIGH, не разобравшись, ведёт к парализованному пайплайну: в базовом debian-образе найдётся несколько HIGH-уязвимостей, для которых нет фикса в upstream прямо сейчас. Нужна политика: блокировать только fixable, остальное - в тикет с отслеживанием.

Где сейчас

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

Инструменты молодые и шероховатости есть. Но идея - знать состав того, что ты деплоишь, до того как CVE придёт к тебе снаружи - правильная. Лучше разбираться с этим в спокойном режиме, а не в режиме «только что вышла критическая CVE, у нас есть два часа».

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.