Supply-chain безопасность: чтение конфигов и пайплайнов
Суть Читайте реальные манифесты, lockfile, вызов cosign verify и CI-воркфлоу, предсказывайте supply-chain поведение и выбирайте фикс с наибольшим рычагом.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min
Supply-chain проблемы живут в манифестах, lockfile и YAML пайплайнов — не в коде приложения. Прочитайте каждый сниппет, предскажите, где шаг установки уязвим, и выберите фикс, который сеньор сделал бы первым.
Цель
Отработайте цикл, который вы запускаете в каждом supply-chain ревью: прочитать манифест и пайплайн, предсказать, где могут войти недоверенные байты или недоверенный код, и взяться за контроль с наибольшим рычагом, прежде чем добавлять ещё сканирование.
Сниппет 1 — манифест
// package.json — и шаг CI, который его ставит{ "dependencies": { "left-pad": "^1.3.0", "@acme/billing": "^2.0.0" }}// CI: run: npm install
Викторина
Completed
Две вещи здесь ослабляют шаг установки. Какая пара и каков единственный фикс с наибольшим рычагом?
Heads-up Модность конкретного пакета — не supply-chain дефект. Дефект — ослабленные диапазоны плюс неэнфорсящая команда установки, пропускающая новые или подменённые байты.
Heads-up Классификация зависимости не меняет целостность шага установки. Уязвимость — caret-диапазон и `npm install` вместо `npm ci`, независимо от секции, где стоит пакет.
Heads-up `npm install` перезапишет lockfile под ослабленный диапазон, так что проверяемый хэш — это то, что он только что разрешил. Лишь `npm ci` против закоммиченного lockfile форсирует записанные хэши.
Сниппет 2 — манифест против lockfile
# package.json говорит:"@acme/ui": "^3.1.0"# package-lock.json (закоммичен) зафиксировал:"@acme/ui": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@acme/ui/-/ui-3.1.0.tgz", "integrity": "sha512-Abc123..." }# Вчера опубликована новая 3.4.0. CI запускает `npm ci`.
Викторина
Completed
С `npm ci` и этим закоммиченным lockfile какая версия установится и что делает поле integrity?
Heads-up `npm ci` не сверяется с caret-диапазоном; он ставит lockfile дословно. Caret важен лишь когда вы намеренно запускаете обновление, регенерирующее lockfile.
Heads-up Поле integrity форсируется: npm хэширует загруженный tarball и сравнивает с записанным sha512, падая при любом расхождении. Это и есть гарантия от подмены байтов.
Heads-up Под `npm ci` lockfile авторитетен, а не рекомендателен: и версия, и integrity-хэш форсируются, а расхождение валит установку.
Сниппет 3 — проверка provenance
# Пайплайн релиза подписывает образ; шлюз деплоя проверяет до выката:cosign verify \ --certificate-identity-regexp "https://github.com/acme/.*" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ ghcr.io/acme/api@sha256:9f2b... # зафиксировано по digest, не :latest
Викторина
Completed
Что на самом деле гарантирует этот шлюз cosign verify и почему важен @sha256 digest (а не :latest)?
Heads-up cosign проверяет подписи и идентичность provenance, а не уязвимости. Сканирование CVE — отдельный шаг по SBOM; verify отвечает за подлинность, а не за свежесть патчей.
Heads-up Подпись доказывает, кто собрал и что артефакт не подменён с момента подписания — а не что исходник был безвреден. Скомпрометированная, но легитимно подписанная сборка всё равно проходит; подписание снижает риск самозванца, не инсайдера.
Heads-up Тег изменяем: :latest можно перенаправить на другой образ после проверки. Фиксация по digest привязывает проверку к точным неизменяемым байтам, которые вы деплоите.
Сниппет 4 — CI-воркфлоу
on: pull_request_target: # запускается в контексте БАЗОВОГО репозиторияjobs: build: permissions: contents: write packages: write steps: - uses: actions/checkout@v4 with: { ref: ${{ github.event.pull_request.head.sha }} } # выкачивает код PR - run: npm install && npm run build # выполняет недоверенный код с токенами на запись + секретами
Викторина
Completed
Почему этот воркфлоу опасен и каков первый фикс?
Heads-up pull_request_target намеренно запускается в доверенном базовом контексте с секретами; сочетание его с checkout кода head PR и правами на запись — классический паттерн эксплойта, а не рекомендация.
Heads-up Фиксация actions по SHA — хорошая гигиена, но доминирующий риск здесь — выполнение недоверенного кода PR с секретами на запись, радиус поражения куда больше тега.
Heads-up Audit ловит известные advisory; он ничего не делает с недоверенным кодом, бегущим с токеном на запись и секретами. Фикс — least-privilege scoping и невыдача секретов запускам недоверенного кода.
Итог
Каждое supply-chain ревью читается в манифестах и YAML пайплайнов: caret-диапазоны плюс npm install пропускают новые или подменённые байты, тогда как закоммиченный lockfile плюс npm ci форсирует точные версии и integrity-хэши; cosign verify против ожидаемой идентичности сборки, с образом, зафиксированным по digest, отклоняет самозваные артефакты на шлюзе деплоя; а CI-воркфлоу, выполняющий недоверенный код PR с секретами на запись, — баг с наибольшим радиусом поражения. Читайте конфиг, найдите, где недоверенные байты или недоверенный код встречаются с вашими учётными данными, и чините эту границу прежде, чем добавлять ещё сканирование.