A container hands you a gift-wrapped tarball, but the ribbon is a symlink that redirects the present onto your nightstand
CVE-2026-17106, dubbed CopyEscape, is a path-traversal and TOCTOU race condition in Docker's docker cp (and sbx cp) archive pipeline. When copying files from a container to the host, the Docker daemon walks the container filesystem, tars it up, and streams it to the CLI for local extraction. A malicious container can race the daemon's directory walk — swapping a directory for an absolute symlink between the WalkDir stat and the Lstat tar-header creation — causing the archive to contain a symlink entry followed by child entries that, upon extraction, land *outside* the user-chosen destination. The CLI's path-validation uses a lexical string check on a *constructed* path but then hands the *original, attacker-controlled* hdr.Linkname to os.Symlink, so the kernel resolves it to an arbitrary host location. Affected: Docker Engine/CLI < 29.7.2, Docker Desktop < 4.86.0, Docker Sandboxes < 0.38.0 (library root: moby/go-archive < 0.3.0). The container must be running for the race to fire.
The GitHub Security Advisory (GHSA-hfg8-hc9c-6c3h) rates this High / CVSS 4.0 7.1, which is honest. The attack *does* require user interaction — someone or something must invoke docker cp against a live, attacker-controlled container — and it *does* require winning a race. But Imperva's PoC shows the race is reliable: you plant a large file before the pivot directory, monitor inotify, and trigger the swap deterministically. On Linux with sudo docker cp the chain ends at root-level arbitrary file write (demonstrated by replacing /usr/bin/runc). On macOS developer boxes it drops LaunchAgent persistence. On CI/CD runners that extract build artifacts via docker cp, it's a supply-chain pivot. The 7.1 score captures the technical friction; it undersells the blast radius on high-value hosts.
5 steps from start to impact.
Attacker controls a container
LD_PRELOAD shim that monitors filesystem events and performs the symlink swap on cue. In CI/CD pipelines that pull third-party images for build/test steps, this is the natural entry point.- Attacker can publish or push an image to a registry consumed by the target
- OR attacker has code execution inside an existing container
- Enterprise registries with image-signing (Docker Content Trust, Sigstore/cosign) block unsigned images
- Private registries with allowlisting reduce exposure to arbitrary public images
Victim invokes docker cp on the live container
docker cp <container>:/path /host/dest while the container is running. The daemon begins its filepath.WalkDir traversal of the container filesystem. The attacker's shim inside the container watches for the walk to reach the decoy directory via inotify / fanotify events.- Target host runs an unpatched Docker Engine/CLI < 29.7.2
- The
docker cpcommand targets a path under attacker control inside the container - Container is running (stopped containers block the race)
- Many production workflows use
kubectl cp(different code path, not affected) rather than rawdocker cp - Some organizations never use
docker cpat all — volume mounts ordocker build --outputare alternatives
auditd on Linux, Endpoint Security Framework on macOS) can capture docker cp invocations. No commercial scanner specifically flags this pattern yet.Race condition swaps directory for symlink
WalkDir (which records the path as a directory) and the subsequent Lstat (which reads it again for tar metadata), the in-container shim replaces the directory with an absolute symlink pointing to a host-sensitive path like /usr/bin, ~/.ssh, or ~/Library/LaunchAgents. The resulting tar archive now contains a symlink header followed by child entries that the CLI will extract *through* that symlink.- Container process has write access to the directory being copied
- Timing window is reachable (Imperva demonstrated reliable wins using a large preceding file to widen the window)
- Read-only container filesystems (
--read-only) prevent the swap entirely - Minimal base images (distroless, scratch) may lack the tooling to run the shim
CLI extracts through the symlink — arbitrary host file write
os.Symlink with the *original, unmodified* hdr.Linkname — an absolute path like /usr/bin. Subsequent child entries in the archive are written through the now-resolved symlink, landing outside the intended destination. The files are written with the permissions of the user running docker cp.- User running
docker cphas write permission to the symlink target on the host
- Non-root
docker cplimits writes to the invoking user's writable paths - SELinux / AppArmor with strict Docker profiles may deny writes to sensitive host paths
file_events) on critical host paths would detect unexpected writes post-exploitation.Code execution on the host
/usr/bin/runc yields root the next time Docker invokes it; overwriting ~/.bashrc or ~/.zshrc yields user-level execution on next shell; dropping a LaunchAgent plist on macOS yields persistent user-level execution. On a CI runner, overwriting build scripts or injecting into artifact output directories yields supply-chain compromise.- Overwritten file is eventually executed by the host OS or a host process
- Immutable infrastructure (ephemeral CI runners rebuilt per job) limits persistence
- Runtime protection (Falco, Sysdig) can alert on unexpected process execution from overwritten binaries
The supporting signals.
| In-the-Wild Exploitation | No confirmed in-the-wild exploitation. Not KEV-listed as of 2026-08-12. No campaigns attributed. |
|---|---|
| Proof-of-Concept | Detailed technical PoC published by Ron Masas (Imperva Red Team) in the CopyEscape blog post. Demonstrates reliable race-condition win via inotify + large-file timing trick. No standalone public exploit repo found yet, but the writeup is weaponization-grade. |
| EPSS | Not yet scored by FIRST (CVE published August 2026). Expect moderate EPSS given the user-interaction requirement. |
| KEV Status | Not listed in CISA KEV catalog. |
| CVSS Vector | GHSA-published CVSS 4.0: 7.1 — CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N. Local attack vector, requires user action and attack prerequisites (race condition), but all three CIA impacts are High. |
| Affected Versions | Docker Engine/CLI < 29.7.2, Docker Desktop < 4.86.0, Docker Sandboxes < 0.38.0, moby/go-archive < 0.3.0 |
| Fixed Versions | Docker Engine/CLI 29.7.2 (Aug 6, 2026), Docker Desktop 4.86.0 (Aug 10, 2026), Sandboxes 0.38.0 (Aug 6, 2026), moby/go-archive 0.3.0 |
| Scanning / Exposure | Docker holds ~86% containerization market share per 6sense; 92% of IT professionals use Docker per 2026 surveys. docker cp usage is concentrated in dev/test and CI/CD rather than production Kubernetes workloads. |
| Disclosure Timeline | Reported 2026-04-11 → Docker ACK 2026-04-15 → 90-day deadline 2026-07-10 → CVE assigned 2026-07-24 → initial fix (with regressions) 2026-07-30 → final patches 2026-08-06 to 08-10 |
| Researcher / Org | Ron Masas, Imperva Red Team. Previously disclosed CVE-2025-62725 (Docker Compose arbitrary file write, CVSS 8.9). |
noisgate verdict.
The single most decisive factor is the supply-chain pivot via CI/CD build runners — any CI pipeline that runs docker cp against an untrusted container image grants an attacker arbitrary file write on the build host, which is a high-value-role outcome that floors this verdict at HIGH despite the user-interaction and race-condition friction.
Why this verdict
- User interaction is real friction: The attack requires someone or something to run
docker cpagainst a live, attacker-controlled container — this is not a listen-and-exploit network vuln. This caps the score below CRITICAL for most deployment roles. - Race condition is reliable but not free: Imperva's PoC demonstrates a deterministic win using
inotify+ large-file timing, but it still requires the container to be running and the attacker to have planted the shim. Read-only containers (--read-only) kill the chain entirely. - Role multiplier — CI/CD build runners: CI pipelines routinely pull third-party images and extract artifacts with
docker cp. A malicious image in this context achieves arbitrary file write on the build host → build artifact poisoning → supply-chain compromise. CI runners are in the high-value role catalog. This floors the verdict at HIGH. - Role multiplier — AI-agent sandboxes: Docker Sandboxes (
sbx cp) are explicitly affected. AI-agent workflows that copy files between sandbox and host are a growing attack surface with weak trust boundaries. - Developer workstations are medium-value: Overwriting
~/.bashrc,~/.ssh/authorized_keys, or LaunchAgent plists yields persistent access to a developer's machine — valuable for lateral movement but not fleet-scale.
Why not higher?
CRITICAL would require either unauthenticated remote exploitation or a canonical high-value-role component where ≥10% of installs are the high-value role *by definition*. Docker Engine is broadly deployed, but docker cp usage against untrusted containers is a subset behavior, not the default operating mode. The mandatory user interaction (UI:A) and attack prerequisites (AT:P) mean this cannot be triggered by a drive-by network scan. No in-the-wild exploitation or KEV listing further argues against CRITICAL.
Why not lower?
MEDIUM would ignore the CI/CD and AI-sandbox blast radius. In environments where docker cp is wired into automated pipelines pulling external images, the chain is essentially automated — the 'user interaction' is a cron job, not a human clicking. The Imperva writeup provides weaponization-grade detail, and Docker's 86% market share means the affected population is enormous. The floor rule for supply-chain-pivot outcomes on CI/CD infrastructure keeps this at HIGH.
What to do — in priority order.
- Stop containers before copying files — The TOCTOU race requires a running container to swap the directory for a symlink. Running
docker stop <cid> && docker cp <cid>:/path /desteliminates the race entirely. Deploy this as a wrapper or CI pipeline policy within the noisgate mitigation SLA of 30 days. - Use
--read-onlyfor untrusted containers — A read-only root filesystem (docker run --read-only) prevents the in-container shim from replacing directories with symlinks. Apply to all CI job containers and sandbox workloads. - Drop
sudofromdocker cpinvocations — Runningdocker cpas a non-root user limits the file-write blast radius to user-writable paths, preventing the demonstrated/usr/bin/runcoverwrite that yields root. Audit CI runner configurations forsudo dockerusage. - Enforce image signing and registry allowlisting — Docker Content Trust or cosign/Sigstore verification prevents unsigned or untrusted images from being pulled into CI pipelines, blocking the primary supply-chain entry vector.
- Enable file-integrity monitoring on CI runners — Deploy AIDE, osquery
file_events, or equivalent FIM on build hosts to detect unexpected writes to system binaries, shell configs, and build artifact directories. This provides detection-in-depth while patching is rolled out.
- Network segmentation / firewall rules — the attack is entirely local between the Docker CLI and a container on the same host; no network traffic is involved.
- Container image scanning (Trivy, Grype, Docker Scout) — the malicious payload is runtime behavior (an
LD_PRELOADshim orinotifywatcher), not a known vulnerable dependency in an image layer. Scanners will not flag this. - seccomp default profile — Docker's default seccomp profile allows
inotify_init,inotify_add_watch,symlink, andrename, which are all the syscalls needed for the exploit. A custom restrictive profile *could* help but the default does not. - AppArmor docker-default profile — the default profile restricts mount and ptrace but does not prevent symlink creation or directory manipulation within the container's own filesystem.
Crowdsourced verification payload.
Run this on any host where Docker Engine/CLI is installed. Execute as the user who normally runs docker commands. Example: bash check_copyescape.sh
#!/usr/bin/env bash
# check_copyescape.sh — Detect CVE-2026-17106 (CopyEscape) exposure
# Run on any Docker host. No elevated privileges required.
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
PATCHED_ENGINE="29.7.2"
PATCHED_DESKTOP="4.86.0"
version_gte() {
# Returns 0 if $1 >= $2 using sort -V
[ "$(printf '%s\n%s' "$1" "$2" | sort -V | head -n1)" = "$2" ]
}
# --- Check Docker CLI/Engine version ---
if ! command -v docker &>/dev/null; then
echo "UNKNOWN — docker command not found on this host."
exit 2
fi
RAW_VERSION=$(docker version --format '{{.Client.Version}}' 2>/dev/null || true)
if [ -z "$RAW_VERSION" ]; then
echo "UNKNOWN — could not determine Docker CLI version."
exit 2
fi
# Strip leading 'v' if present
CLI_VERSION="${RAW_VERSION#v}"
echo "Detected Docker CLI version: $CLI_VERSION"
echo "Patched version: >= $PATCHED_ENGINE"
if version_gte "$CLI_VERSION" "$PATCHED_ENGINE"; then
echo "PATCHED — Docker CLI $CLI_VERSION is >= $PATCHED_ENGINE. CVE-2026-17106 is fixed."
exit 0
else
echo "VULNERABLE — Docker CLI $CLI_VERSION is below $PATCHED_ENGINE. CVE-2026-17106 applies."
echo "Upgrade Docker Engine/CLI to >= $PATCHED_ENGINE or Docker Desktop to >= $PATCHED_DESKTOP."
exit 1
fiIf you remember one thing.
docker cp or sbx cp against third-party or untrusted container images — these are your highest-blast-radius targets. Per the noisgate mitigation SLA for HIGH, deploy compensating controls (stop containers before copy, enforce --read-only, drop sudo) within 30 days. Per the noisgate remediation SLA, upgrade Docker Engine/CLI to 29.7.2+ and Docker Desktop to 4.86.0+ across your fleet within 180 days. Given the fresh public PoC details, front-load CI/CD and developer workstation patching into your next maintenance window — ideally this week. Audit your pipelines for any docker cp usage against live, untrusted containers and eliminate it immediately as a zero-cost compensating control.Sources
- Imperva — CopyEscape: Taking Over Docker Hosts with docker cp
- GHSA-hfg8-hc9c-6c3h — moby/go-archive Advisory
- GBHackers — Docker CopyEscape Vulnerability
- CyberSecurity News — CopyEscape Docker Vulnerability
- Moby/Moby Releases (v29.7.2)
- Docker CLI PR #7139 — go-archive v0.3.0 vendor update
- NHS England — Docker Security Updates for Copy Functionality
- CyberPress — CopyEscape Docker Flaw
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.