Skip to content

Back to the catalog

Observing Privilege Escalation in Kubernetes (EKS CloudWatch Observability Add-on)
labs.reversec.comwriteup

Observing Privilege Escalation in Kubernetes (EKS CloudWatch Observability Add-on)

Reversec details a privilege escalation vulnerability in AWS EKS's CloudWatch Observability Add-on: the cloudwatch-agent service account, deployed via DaemonSet to every node, had cluster-wide permission to update ConfigMaps, allowing any attacker who compromised a node (e.g. via a privileged pod with hostPath access) to steal the agent's service account token, rewrite the aws-auth ConfigMap, and grant themselves cluster-admin via system:masters. The flaw existed in the default, unmodified add-on configuration (no misconfig required) and was found in two separate client engagements; AWS acknowledged it and shipped a fix in add-on v5.3.0-eksbuild.1 that scopes the update-ConfigMap permission to a namespaced role, though a related privilege-escalation path via the nodes/proxy permission (disclosed separately by Graham Helton) remains unaddressed until Kubernetes 1.36's fine-grained Kubelet authorization lands in EKS.

TL;DR Default EKS CloudWatch Observability Add-on let a node-compromised attacker steal the cloudwatch-agent service account token and rewrite aws-auth to grant themselves cluster-admin — root cause was an over-privileged cluster-wide ConfigMap-update permission, now fixed in add-on v5.3.0+.
Document

What it is

The CloudWatch Observability Add-on's cloudwatch-agent service account (shared by the cloudwatch-agent and fluent-bit DaemonSets, present on every node) held a cluster-scoped update permission on ConfigMaps in add-on versions through v4.10.1-eksbuild.1 and earlier, tested by Reversec against Kubernetes v1.35.

How it works

flowchart TD
    A[Attacker deploys privileged pod with hostPath mount] --> B[Reads /var/lib/kubelet/pods on host]
    B --> C[Extracts cloudwatch-agent SA token from another pod's volume]
    C --> D[kubectl edit fails: no 'patch' perm]
    D --> E[kubectl edit still writes local YAML copy]
    E --> F[kubectl replace succeeds: 'update' perm is sufficient]
    F --> G[aws-auth ConfigMap rewritten: user added to system:masters]
    G --> H[Cluster-admin]

kubectl edit fails because it uses patch, but it still writes the proposed manifest locally; kubectl replace -f against that file uses update, which the service account does have — so the missing patch permission is not a real barrier. A second, separate escalation path exists via the get permission on nodes/proxy, which (per a blog post by Graham Helton, referenced but not detailed here) allows code execution on pods via the kubelet API; this is unrelated to the ConfigMap issue and was not fixed by AWS's patch.

Preconditions / Affected

  • EKS cluster using "EKS API and ConfigMap" authentication mode (ConfigMap-mode clusters only — pure EKS API/access-entry mode is not affected since access entries override the ConfigMap).
  • CloudWatch Observability Add-on in default configuration, version ≤ v5.2.x (confirmed vulnerable at v4.10.1-eksbuild.1).
  • Attacker needs node-level access, e.g. via a privileged pod with hostPath access to /var/lib/kubelet/pods to read other pods' service-account tokens.

What to do

  • Upgrade the add-on to v5.3.0-eksbuild.1 or later: this version introduces a new namespaced cloudwatch-agent-role in the amazon-cloudwatch namespace holding the ConfigMap update permission, and removes that permission from the cluster-wide role — closing the aws-auth escalation path specifically.
  • This upgrade does not touch the nodes/proxy permission; that escalation path remains open on all current versions and is tracked separately against Kubernetes 1.36's "fine-grained Kubelet authorization," which went GA in that release per the author's post-talk update. EKS was still capped at Kubernetes v1.35 as of 3 June 2026, so no EKS-side fix was available at time of writing.
  • Where migration to EKS API/access-entry auth isn't possible, mitigate via Pod Security Standards restricting privileged/hostPath pods, and audit third-party add-on service-account permissions directly (the author recommends IceKube for mapping escalation paths).

Caveats

Reversec could not confirm whether a fully namespaced role (no cluster role at all) is viable for the agent — EKS's managed add-on update process repeatedly auto-restored the cluster role during testing, so the namespacing fix's completeness is AWS's implementation, not independently verified by the author. The nodes/proxy mitigation (restricting kubelet port traffic) is noted as unverified and potentially disruptive.

Organisations named here

  • fwd:cloudsec
  • Graham Helton
  • nodes/proxy vulnerability

Technologies named here

  • kubectl
  • Amazon EKS
  • Amazon CloudWatch Observability Add-on
  • AWS CLI
  • Kubernetes
  • IceKube
  • aws-auth ConfigMap
  • AWS IAM Authenticator
  • cloudwatch-agent service account/DaemonSet
  • AWS
  • AWS IAM
  • Amazon CloudWatch

Techniques named here

  • kubectl edit/replace workaround for missing patch permission
  • nodes/proxy permission abuse for code execution