应显式指定带版本号或digest的from镜像(如nginx:1.25.3或nginx@sha256:abc123),禁用latest等易变标签,优先选用语义化版本及可信registry地址,并在多阶段构建中确保各阶段均合规锁定。

直接检查 Dockerfile 中的 FROM 指令是否符合安全、可重现和可审计要求,是镜像构建前最关键的静态审查环节。
检查镜像来源是否明确可信
确保每个 FROM 都指向可验证的 registry,避免隐式依赖默认行为:
- 禁止裸写
FROM ubuntu或FROM nginx—— 这类写法实际等价于FROM docker.io/library/ubuntu:latest,既未锁定版本,也未显式声明 registry - 必须显式写出完整 registry 地址:如
FROM docker.io/library/debian:12.5、FROM gcr.io/distroless/python3:3.11或私有地址FROM registry.company.com/base/alpine:3.20.3 - 若使用私有 registry,需在 Hadolint 的
.hadolint.yaml中配置trustedRegistries列表,否则 DL3026 规则会报错
检查标签是否固定且语义清晰
版本号或 digest 是构建确定性的基础,不能依赖易变标签:
- 禁用
:latest、:stable、:alpine(Alpine 的无补丁版)等非固定标签 - 优先选用带小版本号的语义化标签,例如
python:3.11.9-slim、node:20.15.1-alpine - 更严格场景下,直接使用 digest 锁定(如
nginx@sha256:abc123...),它比 tag 更不可篡改 - 对 Alpine 等滚动发布镜像,注意区分
alpine:3.20(可能随时间更新)与alpine:3.20.3(精确快照)
检查多阶段构建中的 FROM 是否分层合理
多阶段构建中每个 FROM 都应独立满足规范,尤其注意构建阶段与运行阶段的隔离:
- 构建阶段(如
FROM node:20 AS build)也需指定完整 tag 或 digest,防止编译环境漂移 - 最终运行阶段(如
FROM nginx:1.25.3-alpine)必须使用最小化、加固过的镜像,且禁止复用构建阶段的 registry 或 tag 策略 - 避免跨阶段引用未声明 registry 的镜像,例如
COPY --from=build /app/dist /usr/share/nginx/html前,build 阶段的 FROM 必须合规
用工具自动执行并集成到 CI 流程
人工检查容易遗漏,应通过工具固化标准:
- 用
hadolint --config .hadolint.yaml Dockerfile扫描,重点捕获 DL3006(未指定 tag)、DL3026(不可信 registry)、DL3013(latest 使用)等规则 - 在 CI 中加入
docker pull+docker inspect验证步骤,提取实际拉取镜像的RepoDigests和RepoTags,比对是否与预期一致 - 结合 Trivy 或 Syft 生成 SBOM,确认基础镜像版本能映射到已知漏洞数据库,实现“版本 → CVE → 修复路径”的闭环追溯











