容器镜像泄露凭证后怎样评估和处置

容器镜像里的访问令牌一旦能被匿名拉取,就应按已经泄露处理。风险不取决于镜像是否“只用于构建”,而取决于令牌仍能访问什么、镜像层能否被历史版本找回,以及攻击者能否把一次读取扩展成代码写入或云资源操作。

为什么旧镜像比源码仓库更容易出事

镜像不是单一文件。一次构建会留下多层文件系统快照,后续 Dockerfile 即使删除了配置文件,旧层也可能仍包含令牌、私钥或内部地址。镜像仓库若允许匿名列目录、取 manifest 或拉 blob,攻击者通常不需要进入应用,就能开始离线检索。

构建缓存和长期保留策略会放大这个问题。开发团队常把镜像当作短期产物,安全人员却要把它看成一份可能跨多年存在的发布记录。令牌过期前,每一个仍可下载的历史层都是入口。

先确认暴露是否真的能造成影响

处置前要验证访问边界,但不要在生产环境做破坏性操作。可以按下面顺序判断。

  1. 记录仓库是否可匿名枚举,能否拉取具体 tag 和 digest。
  2. 用隔离环境分析镜像层,定位密钥文件、环境变量、构建日志和包管理配置。
  3. 通过令牌的最小只读查询确认身份、有效期、权限范围和可访问资源。
  4. 检查令牌是否能写入代码、修改部署配置、读取客户数据或创建新的凭证。

最后一步决定事件等级。一个只能读取公开包的令牌与拥有组织管理权限的令牌,处置节奏完全不同。

发现令牌后先切断什么

先吊销或轮换凭证,再整理证据。仅把镜像设为私有并不能阻止已经下载到本地的副本。轮换后应检查自动化任务、发布流水线和依赖该令牌的脚本,避免修复动作引发连续部署失败。

如果令牌支持细粒度权限,应重新签发只覆盖单个仓库、单个环境和必要操作的凭证。不要用一个长期有效的管理员令牌替换另一个管理员令牌,这会把同一类事故留给下一次构建。

如何让镜像不再携带秘密

构建阶段通过短时 secret mount、CI 的受控变量或工作负载身份取得凭证,运行阶段不把构建令牌复制进镜像。多阶段构建能减少最终镜像内容,但不能替代秘密管理,因为中间镜像、缓存和构建日志同样需要访问控制与清理策略。

提交前扫描 Dockerfile、构建上下文和镜像层。扫描规则应覆盖私钥格式、常见令牌前缀、云配置文件和高熵字符串,并为误报留出人工复核通道。

复盘时该留下哪些改动

把镜像仓库的可见性、保留期限、匿名拉取策略和管理权限写成可审计配置。为高权限令牌增加使用告警,并在发布后做一次镜像内容检查。这样团队下次看到的会是可执行的防线,而非一份只描述事故经过的报告。

常见问题

删除 tag 能消除风险吗

不能保证。已经被拉取的层无法收回,仓库的保留和垃圾回收策略也可能让 digest 暂时仍可访问。

只读令牌是否可以忽略

不能。私有代码、配置和客户专用镜像本身就可能包含可继续利用的信息。