Safeguard
Cloud Security•

Audit who can write StatefulSets and ControllerRevisions in Kubernetes

CVE-2026-2270 turns namespace-scoped write access into a pod in another namespace. Use it as the reason to run a real RBAC audit with kubectl and jq.

Safeguard Security Team
6 min read

On 23 September 2026 the Kubernetes Security Response Committee closed the tracking issue for CVE-2026-2270 and labeled it for the official CVE feed. The flaw is a confused deputy in the StatefulSet controller: a user with namespace-scoped write permission on both StatefulSet and ControllerRevision objects can make the controller create a pod in a different namespace, with metadata and spec the attacker controls. It is rated Medium (CVSS 3.1 score 5.9), and it is a good excuse to audit a part of RBAC that most teams never look at.

What's affected

The vulnerable component is kube-controller-manager. The issue lists these affected versions and the fixed releases:

  • 1.34: up to and including v1.34.11, fixed in v1.34.12
  • 1.35: up to and including v1.35.8, fixed in v1.35.9
  • 1.36: up to and including v1.36.4, fixed in v1.36.5
  • 1.37: v1.37.0 only, fixed in v1.37.1

The fix changes the controller so that only the spec field of a StatefulSet is restored from a ControllerRevision. The advisory text adds a limit on the attack: the injected pod is deleted by the garbage collector unless the attacker can build a valid StatefulSet OwnerReference, which needs the UID of an existing StatefulSet in the victim namespace. That raises the bar, but it is not a reason to wait. The issue was reported by ImanOracle.

How to check if you're exposed

First, the version. On a self-managed cluster, read the control plane image tag. On a managed service, check the provider's published patched version for your minor release.

kubectl version
kubectl -n kube-system get pods -l component=kube-controller-manager \
  -o jsonpath='{.items[*].spec.containers[*].image}'

Second, who can write both resource types. The Kubernetes docs describe kubectl auth can-i with impersonation for exactly this. This loop checks every service account in every namespace (you need permission to impersonate):

for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
  for sa in $(kubectl get sa -n "$ns" -o jsonpath='{.items[*].metadata.name}'); do
    who="system:serviceaccount:$ns:$sa"
    s=$(kubectl auth can-i create statefulsets.apps -n "$ns" --as="$who")
    c=$(kubectl auth can-i update controllerrevisions.apps -n "$ns" --as="$who")
    if [ "$s" = "yes" ] && [ "$c" = "yes" ]; then
      echo "$ns/$sa can write both"
    fi
  done
done

Repeat with the as flag for human users and the as-group flag for the groups your identity provider maps in. Built-in aggregated roles such as edit are worth testing this way rather than assuming what they include.

Third, find wildcards. The RBAC docs warn that wildcards in resources and verbs can grant access you did not intend, including for resources added later:

kubectl get clusterroles,roles -A -o json | jq -r '
  .items[]
  | select(any(.rules[]?;
      ((.verbs // []) | index("*")) or ((.resources // []) | index("*"))))
  | "\(.kind) \(.metadata.namespace // "cluster") \(.metadata.name)"'

Every line is a role to justify or shrink.

What to do now

  1. Upgrade kube-controller-manager to v1.34.12, v1.35.9, v1.36.5 or v1.37.1 or later. Note that v1.34 reaches end of life on 27 October 2026 per the Kubernetes releases page, so plan the minor upgrade too.
  2. Run the loop above and list every identity that can write both StatefulSets and ControllerRevisions. Most application service accounts should not.
  3. Move deploy rights to a CI identity per namespace and give humans read-only access by default, with time-boxed elevation.
  4. Replace wildcard roles with explicit verbs and resources. Use kubectl auth reconcile to apply role manifests so drift is corrected rather than accumulated.
  5. Turn on audit logging for writes to these objects so you can answer who changed what:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Metadata
    resources:
      - group: "apps"
        resources: ["controllerrevisions", "statefulsets"]
    verbs: ["create", "update", "patch", "delete"]

If you find evidence of exploitation, the issue asks you to write to security@kubernetes.io.

How this could have been avoided

  • Least privilege on workload controllers. The attack starts with write access to StatefulSets and ControllerRevisions. A role that can create pods but not ControllerRevisions never reaches the bug.
  • Patch the control plane on a schedule. The fix was backported to four release lines. Clusters on a supported minor with monthly patching were a single upgrade away.
  • Strict Pod Security in the target namespace. The forged pod is created in the victim namespace, so that namespace's Pod Security admission level still applies to it. Namespaces that enforce the restricted profile limit what a rogue pod can do.
  • Default-deny network policy. A pod that cannot open outbound connections is much less useful to an attacker, even if it starts.
  • Audit alerts on ControllerRevision writes from non-CI identities. That is the unusual event, and the audit rule above captures it.

Why it matters

Namespaces feel like a security boundary, and RBAC grants are written as if they were. This bug shows how a controller acting with its own broad rights can carry a namespace-scoped permission across that boundary. Any controller that copies data from one object into another on behalf of users has the same shape.

The practical lesson is to audit write access to every object a controller reads back. That list is short: workload controllers, their revision objects, and anything an operator reconciles from user input.

Try it yourself

Pick one namespace and run the can-i loop for its service accounts. Write down how many identities can write both objects, then remove the grant from one and run the loop again. If the count did not drop, you have found a second path, often an aggregated role or a wildcard.

Quick check

Which two object types must a user be able to write to use CVE-2026-2270?

StatefulSet and ControllerRevision objects, with namespace-scoped write permissions.

Which kube-controller-manager versions fix the issue?

v1.34.12, v1.35.9, v1.36.5 and v1.37.1 or later.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.