Grype:围绕软件包目录与 SBOM 建立可复扫漏洞证据
Grype 的核心输入是软件包目录。它可以直接分析镜像或目录,也可以消费 Syft 等工具生成的 SBOM。后者把“识别了哪些组件”和“用哪份漏洞库匹配”分成两个可保存阶段,适合对同一制品反复复扫。前提是 SBOM、Grype、数据库与配置都能追溯。
本文使用 Grype 0.117.0 作为实验坐标。家族 17 是 Grype 产品权威入口;供应链流水线只引用本文的安装、数据库和门禁语义。
验证发布物与版本
官方 Release 为 checksums 提供签名材料。受控工具仓库先验证身份和摘要:
set -euo pipefail
GRYPE_VERSION=0.117.0
ASSET="grype_${GRYPE_VERSION}_linux_amd64.tar.gz"
SUMS="grype_${GRYPE_VERSION}_checksums.txt"
BASE="https://github.com/anchore/grype/releases/download/v${GRYPE_VERSION}"
work_dir="$(mktemp -d)"
cd "$work_dir"
for file in "$ASSET" "$SUMS" "${SUMS}.pem" "${SUMS}.sig"; do
curl -fLO "${BASE}/${file}"
done
cosign verify-blob "$SUMS" \
--certificate "${SUMS}.pem" \
--signature "${SUMS}.sig" \
--certificate-identity-regexp 'https://github\.com/anchore/grype/\.github/workflows/.+' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com'
grep " ${ASSET}$" "$SUMS" | sha256sum -c -
tar -xzf "$ASSET" grype
install -m 0755 grype "$HOME/.local/bin/grype"
grype version -o json普通 CI 只消费内部验证后的二进制或固定镜像 digest。动态安装脚本与浮动标签不适合安全门禁。
镜像与 SBOM 是两条输入链
直接扫描不可变镜像 digest:
grype "registry.example.invalid/team/app@sha256:<digest>" \
-o json > artifacts/grype-image.json消费 CycloneDX 或 Syft JSON SBOM:
sha256sum artifacts/app.cdx.json > artifacts/app.cdx.json.sha256
grype "sbom:artifacts/app.cdx.json" \
-o json > artifacts/grype-sbom.jsonSBOM 模式便于数据库更新后复扫,不必重新拉取镜像,但结论上限受 SBOM 组件覆盖限制。报告应绑定 SBOM 哈希、生成器版本、制品 digest、Grype 和数据库状态。没有这些字段,复扫结果变化无法归因。
漏洞库是扫描配置的一部分
联网同步任务显式更新并保存状态:
export GRYPE_DB_CACHE_DIR="$PWD/.cache/grype"
grype db update
grype db status -o json > artifacts/grype-db-status.json发布 Runner 不应在扫描中途自动换库:
GRYPE_DB_CACHE_DIR="/secure/grype-db" \
GRYPE_DB_AUTO_UPDATE=false \
GRYPE_CHECK_FOR_APP_UPDATE=false \
grype "sbom:artifacts/app.cdx.json" \
-o json > artifacts/grype.json离线环境由同步任务导出或传递官方支持的数据库归档,扫描侧执行 grype db import 后再检查状态。Grype 对数据库年龄有保护策略;过期或无法读取应让任务失败,不能永久关闭检查后声称离线可复现。
阈值退出码必须与工具错误分开
set +e
GRYPE_DB_AUTO_UPDATE=false \
GRYPE_CHECK_FOR_APP_UPDATE=false \
grype "sbom:artifacts/app.cdx.json" \
--fail-on high \
-o json > artifacts/grype-gate.json
scanner_rc=$?
set -e
test -s artifacts/grype-gate.json
case "$scanner_rc" in
0) printf 'no threshold finding\n' ;;
2) printf 'threshold finding detected\n' >&2; exit 2 ;;
*) printf 'grype execution failed: %s\n' "$scanner_rc" >&2; exit "$scanner_rc" ;;
esac阈值 high 是示例,不是所有仓库通用策略。生产门禁还要考虑 fix state、运行环境、可利用性、资产暴露和例外期限。完整报告保留低级别与无修复项,门禁视图再按策略裁决。
匹配结果要回到组件证据
一条 finding 至少包含软件包名称、版本、类型、PURL/CPE、漏洞 ID、数据源、严重度和修复版本。误报排查先确认 SBOM 组件是否正确,再看 matcher 与 advisory;不能看到 CVE 不适用就直接全局忽略。
不同发行版对同一 CVE 可能有不同状态。OS 包应优先解释发行版 advisory,语言包则核对生态坐标和 lockfile。包名相同不代表组件相同,路径和 cataloger 证据很重要。
VEX 或 ignore 记录应绑定制品、组件和漏洞,并包含状态、理由、owner、签名与到期。数据库更新后重新复扫,若修复版本或状态变化,旧例外不能无限沿用。
跨家族供应链任务只消费证据
Syft 生成 SBOM、Cosign 签名与 Attestation、发布门禁验证同一 digest,属于家族 18 的交付任务。那条任务可以执行 grype sbom:...,但 Grype 安装、数据库、阈值、匹配和故障语义以本文为唯一权威。这样升级 Grype 时只修改一个产品入口,供应链文章专注证据如何绑定 subject。
权限、成本与故障
扫描私有镜像只授予 Registry pull;SBOM 模式甚至不需要 Registry 权限。报告与 SBOM 会暴露依赖、路径和版本,是攻击面清单,应限制下载与保留期。数据库缓存为只读共享制品,低信任任务不能回写。
结果突然变化先比较 SBOM 哈希、Grype、数据库构建信息、配置和 matcher。空报告先区分零匹配、JSON 写入失败与目标解析失败。扫描慢时记录包数、matcher、数据库、CPU、内存与 I/O;无限增加并发可能放大 SQLite 和磁盘争用。
多架构镜像需要分别生成或核对每个平台 SBOM。把 amd64 的报告挂到整个 manifest list,会让 arm64 的不同包集获得错误背书。证据清单应按平台 digest 索引 SBOM、数据库状态和 Grype 报告,聚合门禁只消费这些明确结果。
升级、回滚与清理
升级使用固定镜像 digest 和固定 SBOM跑新旧 Grype/数据库组合,比较组件、漏洞、数据源、严重度、fix 与退出码。CLI 升级和数据库更新分开评审,避免一次变化无法归因。
回滚恢复二进制、数据库快照、配置与门禁策略。grype db delete 会影响共享 Runner,只能对解析后的明确缓存目录执行。退出 Grype 前,用同一 SBOM 验证替代扫描器的组件与漏洞覆盖,并保留历史报告的读取能力。
