SBOM: откуда берётся ПО, которое мы устанавливаем, и как это проверить
После SolarWinds заказчики задают закономерный вопрос: откуда берётся ПО, которое мы устанавливаем? Объясняем концепцию SBOM и минимальную инвентаризацию open-source зависимостей.
SBOM (Software Bill of Materials) входит в повестку информационной безопасности после атаки SolarWinds: вопрос о происхождении и составе ПО становится практическим
После того как мы разобрали атаку SolarWinds, несколько клиентов задали примерно одинаковый вопрос. Не «как защититься от backdoor в обновлениях» - это сложно и разговор отдельный. А более приземлённый: «А вообще мы знаем, что у нас стоит? Откуда это взялось? Кто это собирал?». Хороший вопрос. Немного запоздалый, но хороший.
В профессиональных кругах на этот вопрос есть ответ - SBOM, Software Bill of Materials. Буквально - список компонентов ПО. Как список ингредиентов на упаковке с едой, только для программного обеспечения.
Что такое SBOM и зачем это нужно
Идея простая. Любое приложение - это не монолит, написанный с нуля. Это слои зависимостей: библиотеки, фреймворки, open-source компоненты, иногда чужие бинарники. Django тянет за собой полтора десятка пакетов. Node.js-приложение - сотни. Java-проект с Maven - вы сами знаете. У каждой из этих зависимостей есть версия, есть лицензия, есть история уязвимостей.
SBOM - это машиночитаемый документ, в котором перечислено: какие компоненты входят в продукт, какие у них версии, откуда они взяты. Форматы уже существуют: SPDX (стандарт Linux Foundation) и CycloneDX (проект OWASP). Оба XML/JSON, оба поддерживаются инструментами.
Зачем это нужно в практическом смысле? Когда появляется новая CVE - скажем, критичная уязвимость в популярной библиотеке - первый вопрос: «У нас это используется?». Без SBOM ответ требует ручного обхода каждого проекта. С SBOM - это запрос к файлу.
Реальная картина у клиентов
Сказать что SBOM повсеместно используется - нельзя. Это мягко говоря не так. Среди проектов, которые мы ведём или аудируем, систематический учёт зависимостей в машиночитаемом формате - редкость. Обычная картина такая:
Разработчики знают что используют - примерно. package.json или requirements.txt есть, но он отражает прямые зависимости. Транзитивные - то, что тянут ваши зависимости - уже мутнее. А именно там чаще всего обнаруживаются проблемные компоненты.
Производственная среда отличается от репозитория. package.json говорит «react ^17.0» - но что реально установлено в продакшне, с какими точными версиями - это package-lock.json или yarn.lock, и то, если они зафиксированы и актуальны.
DevOps и ИБ говорят на разных языках. Разработчик знает про зависимости, безопасник хочет знать про уязвимости. Мост между этими двумя знаниями - и есть SBOM.
Минимальный минимум: что можно сделать сейчас
Не нужно сразу строить полный pipeline с автоматической генерацией SBOM на каждый билд. Минимальные шаги, которые дают реальный результат:
Зафиксируйте lock-файлы в репозитории. package-lock.json, yarn.lock, Gemfile.lock, poetry.lock, Cargo.lock - это ваш де-факто SBOM для прямых и транзитивных зависимостей. Если они не лежат в git - вы не знаете, что реально установлено в продакшне.
Прогоните npm audit / safety / bundler-audit / trivy по своим проектам. Это не SBOM в строгом смысле, но это быстрый способ увидеть уязвимые компоненты. Trivy умеет сканировать не только Python и Node, но и образы Docker - и показывает уязвимости в системных пакетах тоже.
Попробуйте syft для генерации SBOM. Anchore выпустили syft - утилита генерирует SBOM в форматах SPDX и CycloneDX из образа контейнера, директории или репозитория. Работает из коробки, без регистраций. Одна команда - получаете файл с полным списком компонентов.
Настройте Dependabot или аналог. GitHub Dependabot мониторит зависимости и создаёт PR при обнаружении уязвимостей. Это не инвентаризация, но это автоматический мониторинг того, что у вас есть.
Про supply chain шире
SBOM решает часть проблемы - ту, где нужно знать состав. Но SolarWinds показал другое: атаку на сборочный процесс, где вредоносный код попал в официальную сборку от легитимного вендора. Здесь SBOM сам по себе не спасает. Вы можете знать, что используете SolarWinds Orion 2020.2.1 - и это не помогло бы.
Поэтому разговор про supply chain security состоит из нескольких слоёв:
- Инвентаризация - что у нас вообще есть (SBOM).
- Мониторинг уязвимостей - какие из компонентов имеют известные CVE.
- Верификация происхождения - подписи, хэши, reproducible builds.
- Сегрегация и привилегии - ограничение того, что скомпрометированный компонент может сделать.
Последние два пункта - это уже серьёзная архитектурная работа. Но первые два - вполне по силам без большого бюджета, просто как дисциплина.
Где мы сейчас
Честно: мы сами начали подходить к этому системно только сейчас. SolarWinds оказался хорошим катализатором. По нескольким проектам уже прогнали trivy, по двум запустили syft - посмотреть на реальный список компонентов в контейнерах. Результаты предсказуемо неприятные: несколько устаревших версий с известными CVE, которые никто не трогал, потому что «работает».
Аудит зависимостей - это не разовое мероприятие. Это процесс, который должен быть встроен в разработку и эксплуатацию. Начать с lock-файлов и одного сканирования - уже лучше, чем ничего.