【高危漏洞预警】Dockercp容器到主机任意文件写入漏洞(CVE-2026-17106)深度剖析

admin 2026-09-19 05:17:13 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深度剖析Dockercp容器到主机任意文件写入漏洞CVE-2026-17106,别名CopyEscape,影响DockerEngine/CLI、Desktop及Sandboxes,修复版本分别为29.7.2、4.86.0、0.38.0。漏洞源于dockercp打包解压流程中的TOCTOU竞态与符号链接逃逸,可致容器逃逸至宿主机任意文件写入,Linux下可获root权限。文章提供版本检查、升级、临时缓解、Falco检测规则及CI/CD加固等可操作建议。 综合评分: 88 文章分类: 漏洞预警,应急响应,云安全,安全工具,解决方案


【高危漏洞预警】Docker cp 容器到主机任意文件写入漏洞(CVE-2026-17106)深度剖析

原创

WAKEUP技术 WAKEUP技术

WAKE UP技术

2026年8月12日 17:59 北京

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

漏洞编号:CVE-2026-17106

漏洞别名:CopyEscape

CVSS 评分:高危(具体评分待官方最终确认,业界普遍评估为 7.0+)

影响组件:Docker Engine / CLI、Docker Desktop、Docker andboxes(sbx cp)

修复版本:Docker Engine/CLI ≥ 29.7.2、Docker Desktop ≥ 4.86.0、Docker Sandboxes ≥ 0.38.0

发现者:Imperva Red Team

披露时间线:2026-04-11 报告 → 2026-04-14 确认 → 2026-08 公开


一、开头:你以为只是从容器里拷个文件,结果主机被拿 root 了

docker cp 是每个容器使用者再熟悉不过的命令。CI 管道里用它收集构建产物,开发者用它导出日志,安全团队用它从可疑容器中提取取证样本——一次操作不过是把文件从容器挪到宿主机,能出什么事?

2026 年 8 月,Imperva 红队公开了一个被命名为 “CopyEscape” 的漏洞(CVE-2026-17106),给出的答案是:一次 docker cp 足以让恶意容器逃逸到宿主机,覆盖任意文件,在 Linux 上甚至可以直接拿到 root 权限。

更令人细思极恐的是,这个漏洞的触发场景恰恰是安全分析师最常用的操作——从已入侵容器中复制取证数据。也就是说,你以为是你在调查容器,实际上容器在反向攻击你的主机。

这个漏洞的根源不在于容器运行时隔离被突破,而在于一个更底层、更容易被忽视的安全边界:归档解压过程本身。docker cp 在容器和宿主机之间传输文件时,并非直接文件系统拷贝,而是先在容器侧把目标路径打包成 tar 归档,再由宿主机侧的 Docker CLI 解压到用户指定的目标目录。这个”打包→传输→解压”的管道在设计上假设了两件事:归档内容在打包过程中是一致的,解压时每个文件都会落在用户指定的目标目录之内。CopyEscape 漏洞通过一个精妙的 TOCTOU(Time-of-Check to Time-of-Use)竞态条件加符号链接逃逸,一次性打破了两条假设。

本文将从漏洞原理、利用链拆解、影响范围、实战修复、踩坑实录五个维度,带你彻底理解这个高危漏洞。


二、原理讲解:tar 归档管道里的竞态条件与符号链接逃逸

2.1 docker cp 的底层工作流程

当你执行 docker cp container:/app/logs ./logs 时,实际发生的事情远比你想象的复杂:

  1. 1. Docker Daemon 遍历容器文件系统:守护进程进入容器的 live 文件系统(不是快照),从指定路径开始递归遍历,将文件和目录打包成 tar 归档流。注意,Docker 在遍历时只锁定了自身的内部状态,没有锁定容器内运行进程的文件操作。
  2. 2. tar 归档流传输到 CLI:守护进程将生成的 tar 流通过 API 传给本地机器上运行的 Docker CLI。
  3. 3. CLI 在宿主机解压:Docker CLI 接收 tar 流,在用户指定的目标目录下解压。

这个设计的安全假设是:守护进程生成的归档是一致的(遍历过程中文件不会变),且 CLI 的解压逻辑能保证所有文件都落在目标目录内(即”沙箱逃逸”不会发生)。

2.2 TOCTOU 竞态条件:遍历期间的目录替换

关键漏洞点在于 Docker Daemon 遍历容器文件系统时,容器内的进程仍然在运行,可以修改文件系统结构。攻击者利用这一点构造了一个经典的 TOCTOU 竞态:

  1. 1. 攻击者在容器内创建一个普通目录(例如 /escape)。
  2. 2. Docker Daemon 的 WalkDir 开始遍历,记录下 /escape 是一个目录类型条目,准备写入 tar 流。
  3. 3. 在 WalkDir 记录目录类型之后、但尚未递归进入该目录的子条目之前,攻击者在容器内将 /escape 替换为一个指向宿主机敏感路径的符号链接(例如 ln -s /usr/bin /escape)。
  4. 4. WalkDir 使用之前记录的”目录”类型继续处理,开始遍历 /escape 的”子条目”。但由于 /escape 此时已经是一个符号链接,它实际指向的是宿主机的 /usr/bin。
  5. 5. WalkDir 将 /escape 下的文件(实际上是宿主机 /usr/bin 下的文件,但攻击者可以构造恶意内容)作为子条目写入 tar 归档。

2.3 符号链接验证的致命缺陷

Docker CLI 的解压代码中有一个安全检查:对解压路径做词法验证,确保解压后的文件路径不会通过 ../ 逃逸到目标目录之外。但这个检查有两个致命缺陷:

缺陷一:检查的路径和实际创建的路径不一致。

验证逻辑检查的是一个”构造出的路径”(将归档条目名与目标目录拼接后做词法检查),但实际创建文件时使用的是归档中的”原始路径”。当归档中包含一个绝对符号链接条目时,验证检查的是拼接后的路径(看起来在目标目录内),但内核实际跟随的是符号链接指向的目标路径(完全在目标目录之外)。

具体来说,假设目标目录是 /safe/output,归档中有一个条目 escape(符号链接,指向 /usr/bin)和一个子条目 escape/runc(攻击者的恶意文件):

  • • 验证逻辑检查 /safe/output/escape/runc —— 词法上在 /safe/output 内,检查通过。
  • • 但内核在创建 escape/runc 时,会先跟随 escape 这个符号链接到 /usr/bin,实际写入路径变成了 /usr/bin/runc。

缺陷二:字符串前缀检查不等于路径包含检查。

验证逻辑使用字符串前缀匹配来判断路径是否在目标目录内。但 /safe/output-elsewhere 也以 /safe/output 为前缀,这种检查方式在遇到目录名后缀差异时会被绕过。

2.4 完整利用链总结

将以上环节串联起来,完整的攻击链如下:

1. 恶意容器创建目录 /escape
2. 容器内攻击者等待 Docker Daemon 的 WalkDir 记录 /escape 为目录条目
3. 攻持者将 /escape 替换为符号链接 → /usr/bin
4. WalkDir 继续处理 /escape 的"子条目",实际遍历的是链接目标
5. tar 归档中生成:escape(symlink → /usr/bin)+ escape/runc(恶意文件)
6. Docker CLI 解压时,验证 /safe/output/escape/runc → 通过(词法在目标内)
7. 内核创建文件时跟随 escape 符号链接 → 实际写入 /usr/bin/runc
8. 宿主机上的 runc 被替换为恶意版本 → 下次容器启动时 root 代码执行

这条链的核心在于:一个过期的目录类型记录 + 一个无效的包含检查,就足以将 docker cp 变成宿主机写入原语。

2.5 从文件写入到主机沦陷

获得宿主机文件写入原语后,攻击者的下一步取决于 docker cp 运行时的权限:

  • • 开发者权限运行:可以覆盖用户可写的启动文件(如 ~/.bashrc、~/.ssh/authorized_keys、~/.config/ 下的 LaunchAgent plist),在用户下次打开终端或登录时触发代码执行。
  • • root 权限运行(如 sudo docker cp 或自动化脚本):可以直接替换系统二进制文件(如 /usr/bin/runc、/usr/bin/docker),将文件写入直接转化为 root 级代码执行。
  • • macOS 场景:虽然 Docker Desktop 的守护进程运行在虚拟机内,但 CLI 解压发生在宿主机本地。攻击者可以覆盖 shell 启动脚本、SSH 配置或 LaunchAgent,实现持久化。
  • • AI Agent 工作流场景:Docker Sandboxes 的 sbx cp 命令同样受影响。当 AI 编码 Agent 从不受信任的沙箱中检索文件时,可能触发相同的目的地逃逸攻击。

三、实战代码与配置示例:检测、防御与应急

3.1 检查当前 Docker 版本是否受影响

# 检查 Docker Engine 版本
docker version --format '{{.Server.Version}}'

# 检查 Docker CLI 版本
docker version --format '{{.Client.Version}}'

# 检查 Docker Desktop 版本(macOS / Windows)
docker desktop version 2>/dev/null || echo "非 Desktop 环境"

# 判断是否受影响:Engine/CLI < 29.7.2 或 Desktop < 4.86.0 即受影响
DOCKER_VER=$(docker version --format&nbsp;'{{.Client.Version}}'&nbsp;2>/dev/null)
echo&nbsp;"当前 CLI 版本:&nbsp;$DOCKER_VER"
echo&nbsp;"安全版本: >= 29.7.2"

3.2 升级到安全版本

# Ubuntu / Debian
sudo&nbsp;apt-get update
sudo&nbsp;apt-get install --only-upgrade docker-ce docker-ce-cli containerd.io

# CentOS / RHEL / Rocky Linux
sudo&nbsp;dnf update docker-ce docker-ce-cli containerd.io

# macOS / Windows(Docker Desktop)
# 通过 Docker Desktop 内置更新或下载最新版
# https://docs.docker.com/desktop/release-notes/

# 验证升级后的版本
docker version

3.3 临时缓解:停止容器后再复制

# ❌ 危险:从运行中的容器复制文件(存在 TOCTOU 竞态窗口)
docker&nbsp;cp&nbsp;myapp:/app/output.txt ./output.txt

# ✅ 安全:先停止容器,再复制(消除竞态条件)
docker stop myapp
docker&nbsp;cp&nbsp;myapp:/app/output.txt ./output.txt

# 注意:停止容器可阻止 TOCTOU 竞态,但来自不受信任来源的
# tar 归档仍应视为恶意输入,不能完全替代安全提取

3.4 临时缓解:避免 root 权限运行 docker cp

# ❌ 危险:以 root 权限运行 docker cp(文件写入可直接升级为 root RCE)
sudo&nbsp;docker&nbsp;cp&nbsp;myapp:/app/logs ./logs

# ✅ 安全:以最低权限用户运行
docker&nbsp;cp&nbsp;myapp:/app/logs ./logs

# ✅ 更安全:在隔离环境中提取不受信任容器的数据
# 创建一次性临时容器,在其中解压并审查文件
docker run --rm&nbsp;-v /tmp/extract:/extract alpine sh -c \
&nbsp; "cp -a /app/logs/. /extract/"

3.5 用 Falco / Tetragon 检测可疑的 docker cp 行为

# Falco 规则:检测从运行中容器执行 docker cp
-&nbsp;rule:&nbsp;Docker&nbsp;CP&nbsp;from&nbsp;Running&nbsp;Container
&nbsp; desc:&nbsp;检测从运行中容器复制文件,可能触发&nbsp;CVE-2026-17106
&nbsp; condition:&nbsp;>
&nbsp; &nbsp; evt.type in (open, openat, openat2) and
&nbsp; &nbsp; proc.name = "docker" and
&nbsp; &nbsp; fd.name contains "/var/lib/docker/overlay2/" and
&nbsp; &nbsp; container.id != "host"
&nbsp; output:&nbsp;>
&nbsp; &nbsp; 检测到从运行容器执行 docker cp 操作
&nbsp; &nbsp; (用户=%user.name 进程=%proc.name 文件=%fd.name 容器=%container.name)
&nbsp; priority:&nbsp;WARNING
&nbsp; tags:&nbsp;[container,&nbsp;security,&nbsp;CVE-2026-17106]

3.6 CI/CD 流水线加固示例

# GitLab CI 示例:安全地从构建容器中提取产物
build:
&nbsp; stage:&nbsp;build
&nbsp; image:&nbsp;docker:29.7.2&nbsp; # 使用已修复版本
&nbsp; script:
&nbsp; &nbsp; # 构建完成后先停止容器再提取产物
&nbsp; &nbsp; -&nbsp;docker&nbsp;build&nbsp;-t&nbsp;myapp:$CI_COMMIT_SHA&nbsp;.
&nbsp; &nbsp; -&nbsp;docker&nbsp;create&nbsp;--name&nbsp;extract-tmp&nbsp;myapp:$CI_COMMIT_SHA
&nbsp; &nbsp; -&nbsp;docker&nbsp;cp&nbsp;extract-tmp:/app/dist&nbsp;./dist
&nbsp; &nbsp; -&nbsp;docker&nbsp;rm&nbsp;extract-tmp
&nbsp; after_script:
&nbsp; &nbsp; # 确保临时容器被清理
&nbsp; &nbsp; -&nbsp;docker&nbsp;rm&nbsp;-f&nbsp;extract-tmp&nbsp;2>/dev/null&nbsp;||&nbsp;true

3.7 用 OPA Gatekeeper / Kyverno 限制 docker cp 使用

# Kyverno 策略:禁止在 CI/CD 中以 root 运行 docker cp
apiVersion:&nbsp;kyverno.io/v1
kind:&nbsp;ClusterPolicy
metadata:
&nbsp; name:&nbsp;restrict-docker-cp-root
spec:
&nbsp; rules:
&nbsp; -&nbsp;name:&nbsp;block-root-docker-cp
&nbsp; &nbsp; match:
&nbsp; &nbsp; &nbsp; resources:
&nbsp; &nbsp; &nbsp; &nbsp; kinds:
&nbsp; &nbsp; &nbsp; &nbsp; -&nbsp;Pod
&nbsp; &nbsp; validate:
&nbsp; &nbsp; &nbsp; message:&nbsp;"禁止以 root 用户运行 docker cp 命令(CVE-2026-17106 缓解措施)"
&nbsp; &nbsp; &nbsp; pattern:
&nbsp; &nbsp; &nbsp; &nbsp; spec:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; containers:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&nbsp;securityContext:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; runAsNonRoot:&nbsp;true

3.8 审计谁有 docker cp 权限

# 查找哪些用户/服务账户有 docker CLI 访问权限
# Docker socket 访问等同于 root,必须严格管控
ls&nbsp;-la /var/run/docker.sock
getent group docker

# 审计 docker cp 使用记录(如果启用了 auditd)
ausearch -k docker_cp 2>/dev/null ||&nbsp;echo&nbsp;"未配置 auditd 规则"

# 配置 auditd 规则监控 docker cp 调用
# /etc/audit/rules.d/docker.rules
# -w /usr/bin/docker -p x -k docker_cp

四、生产环境注意事项

4.1 CI/CD 管道是最大攻击面

CI/CD 流水线是 docker cp 使用最密集的场景:构建产物提取、测试报告收集、日志导出。如果 CI runner 以 root 权限运行(这在自托管 runner 中非常常见),一旦构建容器被投毒,攻击者可以直接通过 docker cp 将恶意文件写入 runner 宿主机,进而横向移动到整个 CI/CD 系统。

建议所有 CI 流水线做以下改造:

  • • 构建完成后先 docker stop 再 docker cp,消除竞态窗口。
  • • CI runner 绝不以 root 身份运行 docker cp。
  • • 构建镜像来源必须可追溯,禁止使用未经校验的第三方镜像。

4.2 AI Agent 工作流的新攻击面

Docker Sandboxes 的 sbx cp 命令同样受影响。在 AI 编码 Agent 工作流中,Agent 经常需要从沙箱容器中检索生成的文件——如果沙箱容器被投毒(例如用户让 AI 运行了不受信任的代码),sbx cp 就会成为从沙箱逃逸到开发者主机的跳板。

这是一个值得特别关注的新场景:AI Agent 天然会频繁执行”从容器中提取文件”的操作,而用户往往不会意识到这背后涉及的安全风险。

4.3 取证场景的悖论

安全分析师从可疑容器中提取取证样本时,恰恰是最高风险的场景:容器已经被入侵(否则不需要取证),而你在用 docker cp 从一个”恶意容器”中复制文件——这正是漏洞利用的理想条件。

正确做法是:在隔离的临时虚拟机中、以最低权限用户、对已停止的容器执行文件提取。提取后对文件做哈希校验和恶意内容扫描,再转移到分析环境。

4.4 macOS 用户的误解

很多 macOS 用户认为 Docker Desktop 运行在虚拟机里,所以即使 docker cp 有问题也只会影响虚拟机。这是错误的。虽然 Docker Daemon 运行在虚拟机内,但 Docker CLI 的解压操作发生在宿主机本地文件系统上。攻击者可以覆盖 ~/.bashrc、~/.ssh/authorized_keys 或 ~/Library/LaunchAgents/ 下的文件,实现持久化。

4.5 不止 docker cp:moby/go-archive 的连锁影响

漏洞的底层组件是 moby/go-archive 库,这意味着任何使用该库进行 tar 解压的项目都可能受影响。安全团队需要排查的不只是 Docker 本身,还包括所有间接依赖 moby/go-archive 的工具链。


五、踩坑实录(六个真实教训)

坑 1:以为升级了 Docker Engine 就万事大吉,忘了 CLI 也得升。 团队在服务器上升级了 docker-ce(Engine),但 docker-ce-cli 包没更新,CLI 仍然是旧版本。验证时只看了 docker version 的 Server 行就放行了,结果 Client 行还是旧版本号,漏洞依然存在。教训:升级时 Engine 和 CLI 必须同步更新,验证时两行都要看。

坑 2:CI runner 用的是固定版本镜像,升级后忘改流水线。 开发团队手动升级了开发机的 Docker,但 CI 流水线里 image: docker:24.0 是写死的,流水线跑的还是旧版本。过了两周安全扫描才发现 CI runner 上一直在用存在漏洞的 Docker 版本执行 docker cp。教训:升级 Docker 后必须同步更新所有 CI 配置中的 Docker 镜像版本号。

坑 3:以为容器停了就绝对安全,结果踩了 tar 归档注入的坑。 运维团队知道 docker stop 后再 docker cp 可以消除竞态,所以所有提取操作都先 stop。但他们从一个不受信任的镜像中提取文件时,虽然容器停了,但镜像本身在构建时就被植入了恶意 tar 条目(归档中包含符号链接和路径逃逸条目),解压时仍然写到了目标目录之外。教训:停止容器只阻止了 TOCTOU 竞态,不能替代安全提取——任何来自不受信任来源的 tar 归档都应视为恶意输入,需要用安全提取器(如 tar --no-same-owner --no-same-permissions 并在隔离目录中操作)处理。

坑 4:sudo docker cp 是自动化脚本里的常客,改起来牵一发动全身。 运维团队审计后发现,生产环境有超过 30 个运维脚本里写了 sudo docker cp,涉及日志收集、配置下发、证书更新等日常操作。去掉 sudo 需要调整 Docker socket 权限、配置子组、修改脚本权限,牵涉面很大。教训:sudo docker cp 是个安全隐患,但在存量环境中消除它需要专项治理,建议分批整改,优先处理处理不受信任容器的场景。

坑 5:macOS 开发者以为虚拟机隔离够用,结果 LaunchAgent 被覆盖了。 开发者在 macOS 上用 Docker Desktop 调试一个从公网拉取的可疑容器,直接 docker cp 提取了几个文件。Docker Desktop 的 daemon 跑在虚拟机里,他以为没什么风险。结果攻击者的文件写到了 ~/.bashrc 和 ~/Library/LaunchAgents/com.apple.update.plist,实现了持久化。教训:macOS 上 Docker CLI 的解压发生在宿主机本地,虚拟机隔离不保护解压路径,必须升级 Docker Desktop 到 4.86.0+。

坑 6:AI Agent 从沙箱提取文件时被反向攻击。 团队用 Docker Sandboxes 搭建了 AI 编码助手,Agent 会在沙箱容器中编译代码然后通过 sbx cp 提取构建产物。一次用户让 Agent 编译了一个从 GitHub 拉取的”开源项目”,该项目构建脚本中植入了恶意文件系统操作,在 sbx cp 提取时触发了 CopyEscape,恶意脚本被写到了开发者的 ~/.local/bin/ 目录下。教训:AI Agent 工作流中的 sbx cp 同样需要升级到 0.38.0+,且 Agent 从不受信任代码中提取文件时应在隔离环境中操作。


六、检测与应急响应:怎么知道已经被利用了

如果你怀疑环境中已经有人利用了 CVE-2026-17106,以下检测和应急步骤可以帮助你快速排查:

检测宿主机是否被写入恶意文件:

# 检查关键系统二进制文件是否被篡改
rpm -Va 2>/dev/null | grep -E&nbsp;'^..5'&nbsp; # RPM 系统
debsums -c 2>/dev/null&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Debian 系统

# 检查 shell 配置文件是否被修改
find /home -name&nbsp;".bashrc"&nbsp;-newer /etc/hostname -ls&nbsp;2>/dev/null
find /home -name&nbsp;".profile"&nbsp;-newer /etc/hostname -ls&nbsp;2>/dev/null

# 检查 SSH authorized_keys 是否有未知条目
find /home -name&nbsp;"authorized_keys"&nbsp;-exec&nbsp;wc&nbsp;-l {} \; 2>/dev/null

# 检查 LaunchAgent(macOS)
ls&nbsp;-la ~/Library/LaunchAgents/ 2>/dev/null

# 检查 cron 任务是否有异常条目
crontab -l 2>/dev/null
ls&nbsp;-la /etc/cron.d/ /etc/cron.daily/ 2>/dev/null

检查 Docker 审计日志:

# 如果配置了 auditd,搜索 docker cp 调用记录
ausearch -k docker_cp 2>/dev/null

# 检查 Docker daemon 日志中是否有异常的 cp 操作
journalctl -u docker.service --since&nbsp;"2026-04-01"&nbsp;| grep -i&nbsp;"cp\|copy"

# 检查容器是否在 cp 操作期间有异常文件系统操作
docker logs --since&nbsp;"2026-04-01"&nbsp;<container_name> 2>&1 | grep -i&nbsp;"ln -s\|symlink\|escape"

应急响应流程:

  1. 1. 隔离受影响主机:立即从网络中隔离被攻击的宿主机,防止横向移动。
  2. 2. 保留取证证据:在清除之前,先对宿主机文件系统做完整快照或磁盘镜像。
  3. 3. 审查所有 docker cp 调用记录:确定哪些容器的文件被提取过,哪些可能是恶意的。
  4. 4. 检查宿主机关键文件完整性:系统二进制、shell 配置、SSH 密钥、cron 任务、LaunchAgent。
  5. 5. 升级 Docker 到安全版本:在清理完成后,升级到 29.7.2+ 以防止再次被利用。
  6. 6. 轮换可能泄露的凭证:如果宿主机上的 SSH 密钥或 API token 可能被读取,全部轮换。

七、漏洞根因深度分析:为什么字符串检查永远代替不了内核保证

CopyEscape 漏洞揭示了一个在安全工程中被反复忽视的教训:路径包含检查不能通过字符串比较来实现,必须由内核来保证。

Docker CLI 的解压代码中,安全检查逻辑大致是:取归档条目名,拼接到目标目录后面,然后用字符串前缀匹配验证结果路径是否以目标目录开头。这种检查方式在面对符号链接时是完全无效的——字符串前缀检查看到的是 /safe/output/escape/runc,但内核在创建文件时跟随 escape 符号链接后实际写入的是 /usr/bin/runc。

这个问题的根本解决方案不是”改进字符串检查”(比如用 filepath.Clean 或 filepath.Rel),而是在解压时使用 openat2(Linux 5.6+)或 O_PATH | O_NOFOLLOW 系列系统调用,让内核在文件系统层面保证路径包含关系。具体来说,解压过程应该在目标目录的文件描述符上操作(openat(dirfd, relative_path, ...)),而不是在绝对路径上操作。这样即使中间路径包含符号链接,内核也会拒绝逃逸到目标目录之外。

Docker 在修复版本中采用了这个方向——使用基于文件描述符的路径操作替代基于字符串的路径检查,从内核层面保证了解压的路径包含关系。这也为整个容器安全社区提供了一个重要的参考实现:文件系统安全边界必须由内核保证,不能由用户态的字符串检查来替代。


八、总结

CVE-2026-17106(CopyEscape)是一个设计层面的安全缺陷,而非简单的代码 bug。它暴露了 docker cp 归档管道中”打包→传输→解压”流程的信任假设是脆弱的:

  1. 1. TOCTOU 竞态:容器内进程可以在 Docker Daemon 遍历文件系统时修改文件结构,使归档内容不一致。
  2. 2. 符号链接逃逸:解压代码的路径包含检查使用字符串前缀匹配,无法防御符号链接导致的路径逃逸。
  3. 3. 检查与使用不一致:验证逻辑检查的路径与实际创建文件时使用的路径不匹配,使得安全检查形同虚设。

修复建议:

  • • 立即升级到 Docker Engine/CLI 29.7.2+、Docker Desktop 4.86.0+、Docker Sandboxes 0.38.0+。
  • • 过渡期避免从运行中容器执行 docker cp,先 docker stop 再复制。
  • • 绝不以 root 权限运行 docker cp,尤其是自动化脚本中。
  • • CI/CD 流水线中同步更新 Docker 镜像版本号。
  • • AI Agent 工作流中从不受信任沙箱提取文件时使用隔离环境。

核心教训:归档解压是一个安全边界,路径包含检查必须由内核保证而非字符串比较。这个教训不仅适用于 Docker,也适用于所有需要处理来自不受信任来源的归档文件的工具。


本文作者:WAKE UP技术

参考来源:Imperva Red Team 技术报告、奇安信 CERT 安全通告、moby/go-archive 源码


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。

本文转载自:WAKE UP技术 WAKEUP技术 WAKEUP技术《【高危漏洞预警】Docker cp 容器到主机任意文件写入漏洞(CVE-2026-17106)深度剖析》

评论:0   参与:  0