SLSA и Supply Chain Security
Защита цепочки поставок ПО: SLSA framework, Sigstore и SBOM
SolarWinds, Log4Shell и 18 000 компрометированных организаций
В декабре 2020 года стало известно, что атакующие скомпрометировали систему сборки SolarWinds Orion — популярной платформы для мониторинга сетей. Вредоносный код попал в обновление, которое установили более 18 000 организаций, включая государственные агентства США, Microsoft и Intel. Атака оставалась незамеченной месяцы: обновление было подписано валидным сертификатом SolarWinds, прошло все проверки целостности, и ничто в нём не указывало на компрометацию.
Год спустя, в декабре 2021 года, обнаружилась уязвимость Log4Shell в библиотеке Apache Log4j — одном из самых распространённых Java-компонентов для логирования. Уязвимость позволяла выполнить произвольный код, отправив специально сформированную строку в лог. Миллионы приложений использовали Log4j, и первые часы после раскрытия превратились в хаос: организации пытались выяснить, используют ли они эту библиотеку, в какой версии, и через какие транзитивные зависимости. Те, у кого был актуальный SBOM (Software Bill of Materials), ответили на эти вопросы за часы. Остальные — за недели.
Эти два инцидента изменили разговор о безопасности цепочки поставок ПО. Стало понятно, что доверять подписанному артефакту недостаточно — нужно доверять процессу его сборки. И что знать свои зависимости — не опция, а необходимость.
SLSA: четыре уровня зрелости
SLSA (Supply-chain Levels for Software Artifacts, произносится «salsa») — фреймворк от Google и OpenSSF, который определяет прогрессивные уровни защиты цепочки поставок. Последняя версия — SLSA v1.1 от апреля 2025 года.
SLSA Level 1 — документация. Процесс сборки описан, и для каждого артефакта генерируется provenance — машиночитаемый документ, который фиксирует, из какого исходного кода, каким инструментом и в каком окружении собран артефакт. На этом уровне provenance генерирует сам билд-процесс, и доверие к нему основано на доверии к мейнтейнеру.
SLSA Level 2 — подписанный provenance от hosted-сервиса. Provenance генерируется сервисом сборки (GitHub Actions, Google Cloud Build), а не скриптом разработчика. Сервис подписывает provenance, подтверждая, что сборка произошла на его инфраструктуре из указанного исходного кода.
SLSA Level 3 — изоляция сборки. Билд-процесс выполняется в изолированном окружении, которое не может быть модифицировано разработчиком или другими процессами. Это исключает сценарий SolarWinds, где атакующий модифицировал билд-сервер. На этом уровне даже скомпрометированный мейнтейнер не может незаметно изменить артефакт.
SLSA Level 4 — двустороннее ревью и гермитичные сборки. Каждое изменение проходит review от двух человек, сборка полностью воспроизводима и не зависит от внешних ресурсов. Это самый строгий уровень, и на практике его достигают единицы — в основном критическая инфраструктура.
Фреймворк задуман как инкрементальный: вы начинаете с Level 1 и двигаетесь вверх по мере зрелости. GitHub в 2024 году добавил встроенную поддержку attestations, и с slsa-github-generator можно достичь SLSA Level 2 для большинства типов артефактов за несколько часов работы.
Sigstore: подписание без управления ключами
Классическая проблема подписания артефактов — управление ключами. Вам нужно сгенерировать ключевую пару, хранить приватный ключ в безопасности, ротировать его периодически, отзывать при компрометации, и убедиться, что все потребители вашего артефакта имеют актуальный публичный ключ. Для open-source-проекта с тремя мейнтейнерами это уже обременительно.
Sigstore решает эту проблему через keyless signing — подписание без долгоживущих ключей. Система состоит из трёх компонентов.
Fulcio — certificate authority, который выпускает короткоживущие сертификаты (срок действия — 10 минут). Для получения сертификата вы проходите аутентификацию через OIDC: GitHub Actions, Google, Microsoft, или другой OIDC-провайдер. Fulcio привязывает сертификат к вашей identity (email или workflow) и к моменту времени.
Rekor — append-only transparency log, публичный и неизменяемый реестр всех подписаний. Каждый раз, когда вы подписываете артефакт, запись попадает в Rekor. Любой может проверить, что конкретный артефакт был подписан конкретной identity в конкретное время. Если кто-то попытается подменить подпись — расхождение будет видно в логе.
Cosign — инструмент командной строки для подписания и верификации. cosign sign подписывает Docker-образ, бинарник, SBOM или любой файл. cosign verify проверяет подпись. В CI-пайплайне (GitHub Actions) весь процесс автоматический: cosign получает OIDC-токен от GitHub, запрашивает сертификат у Fulcio, подписывает артефакт, записывает событие в Rekor — и всё это одной командой, без управления ключами.
SBOM: список ингредиентов вашего ПО
SBOM (Software Bill of Materials) — машиночитаемый документ, который перечисляет все компоненты вашего приложения: прямые и транзитивные зависимости, их версии, лицензии и известные уязвимости. Два основных формата — SPDX (от Linux Foundation) и CycloneDX (от OWASP).
SBOM стал критически важным после Log4Shell. CISA (Cybersecurity and Infrastructure Security Agency) сделал SBOM краеугольным элементом своих рекомендаций по безопасности: когда появляется следующая уязвимость масштаба Log4Shell, организации с актуальными SBOM определят затронутые системы за часы, а не за недели.
Генерация SBOM встроена в современные инструменты. Syft от Anchore сканирует Docker-образы и файловые системы, npm sbom генерирует SBOM для Node.js-проектов, Trivy от Aqua Security совмещает генерацию SBOM со сканированием уязвимостей. Cosign умеет подписывать SBOM и прикреплять подписанный SBOM к Docker-образу, создавая верифицируемую связь между образом и его списком компонентов.
npm, PyPI и проблема доверия к пакетам
Supply chain атаки на пакетные менеджеры выросли на 1300% за три года к 2024 году. Typosquatting (регистрация пакета с похожим именем — crypt0graphy вместо cryptography), dependency confusion (публикация пакета с именем внутреннего пакета компании в публичном реестре), захват заброшенных пакетов — атаки становятся изощрённее.
В 2025 году кампания MUT-8694 одновременно атаковала npm и PyPI, распространяя infostealer через пакеты, которые маскировались под популярные утилиты. В июне 2025 года атака на экосистему GlueStack затронула более дюжины пакетов с суммарным количеством загрузок около миллиона в неделю.
Защита от этих атак многослойная. npm audit и pip-audit проверяют известные уязвимости в зависимостях — добавьте их в CI. Lock-файлы (package-lock.json, poetry.lock) фиксируют точные версии и хэши зависимостей — коммитьте их и проверяйте целостность при установке (npm ci вместо npm install). Socket.dev анализирует поведение пакетов: если пакет внезапно начал обращаться к сетевым ресурсам или файловой системе после обновления, Socket это обнаружит. Дополнительно SAST и DAST сканеры помогут обнаружить подозрительное поведение уже на уровне вашего кода.
Для внутренних пакетов используйте scoped registries: настройте npm/pip так, чтобы пакеты с вашим scope (@mycompany/) загружались только из вашего приватного registry, а не из публичного — это закрывает вектор dependency confusion.
Практический маршрут
Внедрение supply chain security — как SLSA — задумано инкрементальным. Вот четыре шага от «ничего нет» до разумного уровня защиты.
Шаг 1: включите npm audit / pip-audit / trivy в CI — в духе shift-left. Пусть пайплайн падает на критических уязвимостях в зависимостях. Это 20 минут настройки и SLSA Level 0, но уже закрывает сценарий «мы используем библиотеку с известной CVE и не знаем об этом».
Шаг 2: добавьте генерацию SBOM в ваш release pipeline. Syft или встроенный npm sbom генерирует документ, который вы сохраняете рядом с артефактом. Когда появится следующий Log4Shell, вы откроете SBOM и за 5 минут поймёте, затронуты ли вы.
Шаг 3: подпишите ваши артефакты через Cosign. Если вы используете GitHub Actions, slsa-github-generator даёт вам SLSA Level 2 provenance с минимальной настройкой — в документации GitHub есть пошаговый гайд для Go-модулей, контейнеров и generic-артефактов.
Шаг 4: настройте верификацию при деплое. Kubernetes admission controller (Kyverno или OPA Gatekeeper) может проверять, что деплоящийся образ подписан вашим CI и имеет валидный provenance. Это замыкает цепочку: код прошёл ревью → CI собрал и подписал → Kubernetes проверил подпись → образ запустился в production.