A single missing backslash turns a routine “copy a file from a pod” into remote code execution on Windows admin machines — here’s how it works, and how to shut it down.
TL;DR
If you run kubectl cp from a Windows machine, a malicious container can exploit a security loophole to write files anywhere on your computer, far beyond your intended destination directory. This happens because the built-in safety check blocks Unix-style directory escape sequences but completely overlooks the Windows-equivalent path.
By taking advantage of this vulnerability, a compromised pod can secretly drop an executable straight into your Windows workstation. The next time your machine reboots, the attacker’s code automatically executes, resulting in a full takeover of your workstation.
What is kubectl cp?
Kubernetes is the system that runs containerized applications at scale. kubectl is the command-line tool operators use to talk to a cluster. One of its most-used subcommands is kubectl cp, which copies files between your local machine and a running container.
Under the hood, kubectl cp doesn’t do anything fancy. It runs tar inside the pod to bundle up the requested files, streams that archive back to your machine, and unpacks it into your chosen destination.
The Trust Assumption That Breaks
Most people naturally assume that when they pull data out of a pod, they are the ones in charge. In reality, the pod fully controls the incoming data stream – right down to the exact filenames tucked inside the archive. If an attacker gains control of that pod through a compromised app, a malicious base image, or a supply-chain breach, they suddenly own those filenames. And as this vulnerability proves, a cleverly crafted filename can easily be turned into a weapon.
Root Cause
When kubectl unpacks the archive, it validates each entry with an isRelative() check. That function relies on a helper, stripPathShortcuts(), to remove directory-traversal sequences and confirm the path can’t escape. Here is the heart of the vulnerability:
func stripPathShortcuts(p string) string {
newPath := p
trimmed := strings.TrimPrefix(newPath, "../") // <-- POSIX only
for trimmed != newPath {
newPath = trimmed
trimmed = strings.TrimPrefix(newPath, "../") // <-- POSIX only
}
// ...
}
func isRelative(base, target localPath) bool {
relative, err := filepath.Rel(base.String(), target.String())
if err != nil { return false }
return relative == "." || relative == stripPathShortcuts(relative)
} The guard blocks “../” but is blind to “..”, and Windows happily treats “..” as “go up a directory.” The check that’s supposed to keep files inside your folder becomes a rubber stamp.
The Attack Chain, Step by Step
Here’s how the pieces fit together conceptually.
- Gain a foothold in a pod. The attacker controls a container via a compromised application, a poisoned image, or lateral movement inside the cluster.
- Rig the archive source. Since kubectl cp shells out to tar inside the pod, the attacker replaces or wraps tar so that any copy request streams back an archive of their choosing instead of the real files.
- Poison the filenames. That archive contains an entry whose name uses Windows-style backslash traversal to climb out of the destination and point at a sensitive location — for example, the user’s Startup folder.
Legitimate entry: etcpasswd
Malicious entry: etcpasswd........Users<user>AppDataRoaming
MicrosoftWindowsStart MenuProgramsStartuprun.bat - The victim runs a normal command. A user does something entirely routine, like copying a config or log file out of the pod to a local folder.
- The guards fail. kubectl’s isRelative() check doesn’t recognize the backslash traversal, so the crafted path passes validation and the file is written outside the intended folder – into Startup.
- Code runs on the next login. Anything in the Windows Startup folder executes automatically when the user next logs in or reboots. From there, the attacker has code execution on the workstation.
While targeting the Startup folder is the cleanest example, the broader danger of arbitrary file write access runs much deeper. An attacker can quietly overwrite local scripts, system configurations, or trusted binaries, turning routine developer workflows into hidden execution triggers.
Proof of Concept
Why This Matters
Workstation Compromise: The victims are typically cluster admins holding broad credentials, cloud tokens, and SSH keys. Turning a routine log pull into code execution grants an attacker instant access to high-privilege keys.
CI/CD Blast Radius: Automated Windows build nodes running kubectl cp can be hijacked by a malicious pod. Compromising the runner poisons downstream releases, escalating a workstation bug into a full supply-chain breach.
Broken Trust: Administrators view kubectl as a safe, essential tool. Exploiting the gap between expected behavior and arbitrary file writes allows attacks to hide in plain sight during normal ops.
Am I Affected?
You are potentially exposed if all of the following are true:
- You run
kubectl cpfrom a Windows client - You copy files out of pods that could be attacker-influenced (untrusted images, multi-tenant clusters, internet-facing workloads)
- You are running a kubectl version prior to the fixed release.
Check your client version:
kubectl version --client Upgrade to kubectl version 1.34.12, 1.35.9, or 1.36.5 and above. Any Windows CI/CD runner or admin workstation using kubectl cp should be treated as in-scope for immediate remediation.
Key Takeaways
- Pulling data from a container transfers control over file metadata to the pod. Relying on default client checks for untrusted streams leaves infrastructure open to arbitrary file writes.
- Windows admin workstations and CI/CD build nodes require immediate remediation to prevent privilege escalation and supply chain compromise through automated workflows.
- Upgrade kubectl to patched versions 1.34.12, 1.35.9, or 1.36.5.
References
- Reported issue: github.com/kubernetes/kubernetes/issues/141294
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’).
- Kubernetes Security & Disclosure: kubernetes.io/docs/reference/issues-security/security/
- https://github.com/advisories/GHSA-pw89-p422-jr5j
- https://nvd.nist.gov/vuln/detail/cve-2026-19444
