Docker — CopyEscape: Container-to-Host Escape via docker cp Race Condition (CVE-2026-17106)
Published: 2026-08-15 • Researcher: masasron (Imperva Red Team)
- Severity
- Critical
- CVE
- CVE-2026-17106
- Category
- binary
- Affected product
- Docker Engine / Docker Desktop, docker cp CLI command
- Affected versions
- Docker Engine/CLI 29.6.1, Docker Desktop 4.81.0, and earlier (prior to the security fix)
- Disclosed
- 2026-08-15
- Patch status
- Unverified
Tags
References
Archive entry
intelseclab/poc-archiveOn this page
Metadata
| Field | Value |
|---|---|
| Date Added | 2026-08-15 |
| Last Updated | 2026-08-15 |
| Author / Researcher | masasron (Imperva Red Team) |
| CVE / Advisory | CVE-2026-17106 |
| Category | binary |
| Severity | Critical |
| CVSS Score | 9.8 (estimated, container escape to host RCE) |
| Status | Patched |
| Tags | docker, container-escape, race-condition, symlink, path-traversal, runc, host-takeover, linux, macos, CWE-367, CWE-59, CVE-2026-17106 |
| Related |
Affected Target
| Field | Value |
|---|---|
| Software / System | Docker Engine / Docker Desktop, docker cp CLI command |
| Versions Affected | Docker Engine/CLI 29.6.1, Docker Desktop 4.81.0, and earlier (prior to the security fix) |
| Language / Platform | C (inotify monitor + LD_PRELOAD shim), shell scripts; targets Linux and macOS Docker hosts |
| Authentication Required | Requires a running malicious container and a user who runs docker cp against it |
| Network Access Required | Local – the attacker controls a container on the target Docker host |
Summary
CVE-2026-17106, nicknamed CopyEscape, is a race condition in Docker’s docker cp command that allows a malicious running container to escape and write arbitrary files on the Docker host. The vulnerability exists in how Docker’s archive producer walks the container filesystem: a race window allows the container to replace a directory with an absolute symlink between the time Docker reads the directory listing and the time it archives the contents. The resulting tar stream contains the symlink followed by child entries beneath it; the vulnerable Docker CLI extracts the symlink and then follows it, writing attacker-controlled content to arbitrary host paths.
The Linux PoC demonstrates overwriting /usr/bin/runc with a malicious script that creates /imperva_red_team when executed – achieving persistent host-level code execution. The macOS PoC demonstrates a non-destructive write to ~/pwnd.
Vulnerability Details
Root Cause
Docker’s docker cp command archives files from a running container by walking the container’s filesystem. The archive producer performs a directory listing, then reads file contents based on that listing. A TOCTOU (time-of-check-to-time-of-use) race exists between these two steps:
- Check: Docker reads
/watched/file.txtas a directory and begins archiving its children. - Use: The container replaces the directory with an absolute symlink pointing to a host path (e.g.,
/usr/bin). - Extract: The CLI extracts the symlink, then extracts child entries through it onto the host filesystem.
The exploit uses two mechanisms to win the race:
- An
inotifymonitor watches for Docker’s access to a trigger file (aaa.txt) inside the directory, then atomically pivots the directory to a symlink. - An
LD_PRELOADshim interceptsopen/stat/lstatto make processes inside the container see/watched/file.txtas a regular file, while the Docker daemon sees the underlying directory structure.
Impact
- Host filesystem write: Arbitrary file creation/overwrite with the permissions of the
docker cpcaller (typically root). - Container escape: Overwriting
/usr/bin/runcgives the attacker code execution on the host as root on any subsequent container operation. - Persistence: The replaced
runcexecutes on every Docker container lifecycle event.
Environment / Lab Setup
| |
Setup Steps
| |
Proof of Concept
See
linux/monitor.c(233 lines, C),linux/watched_preload.c(90 lines, C),macos/monitor.c,macos/watched_preload.c, and shell scripts in this folder – mirrored byte-for-byte from masasron/CopyEscape-CVE-2026-17106. The upstream README is preserved asupstream-README.md.
Step-by-Step Reproduction (Linux)
- Build the image:
docker build -t copyescape-linux linux/ - Start the container:
docker run --name copyescape-linux copyescape-linux - Verify file appears normal:
docker exec copyescape-linux cat /watched/file.txtoutputs “top-level file” - Trigger:
docker cp copyescape-linux:/watched/file.txt ./file.txt - Verify:
sed -n '1,3p' /usr/bin/runcshows the PoC shell script;ls -l /imperva_red_teamconfirms host write. - Restore:
cp --preserve=all /root/runc.copyescape-backup /usr/bin/runc
Exploit Code
The inotify monitor – watches for Docker’s file access, then pivots directory to symlink:
| |
The LD_PRELOAD shim – makes container processes see a regular file:
| |
Expected Output
pivoted /watched/file.txt/escape -> /usr/bin
copy activity went quiet, exitingAfter trigger, /usr/bin/runc contains the PoC payload and /imperva_red_team exists.
Detection and Indicators of Compromise
Remediation
| Action | Detail |
|---|---|
| Patch | Update Docker Engine/CLI and Docker Desktop to the version that fixes CVE-2026-17106. The fix rejects malicious archive streams or completes the copy without following symlinks outside the destination. |
| Workaround | Avoid using docker cp to copy files out of untrusted containers. Use volume mounts or docker exec with output redirection instead. |
| Verification | After patching, run the macOS PoC – ~/pwnd should not be created. |
References
Notes
Verified this session by reading all source files: linux/monitor.c (233 lines), linux/watched_preload.c (90 lines), macos/monitor.c, macos/watched_preload.c, linux/entrypoint.sh, macos/entrypoint.sh, macos/demo-macos.sh, and Dockerfiles.
Malware screen – clean. The monitor uses standard POSIX inotify for filesystem event detection and rename() for the atomic symlink pivot. The LD_PRELOAD shim uses standard dlsym(RTLD_NEXT, ...) interposition with no obfuscation. Shell scripts are straightforward Docker build/run/cp orchestration. No remote downloaders, no credential exfiltration, no miners, no persistence beyond the demonstrated runc overwrite. No committed binaries.
Author: masasron is credited as Imperva Red Team. The repo has 15 stars, includes both Linux and macOS demonstrations, and a detailed blog post link.