get nodes/proxy
Lets an attacker execute commands in any pod on the node.
WebSocket exec handshakes over HTTP GET map to the get verb, so get alone on nodes/proxy bypasses pods/exec and the audit log.
Proxies to the kubelet API on port 10250.
Combined with create on nodes, it also drives fake-Node SSRF, making the API server proxy back to itself.
What that returns depends on how the cluster binds the apiserver-kubelet-client certificate.
- API Group
- (core)
- Scope
- cluster
- Audit Level
- RequestResponse
Escalation Paths
Connect to the exec endpoint via WebSocket.
The HTTP GET upgrade handshake maps to the 'get' verb at the kubelet, so get nodes/proxy alone is sufficient
The kubelet never performs a secondary 'create' check for the exec operation that follows the handshake
Path A, via API server proxy, uses curl with Upgrade: websocket headers.
Auth is logged as a nodes/proxy check only, the actual exec is invisible to audit
Path B is direct to the kubelet on port 10250, using websocat wss://$NODE_IP:10250/exec/....
Zero API server audit events are generated
Execute arbitrary commands in any pod on the node, and steal service account tokens to pivot
Additional rights needed:
Note:
There is no CVE.
The security team calls this working as intended (Jan 2026).
CVE-2020-8559 and CVE-2022-3294 are separate patched issues.
WebSocket exec bypass has no fix.
KEP-2862 adds narrower subresources but does not cover exec/attach/portforward.
Register a fake Node object with status.addresses[InternalIP] = API server internal IP and daemonEndpoints.kubeletEndpoint.Port = 6443
Proxy a request through the fake node by running kubectl get --raw /api/v1/nodes/evil-node/proxy/api/v1/secrets
The API server proxies outbound to that address using its apiserver-kubelet-client certificate, so it authenticates to itself
Before kubeadm 1.29 the certificate carried O=system:masters.
From 1.29 it carried O=kubeadm:cluster-admins, a group bound to cluster-admin, so the inner request still returned full cluster access
Current kubeadm binds the certificate to system:kubelet-api-admin instead, narrowing the inner request to the node API (nodes/proxy, metrics, stats, log) rather than cluster-admin
The redirection itself is unchanged by that fix, so the API server can still be pointed at an attacker-chosen address
Post-fix, the gain is network position rather than RBAC, since triggering it already requires get on nodes/proxy.
The API server reaches addresses the caller cannot, under its own identity
Additional rights needed:
· both; the Node object is inert until proxied to
Note:
Those releases narrow the certificate to system:kubelet-api-admin, which removes the cluster-admin outcome but not the redirection.
kubernetes#119270 is still open, reopened for audit re-evaluation.
1.32 reached end of life first, so it stays vulnerable.
No CVE covers this path.
Register a fake Node with a DNS rebinding hostname that initially resolves to a valid public IP
API server checks isProxyableHost before connecting.
At check time, DNS resolves to the allowed IP
By connect time, DNS flips to 127.0.0.1 or 169.254.x.x.
The blocklist check is not re-run (TOCTOU)
SSRF reaches loopback services such as kube-proxy :10249 configz, etcd :2379, and control-plane localhost ports
Additional rights needed:
· both; registering the address and proxying to it
Note:
This is a wontFix.
Fixing requires IP pinning between check and connect, which breaks split-horizon DNS.
Mitigation is dnsmasq min-cache-ttl.
