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

SBOM и верификация цепочки поставок: что изменилось после XZ Utils

Три месяца после XZ Utils backdoor: как мы внедрили автоматическую генерацию SBOM в CI, проверку подписей пакетов и задержку обновлений для системных компонентов.

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

После XZ Utils backdoor индустрия ускоряет внедрение SBOM и автоматической верификации цепочки поставок Open Source

Прошло три месяца с момента, когда CVE-2024-3094 стала главной новостью в инфосек-ленте. Первая реакция - инвентаризация, откат, хот-фиксы - уже за нами. Сейчас интереснее другой вопрос: что изменилось системно, а что осталось декларацией о намерениях.

Коротко: кое-что реально изменилось. Не революция, но и не «поговорили и забыли».

SBOM перестал быть абстракцией

SBOM - Software Bill of Materials, манифест зависимостей сборки - существовал как концепция давно. Его требовали американские регуляторы после другого инцидента, про него писали в методичках. Но у большинства команд в реальных CI-пайплайнах его не было: казалось, что это лишний артефакт непонятного назначения.

XZ Utils изменил этот разговор конкретно. Вопрос «какая версия liblzma сейчас на продакшн-серверах» оказалось нечем быстро ответить - нужно было идти руками по серверам. SBOM не решает проблему закладок, но он позволяет за секунды ответить на вопрос «у нас вообще есть этот пакет и в какой версии», а не разворачивать adhoc-инвентаризацию в субботу утром.

Мы интегрировали генерацию SBOM в CI для нескольких клиентских проектов. Инструмент выбрали Syft - он умеет в CycloneDX и SPDX, понимает контейнерные образы, deb/rpm-пакеты и языковые манифесты (pip, npm, go.mod). Схема простая:

- name: Generate SBOM
  run: |
    syft scan $IMAGE_NAME \
      --output cyclonedx-json=sbom.json \
      --output spdx-json=sbom-spdx.json
- name: Upload SBOM artifact
  uses: actions/upload-artifact@v4
  with:
    name: sbom
    path: sbom*.json

SBOM пишется в артефакты сборки и прикрепляется к релизу. Дальше его можно скармливать в Grype или OSV-Scanner для поиска CVE по зависимостям - это уже следующий слой.

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

Подписи пакетов: инструменты есть, привычки формируются

Следующий шаг после «знаем что стоит» - «знаем, что пакет не подменён». Sigstore и его инструменты (cosign для контейнеров, gitsign для коммитов) существовали до XZ, но после него разговоры о верификации подписей стали в несколько раз конкретнее.

Для контейнерных образов верификация через cosign уже работает у нас в нескольких пайплайнах:

cosign verify \
  --certificate-identity-regexp="https://github.com/<org>/" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
  $IMAGE_NAME

Это проверяет, что образ подписан именно тем CI-пайплайном, который мы ожидаем, а не чем-то другим с тем же именем и тегом. Подмена через registry - сценарий не фантастический, особенно если кто-то получил доступ к пушу в репозиторий.

С deb/rpm-пакетами ситуация другая: там подписи существуют давно (GPG на репозиторий), но проверка обычно идёт автоматически при apt/dnf. Вопрос в том, правильно ли настроены ключи и нет ли где-нибудь --allow-unauthenticated в скриптах автоматизации. Проверяли у клиентов - нашли несколько мест, где этот флаг появился «временно» и там и остался.

Задержка обновлений: три месяца практики

В марте мы описали политику задержки 72 часа для системных пакетов. Три месяца - небольшой срок, но кое-что уже видно.

Задержка не создала ни одного реального инцидента: ни один пакет из списка наблюдения не потребовал срочного патча, который бы мы пропустили из-за ожидания. Зато дважды за это время в течение первых суток после релиза в рассылках и на LWN появлялись обсуждения с замечаниями к патчам - не критичными, но заставившими дистрибьюторов притормозить и выпустить исправленную версию. Мы обновились уже на неё.

Это не доказательство того, что политика работает - выборка слишком мала. Но пока она не мешает и иногда помогает.

Что показалось полезным дополнительно. Список «чувствительных» пакетов мы немного расширили: добавили туда curl и wget - после разбора XZ стало понятно, что инструменты загрузки в сборочных скриптах тоже интересная поверхность. И добавили явную проверку: если пакет из списка обновился в рамках автоматического unattended-upgrades - это должно попасть в changelog с пометкой для ревью.

Что пока не решено

Честно: проблема, которую показал XZ Utils в самой неприятной своей части - атака через легитимного контрибьютора - автоматизированными инструментами не закрывается. SBOM знает, что у тебя стоит, cosign знает, что образ подписан тем CI. Но если сам CI скомпрометирован или если разработчик с правами на коммит внедрил закладку в upstream - это другой уровень.

Здесь работают только процессы: ревью изменений в критичных upstream-проектах, поддержка мейнтейнеров (буквально - финансово и организационно, а не только словами), осознанный выбор зависимостей с учётом health проекта.

Всё это медленнее, чем добавить шаг в пайплайн, и не масштабируется на весь граф зависимостей. Но это реальность, с которой работаем.

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

Контакт

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

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