容器镜像漏洞扫描不能停留在“生成一份报告”。如果团队没有规定哪些漏洞必须修复、哪些镜像禁止上线,即使流水线显示几十个高风险问题,存在隐患的镜像仍可能进入生产环境。
真正有效的方案,需要把基础镜像、应用依赖、扫描报告、阻断阈值和例外审批连接起来,让每次发布都有明确的安全依据。
一、先判断交付风险,不要只看漏洞数量
镜像扫描通常会检查操作系统软件包、语言依赖和应用组件,并按照严重、危急、高危、中危等等级列出已知漏洞。
漏洞数量并不能直接决定是否上线。团队还需要判断:
- 漏洞是否存在可用修复版本
- 受影响组件是否会在运行时加载
- 当前服务是否存在可触达的攻击入口
- 漏洞是否涉及认证、文件解析或命令执行
- 容器是否使用特权模式运行
- 容器是否挂载了宿主机敏感目录
- 运行环境是否采用只读文件系统和最小权限账户
例如,公网接口使用的文件解析组件出现可远程利用的高危漏洞,风险通常高于镜像中未启用的命令行工具漏洞。
扫描器提供的严重度只是判断依据之一。最终是否阻断发布,还应结合应用用途、运行权限和实际暴露面评估。
二、从基础镜像控制漏洞来源
基础镜像是容器漏洞的重要来源。如果多个项目都使用同一个存在风险的基础镜像,漏洞会随着构建流程扩散到大量应用镜像中。
1、使用可信镜像来源
优先选择官方或持续维护的基础镜像,并检查:
- 镜像维护者
- 最近更新时间
- 支持周期
- 软件包来源
- 安全公告
- 镜像签名或来源证明
不要直接使用来源不明的个人镜像,也不要因为镜像体积较小就忽略其维护状态。
2、固定镜像版本或摘要
下面这种写法无法保证不同时间获得相同内容:
FROM node:latest
更稳妥的方法是固定明确版本:
FROM node:24.6.0-bookworm-slim
对构建可复现性要求较高时,可以进一步固定镜像摘要:
FROM node:24.6.0-bookworm-slim@sha256:镜像摘要
固定摘要不代表永久不更新,而是将基础镜像升级变成一次可审计的代码变更。升级时需要重新构建、扫描和测试,再决定是否合并。
3、使用多阶段构建
编译器、包管理器和调试工具通常只在构建阶段使用,不应全部保留在运行镜像中。
FROM node:24.6.0-bookworm-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:stable-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
多阶段构建可以减少最终镜像中的软件包数量,缩小镜像体积和攻击面,也能降低后续漏洞处理压力。
三、建立基础镜像清单
建议在代码仓库中维护基础镜像清单,至少记录以下信息:
| 项目 | 记录内容 |
|---|---|
| 镜像用途 | 构建环境、Web服务、后台任务等 |
| 镜像来源 | 官方仓库及镜像地址 |
| 固定版本 | 标签和镜像摘要 |
| 维护团队 | 负责升级和测试的人员 |
| 最近复核日期 | 最近一次安全检查时间 |
| 更新周期 | 每周、每月或按安全公告更新 |
| 替换方案 | 镜像停止维护后的迁移路径 |
如果漏洞暂时无法修复,还应记录漏洞编号、影响组件、补偿措施、负责人和例外到期日。
没有到期日的例外,很容易从临时放行变成长期遗漏。
四、把扫描加入CI/CD流水线
镜像扫描至少应覆盖三个阶段:
1、基础镜像入库前
在基础镜像进入企业镜像仓库前完成扫描,防止同一漏洞扩散到多个项目。
2、应用镜像构建后
每次构建完成后扫描应用镜像,检查新安装的软件包和应用依赖是否引入漏洞。
3、正式部署前
漏洞数据库持续更新。即使镜像构建时通过扫描,上线前也可能出现新披露的漏洞,因此部署前需要再次检查。
一条基本的交付流程可以设计为:
拉取固定基础镜像
→ 构建应用镜像
→ 生成软件物料清单
→ 执行漏洞扫描
→ 保存扫描报告
→ 判断风险阈值
→ 推送镜像仓库
→ 部署前再次扫描
→ 发布或阻断
软件物料清单用于记录镜像包含哪些组件,扫描报告用于审计,阈值规则则负责决定镜像能否继续交付。
五、使用Trivy扫描容器镜像
Trivy是一款常用的开源安全扫描工具,可以检查容器镜像中的操作系统软件包和应用依赖。
扫描镜像的基本命令如下:
trivy image example.com/project/app:1.0.0
只显示高危和严重漏洞:
trivy image \
--severity HIGH,CRITICAL \
example.com/project/app:1.0.0
仅在发现存在修复版本的高危或严重漏洞时返回失败状态:
trivy image \
--severity HIGH,CRITICAL \
--ignore-unfixed \
--exit-code 1 \
example.com/project/app:1.0.0
其中,--exit-code 1可用于让CI/CD任务失败,从而阻止镜像继续进入发布阶段。
--ignore-unfixed会忽略暂时没有修复版本的漏洞,不能在所有场景中直接使用。对于可远程利用或影响关键服务的漏洞,即使没有修复版本,也应进行人工评估并采取补偿措施。
六、生成软件物料清单
软件物料清单通常称为SBOM,用于记录镜像中的系统包、语言依赖及其版本。
使用Trivy生成CycloneDX格式的SBOM:
trivy image \
--format cyclonedx \
--output sbom.cdx.json \
example.com/project/app:1.0.0
SBOM可以帮助团队完成以下工作:
- 快速确认某个漏洞影响哪些镜像
- 查找正在使用特定组件的项目
- 比较镜像升级前后的依赖变化
- 保留发布版本的组件记录
- 配合安全审计和事件响应
扫描报告和SBOM应与镜像摘要关联,避免镜像标签被覆盖后无法确认报告对应的实际内容。
七、如何设置漏洞阻断阈值
漏洞阈值应结合严重度、可利用性、运行路径和修复状态设置,不能只按照数量决定。
下面是一套可作为初始版本的规则:
| 漏洞情况 | 建议处理 |
|---|---|
| 严重漏洞存在修复版本,并位于运行路径 | 阻断发布 |
| 高危漏洞影响网络入口、认证、文件解析或命令执行 | 阻断发布 |
| 高危漏洞超过3个,且存在明确利用路径 | 阻断发布并创建修复任务 |
| 中危漏洞较多,但没有明确利用路径 | 可以进入测试环境,限期复核 |
| 漏洞没有修复版本 | 进行人工评估,记录例外和补偿措施 |
| 仅影响构建阶段且未进入最终镜像 | 保留记录,根据实际影响处理 |
公网API、管理后台和内部批处理服务可以采用不同阈值,但同一类型的服务应使用统一规则。
初期不必一次拦截所有问题。可以先阻断“存在修复版本、可从外部触达、位于运行路径”的严重漏洞,待流程稳定后再逐步收紧。
八、上线阻断需要支持例外审批
过于宽松的规则会让扫描长期停留在告警阶段,过于严格的规则又可能因为误报或无修复版本阻塞正常交付。
合理的例外记录应包含:
- 漏洞编号
- 镜像名称和摘要
- 受影响组件
- 无法立即修复的原因
- 实际攻击路径
- 临时补偿措施
- 审批人和责任人
- 例外到期日期
例外期限默认不宜过长。到期后应重新扫描并再次评估,不能无限期自动续期。
上线阻断记录还应明确说明触发了哪条规则,以及通过什么方式解除阻断。
【图片位置:镜像扫描通过、阻断和例外审批流程图】
九、阻断后如何修复
镜像被阻断后,常见处理方法包括:
- 升级受影响的软件包或应用依赖
- 更换已修复的基础镜像
- 删除最终镜像中不需要的软件包
- 使用多阶段构建缩小运行镜像
- 停用存在风险且暂时不需要的功能
- 降低容器运行权限
- 限制网络入口和可访问范围
- 增加运行时监控和告警
修改完成后,必须重新构建并重新扫描。
不建议直接在原镜像记录上标记“已修复”。如果镜像摘要没有变化,后续无法证明实际交付内容已经更新。
十、定期复扫生产镜像
漏洞数据库每天都可能更新。构建时通过扫描的镜像,几周后可能因为新漏洞披露而变成高风险镜像。
建议至少每周复扫一次生产镜像,并把结果关联到当前运行的服务:
镜像摘要
→ 所属项目
→ 运行环境
→ 服务负责人
→ 漏洞结果
→ 修复进度
处理顺序可以按照业务风险安排:
- 公网服务和API入口
- 登录、认证及权限系统
- 支付和订单服务
- 文件上传与内容解析服务
- 数据库及内部管理服务
- 后台批处理任务
更新基础镜像后,还要检查应用启动、接口状态、错误率和资源占用,并保留旧镜像作为短期回滚版本。
十一、镜像安全需要配合运行环境
镜像扫描只能发现已知组件漏洞,不能代替运行环境加固。生产容器还应采取以下措施:
- 使用非Root用户运行
- 禁止特权容器
- 减少宿主机目录挂载
- 设置只读根文件系统
- 限制CPU和内存资源
- 关闭不需要的Linux能力
- 隔离构建节点与生产网络
- 妥善管理密钥和环境变量
- 保留日志、监控和异常告警
- 准备数据备份与版本回滚方案
十二、总结
容器镜像漏洞扫描的目标,是阻止无法接受的风险进入交付链路,而不是单纯生成一份漏洞清单。
团队可以先完成三项基础工作:
- 固定基础镜像来源、版本和摘要
- 在构建及部署阶段保存SBOM和扫描报告
- 使用明确阈值决定放行、阻断和例外审批
流程建立后,再逐步加入生产镜像复扫、基础镜像更新周期和运行环境加固。这样既能控制高风险漏洞,也不会让安全检查脱离实际交付场景。
常见问题
1、容器镜像扫描通过后就一定安全吗?
不一定。扫描工具主要识别已知漏洞,无法发现全部业务逻辑问题、错误权限和运行时攻击。还需要配合代码审查、密钥管理和运行环境加固。
2、没有修复版本的漏洞应该直接放行吗?
不能直接放行。应检查组件是否会在运行时加载、是否存在可触达入口,并记录补偿措施、审批人和例外期限。
3、基础镜像固定摘要后还需要更新吗?
需要。固定摘要是为了保证构建可复现,不是永久停止升级。团队仍应定期拉取候选版本,重新构建、扫描和测试。
4、镜像扫描应该在哪个阶段执行?
建议在基础镜像入库前、应用镜像构建后和正式部署前执行,同时对生产镜像进行定期复扫。
5、为什么要保留SBOM?
SBOM记录镜像包含的组件和版本。新漏洞披露后,团队可以快速定位受影响的镜像与线上服务,缩短排查时间。
-
广告合作
-
QQ群号:4114653



