CopyEscape (CVE-2026-17106): How docker cp Can Hand Your Host to an Attacker

The One Command That Owns Your Host
docker cp container:/app/logs ./logs
This command is run thousands of times a day in CI pipelines, developer workstations, and incident response workflows. You run it to extract build artifacts, copy test results, or grab forensic evidence from a container. The container's files land on your host. What could go wrong?
CVE-2026-17106 - nicknamed CopyEscape by Imperva researcher Ron Masas - answers that question. A container you run docker cp on can overwrite any file writable by your user on the host. Shell configuration, SSH authorized_keys, cron jobs, the runc binary - if you can write to it, the container can overwrite it.
How It Works
docker cp is not a direct filesystem copy. The flow works like this:
┌─────────────┐ tar archive ┌──────────────┐
│ Container │──────────────────► │ Docker CLI │
│ (attacker │ (over stdin/stdout)│ (host user) │
│ controlled)│ │ writes files │
└─────────────┘ └──────┬─────────┘
│
┌─────▼──────┐
│ Host FS │
│ e.g. /root │
└────────────┘
- The Docker daemon walks the container's live filesystem
- The daemon serializes the requested path into a tar archive
- The CLI receives the tar stream and extracts it to the destination directory
The container controls step 1. The CLI, running with the host user's permissions, executes step 3. The vulnerability exploits the gap between them.
The Two-Weakness Chain
Weakness 1: TOCTOU Race (Time-of-Check to Time-of-Use)
Docker's archive pipeline reads the container's filesystem, but not atomically. Between the time Docker reads a directory entry and the time it opens the file, the container can swap what lives at that path. A regular file becomes a symlink. The archive includes the symlink instead of the file content. This is the classic TOCTOU race - Docker checks the file, but what it uses has changed.
Weakness 2: Symlink Follow on Extraction
The Docker CLI, when extracting the tar archive on the host, follows symlinks that point outside the destination directory. If the container planted a symlink to /etc/cron.d/, the CLI happily writes files there.
Combined: the container races to replace a file with a symlink to /root/.ssh/authorized_keys during the tar creation. The CLI receives the symlink, follows it, and writes the container's attacker-controlled content to the host's authorized_keys file. SSH access gained.
Two Outcomes, Both Bad
1. Host File Overwrite
The attacker can create or overwrite any file writable by the user running docker cp:
| Target File | Effect |
|---|---|
~/.ssh/authorized_keys |
Add attacker's SSH key, persistent access |
~/.bashrc / ~/.zshrc |
Code execution on next shell open |
/etc/cron.d/backdoor |
Scheduled task execution |
~/.gitconfig |
Credential redirection |
| Source code repos | Supply chain injection |
| CI workspace | Pipeline compromise |
2. Code Execution
On macOS, docker cp runs with the user's full permissions - the attacker's payload executes as the logged-in user immediately after the copy completes.
On Linux, if docker cp is run as root (common in CI, automation, and privileged workstations), the attacker can overwrite system binaries. Overwriting runc - the low-level container runtime - is particularly devastating: the attacker replaces runc with their own binary, and every subsequent container launch executes attacker code as root.
Where This Hits Hardest
CI/CD pipelines are the primary target. A build step runs a container, the pipeline copies out test results or build artifacts via docker cp, and the attacker writes to the CI workspace. From there: exfiltrate secrets, inject into the next build stage, or compromise deployment artifacts.
Developer workstations are the second target. A developer clones a repo, runs a container that looks legitimate (a build environment, a database with test data), runs docker cp to grab a config file, and their ~/.ssh/authorized_keys now contains an attacker's key.
Incident response is the third. You pull a compromised container to a forensics workstation to extract logs and evidence. Running docker cp on that container is exactly the wrong thing to do - you are handing the attacker a path to your forensics machine.
Mitigations
Patch Docker
Docker patched CVE-2026-17106 in Docker Engine 27.5.0 and Docker Desktop 4.39.0. Update immediately:
# Linux
apt-get update && apt-get install -y docker-ce=5:27.5.0-1~ubuntu.24.04~noble
# Verify
docker version --format '{{.Server.Version}}'
# Must show 27.5.0 or higher
# macOS: Docker Desktop → Check for Updates
Pre-Patch Workarounds
If you cannot patch immediately, never run docker cp on untrusted containers. Instead, use a disposable VM or a hardened sandbox:
# Instead of docker cp, use a read-only bind mount + docker export
docker export container_name | tar -x -C /safe/destination/
# Or use a temporary read-only container
docker run --rm -v /safe/destination:/out:ro alpine \
sh -c "docker cp container:/path /tmp && cp -r /tmp/* /out/"
Neither is a full fix. The bind mount approach only works if you trust the container enough to mount its filesystem. The export approach avoids the TOCTOU race by taking a snapshot, but it is slower and more complex.
Harden Your Docker Host
CVE-2026-17106 is one of many container escape vectors. Defense in depth:
# Run docker cp as an unprivileged user, never as root
useradd -m -s /bin/bash dockeruser
usermod -aG docker dockeruser
su - dockeruser
# Use user namespaces (root in container ≠ root on host)
# In /etc/docker/daemon.json:
{
"userns-remap": "default"
}
# Never run docker cp on containers from untrusted sources
# If you must: use a dedicated VM or ephemeral cloud instance
How ServerGurus Protects Customers
All ServerGurus-managed Docker hosts patched to Docker 27.5.0 within 24 hours of the CVE release. For CI customers, we added a pre-pipeline check that verifies Docker Engine version and blocks any pipeline running an unpatched version.
For self-managed customers, we deployed detection rules that alert on:
docker cpcommands run against containers from public registries without verified signatures- File writes to
~/.ssh/,/etc/cron.d/, or/usr/bin/runcoriginating from Docker processes - Symlink creation in
/var/lib/docker/overlay2/followed bydocker cpon the same container within 5 seconds
The Bigger Lesson
docker cp is not a safe operation. It bridges two security domains - the container and the host filesystem - with the host user's full write permissions. For 11 years, the assumption was that the tar extraction was safe because Docker controlled the archive creation. But Docker doesn't control the container's filesystem. The container does. And the container can lie.
The fix is not to stop using docker cp. The fix is to recognize that every docker cp command is a trust operation. If you would not run curl | bash from the container, do not run docker cp on it either.