软件供应链安全
约 1448 字大约 5 分钟
supply-chainsecurity
2025-08-19
概述
软件供应链安全关注的是从源代码到生产部署全链路中每个环节的安全性。近年来,SolarWinds、Log4Shell、CodeCov 等事件表明,供应链攻击已成为最严重的安全威胁之一。攻击者不再直接攻击目标,而是通过污染依赖、构建工具或分发渠道实现间接入侵。
供应链攻击面
SLSA 框架
SLSA(Supply-chain Levels for Software Artifacts)是 Google 提出的供应链安全框架,定义了四个安全级别。
生成 SLSA Provenance
# GitHub Actions: 生成 SLSA Provenance
name: Build and Attest
on:
push:
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write # OIDC token
contents: read
attestations: write
steps:
- uses: actions/checkout@v4
- name: Build
run: |
go build -o myapp ./cmd/myapp
- name: Generate SLSA Provenance
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1
with:
base64-subjects: |
$(sha256sum myapp | base64 -w0)SBOM (Software Bill of Materials)
SBOM 是软件组件的清单,记录了所有依赖及其版本。
# 使用 Syft 生成 SBOM
syft packages dir:./my-project -o spdx-json > sbom.spdx.json
syft packages myimage:latest -o cyclonedx-json > sbom.cdx.json
# 使用 Trivy 生成 SBOM
trivy fs --format spdx-json --output sbom.json .
trivy image --format cyclonedx --output sbom.cdx.json myimage:latest// CycloneDX SBOM 示例(简化)
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"component": {
"type": "application",
"name": "my-application",
"version": "1.0.0"
}
},
"components": [
{
"type": "library",
"name": "express",
"version": "4.18.2",
"purl": "pkg:npm/express@4.18.2",
"licenses": [{ "license": { "id": "MIT" } }],
"hashes": [{
"alg": "SHA-256",
"content": "abc123..."
}]
}
]
}依赖扫描
# GitHub Actions: 依赖安全扫描
name: Dependency Security
on:
pull_request:
schedule:
- cron: '0 6 * * 1' # 每周一扫描
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# npm audit
- name: NPM Audit
run: npm audit --audit-level=high
# Trivy 文件系统扫描
- name: Trivy FS Scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'HIGH,CRITICAL'
exit-code: '1'
# Snyk 扫描
- name: Snyk Test
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=highSigstore/Cosign 签名验证
# 安装 Cosign
go install github.com/sigstore/cosign/v2/cmd/cosign@latest
# Keyless 签名(使用 OIDC,推荐)
cosign sign --yes registry.example.com/myapp:v1.2.3
# 会打开浏览器进行 OIDC 认证,签名记录到 Rekor 透明日志
# 验证签名
cosign verify registry.example.com/myapp:v1.2.3 \
--certificate-identity "user@example.com" \
--certificate-oidc-issuer "https://accounts.google.com"
# 使用密钥对签名
cosign generate-key-pair
cosign sign --key cosign.key registry.example.com/myapp:v1.2.3
cosign verify --key cosign.pub registry.example.com/myapp:v1.2.3
# 签名 SBOM 并附加到镜像
cosign attest --predicate sbom.cdx.json \
--type cyclonedx \
registry.example.com/myapp:v1.2.3Lock 文件安全
# npm: package-lock.json 必须提交到版本控制
# CI 中使用 ci 命令(严格按 lock 文件安装)
npm ci # 而非 npm install
# pip: 使用 hash 固定
pip install --require-hashes -r requirements.txt
# Go: go.sum 记录依赖哈希
go mod verify # 验证本地模块缓存的完整性# requirements.txt 带 hash 验证
Flask==2.3.3 \
--hash=sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b
requests==2.31.0 \
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003e可复现构建
# Dockerfile 最佳实践:可复现构建
FROM golang:1.21.5@sha256:abc123... AS builder
# 固定依赖版本
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
# 使用确定性构建标志
RUN CGO_ENABLED=0 GOFLAGS="-trimpath" \
go build -ldflags="-s -w -buildid=" \
-o /app ./cmd/server
# 最小运行时镜像
FROM gcr.io/distroless/static-debian12@sha256:def456...
COPY --from=builder /app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]Dependabot/Renovate 自动化更新
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
reviewers:
- "security-team"
labels:
- "dependencies"
# 安全更新立即创建 PR
# 版本更新按计划
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"// renovate.json (Renovate Bot 更灵活的配置)
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended", "security:openssf-scorecard"],
"vulnerabilityAlerts": {
"enabled": true,
"labels": ["security"]
},
"packageRules": [
{
"matchUpdateTypes": ["patch"],
"automerge": true
},
{
"matchUpdateTypes": ["major"],
"reviewers": ["team:security"]
}
]
}供应链安全检查清单
最佳实践
- 提交 Lock 文件并在 CI 中使用
npm ci/pip install --require-hashes - 启用 Dependabot/Renovate 自动化依赖更新,安全补丁优先合并
- 使用 Cosign 签名容器镜像,在 K8s 中配置签名验证策略
- 为每次构建生成 SBOM,存储在制品仓库中供审计
- 使用摘要(digest)固定基础镜像,而非仅使用标签
- CI/CD 环境最小权限化,限制构建环境的网络访问和密钥范围
- 启用 Git 提交签名和分支保护,要求 PR 评审后才能合并
- 定期审计依赖:扫描已知漏洞、检查许可证兼容性、评估维护状态
贡献者
更新日志
2026/3/14 13:09
查看所有更新日志
9f6c2-feat: organize wiki content and refresh site setup于