Back to Intelligence

CVE-2026-105312: Strimzi Kafka Operator Console CR RBAC Escape — Detection and Remediation Guide

SA
Security Arsenal Team
October 20, 2026
12 min read

Introduction

NVD has published CVE-2026-105312, a CVSS 9.9 (Critical) network-exploitable vulnerability affecting Strimzi, the widely deployed Kubernetes operator for Apache Kafka. This is not a memory corruption bug or a deserialization flaw buried in a rarely-used code path — it is an architectural trust failure that turns a routine, low-privilege Kubernetes permission into full cross-tenant control of the Kafka control plane.

The mechanics are brutal in their simplicity: any tenant with create permission on Console custom resources can set spec.containers.api.spec.image to an arbitrary container image. The Strimzi operator — which runs with highly privileged cluster-scoped RBAC — dutifully deploys that attacker-controlled image into a pod. That pod's ServiceAccount is bound via ClusterRoleBinding to a ClusterRole granting cluster-wide get/list/watch on all Strimzi CRDs (including KafkaUser credentials), patch on Kafka and KafkaRebalance resources, and cluster-monitoring-view. The attacker's image simply reads the projected ServiceAccount token from disk and inherits all of it.

If you run Strimzi in any multi-tenant configuration — or any configuration where CR creation rights are delegated below cluster-admin — treat this as an active exposure requiring immediate remediation. A 9.9 with network reachability and no user interaction requirement is the kind of finding that moves from disclosure to exploitation tooling quickly.

Technical Analysis

Affected Component

  • Product: Strimzi Kafka Operator (Console custom resource handling)
  • Platform: Kubernetes / OpenShift clusters running the Strimzi operator
  • CVE: CVE-2026-105312 — CVSS v3.1 score 9.9 (Critical), attack vector NETWORK, low attack complexity, low privileges required, scope changed
  • Advisory: NVD — CVE-2026-105312

How the Vulnerability Works

From a defender's perspective, the attack chain is a textbook confused deputy / privilege escalation via operator pattern abuse:

  1. Prerequisite: The attacker holds a Kubernetes identity with create (or update) permission on Console custom resources in any namespace. In many Strimzi deployments, this permission is granted to development teams or CI pipelines to self-manage Kafka UI instances — it is not treated as a privileged operation.
  2. Payload injection: The attacker submits a Console CR with spec.containers.api.spec.image pointing to an image they control (e.g., hosted on a public registry). The operator accepts this field without validation, allowlisting, or image signature enforcement.
  3. Privileged deployment: The Strimzi operator reconciles the CR and creates a Deployment using the attacker-controlled image. Critically, the resulting pod mounts the operator-managed ServiceAccount token at /var/run/secrets/kubernetes.io/serviceaccount/token.
  4. Token theft: Attacker code in the container reads the projected token. No exploit code is needed — cat /var/run/secrets/kubernetes.io/serviceaccount/token is the entire payload.
  5. Control-plane compromise: That token is bound (via ClusterRoleBinding) to a ClusterRole granting:
    • Cluster-wide get/list/watch on all Strimzi CRDs — including KafkaUser resources, which encode Kafka authentication material (SCRAM credentials, TLS client certs). This is cross-tenant credential access.
    • Patch on Kafka and KafkaRebalance resources — allowing tampering with cluster configuration, listener authentication, and rebalancing operations across every tenant's Kafka cluster.
    • cluster-monitoring-view — broad read visibility into cluster state useful for further lateral movement.
  6. Impact: Read access to every tenant's Kafka credentials and write access to every tenant's Kafka cluster definition. From there, data exfiltration from topics, credential harvesting, and persistence via modified cluster configs are all on the table.

The CVSS scope change (S:C) is well-earned: the vulnerable component (Console CR handling) compromises a security authority (the operator's cluster-scoped identity) far beyond its own privilege boundary.

Why This Pattern Matters Beyond This CVE

This is the operator privilege amplification problem that I've seen repeatedly in Kubernetes assessments: operators reconcile low-privilege custom resources using high-privilege identities, and any user-controlled field that flows into a pod spec (image, env, volumes, args) becomes a privilege escalation primitive. The Console CR's spec.containers.api.spec.image field is exactly such a sink. When you audit any operator, enumerate which CR fields reach the pod spec and what identity the resulting pod runs as. That audit would have caught this class of bug.

Exploitation Status

  • In-the-wild exploitation: Not confirmed at time of publication.
  • Public PoC: The vulnerability description fully specifies the attack path; exploitation requires no novel technique — only a malicious image and a valid Console CR. Expect weaponization to be trivial and fast.
  • CISA KEV: Not listed as of this writing. Monitor the CISA KEV catalog — given the 9.9 score and trivial exploitability, listing is plausible if exploitation emerges.

Do not interpret "no confirmed exploitation" as breathing room. The exploit is a YAML manifest, not a binary.

Detection & Response

Detection for this vulnerability centers on three observable behaviors: (1) creation or modification of Console CRs with an image override, (2) anomalous use of the Strimzi operator's ServiceAccount token from unexpected sources, and (3) workloads reading projected SA tokens who have no business doing so. All are high-signal when tuned against your known-good operator behavior.

Sigma Rules

These rules assume Kubernetes audit logging is enabled and shipped to your SIEM (for the audit rule) and that you have Linux process telemetry from node-level EDR or eBPF sensors (for the token-access rule).

YAML
---
title: Kubernetes Console CR Created With Image Override (CVE-2026-105312)
id: 3f9c1a72-5b84-4e2d-9c17-8a6f0d2e4b31
status: experimental
description: Detects creation or update of Strimzi Console custom resources specifying spec.containers.api.spec.image, the exploitation vector for CVE-2026-105312. Any Console CR with an explicit image override should be treated as hostile until validated against approved image allowlists.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-105312
  - https://attack.mitre.org/techniques/T1078/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.privilege_escalation
  - attack.t1078
  - cve.2026.105312
logsource:
  product: kubernetes
  service: audit
detection:
  selection_resource:
    objectRef.resource|contains: 'consoles'
  selection_verb:
    verb:
      - 'create'
      - 'update'
      - 'patch'
  selection_image:
    requestObject|contains: 'spec.containers.api.spec.image'
  condition: selection_resource and selection_verb and selection_image
falsepositives:
  - Legitimate platform engineering teams pinning Console images during upgrades
level: high
---
title: Workload Process Reading Projected Kubernetes ServiceAccount Token
id: 8b2e4d61-7c53-4a1f-b308-2d9c5e7f1a44
status: experimental
description: Detects non-standard processes opening or reading the projected ServiceAccount token path inside containers. Legitimate workloads use client libraries; direct shell/tool access to the token file is characteristic of token theft following CVE-2026-105312-style image substitution.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-105312
  - https://attack.mitre.org/techniques/T1528/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.credential_access
  - attack.t1528
logsource:
  category: process_creation
  product: linux
detection:
  selection:
    CommandLine|contains:
      - '/var/run/secrets/kubernetes.io/serviceaccount/token'
      - '/run/secrets/kubernetes.io/serviceaccount/token'
  filter_known_clients:
    Image|contains:
      - 'kubectl'
  condition: selection and not filter_known_clients
falsepositives:
  - Debugging sessions by cluster administrators inside pods
  - Custom bootstrap scripts that manually construct API clients
level: high
---
title: Strimzi Operator ServiceAccount Used From Unexpected Pod
id: 5c7a9e13-2f48-4d6b-9120-6e3b8d4f7c02
status: experimental
description: Detects Kubernetes API audit events where the Strimzi operator or Console ServiceAccount identity authenticates from a pod or namespace that does not match the operator deployment, indicating token theft and replay as described in CVE-2026-105312.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-105312
  - https://attack.mitre.org/techniques/T1078.004/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.lateral_movement
  - attack.t1078.004
logsource:
  product: kubernetes
  service: audit
detection:
  selection_identity:
    user.username|contains:
      - 'system:serviceaccount:strimzi'
      - 'strimzi-cluster-operator'
      - 'console'
  selection_sensitive:
    objectRef.resource|contains:
      - 'kafkausers'
      - 'kafkas'
      - 'kafkarebalances'
  filter_legit_namespace:
    sourceIPs|contains:
      - 'KNOWN_OPERATOR_POD_CIDR'
  condition: selection_identity and selection_sensitive and not filter_legit_namespace
falsepositives:
  - Operator pod rescheduling to new nodes changing source IPs; maintain the allowlist
level: critical

KQL (Microsoft Sentinel / Defender)

For AKS clusters with diagnostic settings shipping control-plane logs to Log Analytics/Sentinel, the AzureDiagnostics table carries kube-apiserver audit events. This query hunts for Console CR writes with an image override and correlates subsequent privileged API activity by operator identities. For non-AKS clusters shipping audit logs via Syslog/CEF, adapt the table to CommonSecurityLog.

KQL — Microsoft Sentinel / Defender
// Hunt: Console CR image override + downstream Strimzi control-plane access
let Lookback = 14d;
let SuspiciousConsoleWrites = AzureDiagnostics
| where TimeGenerated > ago(Lookback)
| where Category == "kube-audit" or Category == "kube-audit-admin"
| extend log = tostring(log_s)
| where log has "consoles" and log has_any ("create", "update", "patch")
| where log has "containers.api.spec.image" or log has "\"image\""
| extend User = tostring(parse_json(log).user.username),
         Namespace = tostring(parse_json(log).objectRef.namespace),
         Verb = tostring(parse_json(log).verb),
         SourceIP = tostring(parse_json(log).sourceIPs)
| project WriteTime=TimeGenerated, User, Namespace, Verb, SourceIP, log;
SuspiciousConsoleWrites
| join kind=leftouter (
    AzureDiagnostics
    | where TimeGenerated > ago(Lookback)
    | where Category == "kube-audit" or Category == "kube-audit-admin"
    | extend log = tostring(log_s)
    | where log has_any ("kafkausers", "kafkarebalances", "kafkas")
    | where log has "strimzi" or log has "console"
    | extend SAUser = tostring(parse_json(log).user.username),
             Resource = tostring(parse_json(log).objectRef.resource),
             APIVerb = tostring(parse_json(log).verb),
             APISourceIP = tostring(parse_json(log).sourceIPs)
    | project APITime=TimeGenerated, SAUser, Resource, APIVerb, APISourceIP
) on $left.SourceIP == $right.APISourceIP
| project WriteTime, User, Namespace, Verb, APITime, SAUser, Resource, APIVerb, SourceIP
| order by WriteTime desc

This join surfaces the full kill chain: who wrote the Console CR, and whether the Strimzi/Console service account identity subsequently touched KafkaUser, Kafka, or KafkaRebalance objects from the same source IP — a strong indicator the substituted pod is live and operating with stolen credentials. Validate any hit against your known operator pod IPs immediately.

Velociraptor VQL

Velociraptor deployed as a DaemonSet (or via node-level agents) can hunt for processes inside containers that have opened the projected SA token path — a post-exploitation artifact of a substituted image. Pair this with a glob for recently created pod token mounts to scope your blast-radius review.

VQL — Velociraptor
-- Hunt for processes accessing projected ServiceAccount token paths (CVE-2026-105312 post-exploitation)
SELECT Pid,
       Ppid,
       Name,
       Exe,
       CommandLine,
       Username,
       CreateTime
FROM pslist()
WHERE CommandLine =~ 'serviceaccount/token'
   OR CommandLine =~ '/var/run/secrets/kubernetes.io'
   OR Exe =~ '(?i)(cat|curl|wget|python|perl|base64)$'
      AND CommandLine =~ 'kubernetes.io/serviceaccount'
ORDER BY CreateTime DESC
VQL — Velociraptor
-- Enumerate projected SA token mounts to identify pods carrying operator-grade credentials
SELECT FullPath,
       Size,
       Mtime,
       Ctime
FROM glob(globs='/var/lib/kubelet/pods/*/volumes/kubernetes.io~projected/*/token')
ORDER BY Mtime DESC
LIMIT 500

Remediation & Audit Script (Bash)

The following script audits your exposure: it enumerates every Console CR and flags any with an explicit image override, inventories ClusterRoleBindings attached to Strimzi/Console service accounts, and lists every subject that can create or update Console resources. Run it with cluster-admin read credentials.

Bash / Shell
#!/bin/bash
# CVE-2026-105312 exposure audit - run with kubectl cluster-admin read access
set -euo pipefail

echo "=== [1] Console CRs with explicit api image override (exploitation vector) ==="
kubectl get consoles --all-namespaces -o json 2>/dev/null | \
  jq -r '.items[] | select(.spec.containers.api.spec.image != null) |
    "SUSPECT: \(.metadata.namespace)/\(.metadata.name) image=\(.spec.containers.api.spec.image)"' || \
  echo "No Console CRD found or none with image overrides."

echo ""
echo "=== [2] All Console CRs (baseline inventory) ==="
kubectl get consoles --all-namespaces -o wide 2>/dev/null || echo "No consoles.console.strimzi.io CRD present."

echo ""
echo "=== [3] ClusterRoleBindings granting Strimzi/Console SAs cluster scope ==="
kubectl get clusterrolebindings -o json | \
  jq -r '.items[] | select(.subjects[]?.name | test("strimzi|console"; "i")) |
    "\(.metadata.name) -> role=\(.roleRef.name) subjects=\([.subjects[] | "\(.namespace)/\(.name)"] | join(","))"'

echo ""
echo "=== [4] Identities able to create/update Console CRs (potential attackers) ==="
kubectl get clusterroles,roles --all-namespaces -o json | \
  jq -r '.items[] | select(.rules[]? | (.resources[]? | test("consoles")) and (.verbs[]? | test("create|update|patch|\\*"))) |
    "\(.kind)/\(.metadata.name) grants console write"'

echo ""
echo "=== [5] Running pods with unexpected images in strimzi namespaces ==="
kubectl get pods --all-namespaces -o json | \
  jq -r '.items[] | select(.metadata.namespace | test("strimzi|kafka"; "i")) |
    "\(.metadata.namespace)/\(.metadata.name): \([.spec.containers[].image] | join(", "))"'

Any SUSPECT line in step 1 is a potential active compromise — isolate the namespace, capture the pod's image and registry provenance, and rotate all KafkaUser credentials cluster-wide before investigating further.

Remediation

  1. Patch immediately. Track the Strimzi project advisory referenced by NVD for CVE-2026-105312 and upgrade the operator to the fixed release as soon as it is available. Verify your running operator version with kubectl get deployment strimzi-cluster-operator -o jsonpath='{.spec.template.spec.containers[0].image}' and confirm post-upgrade that Console CRs no longer permit arbitrary image substitution. Because NVD entries lag vendor fixes, watch the Strimzi GitHub releases and security advisories directly.
  2. Restrict Console CR write access now (primary workaround). Until patched, treat create/update/patch on consoles.console.strimzi.io as a cluster-admin-equivalent operation. Audit the output of step 4 in the script above and strip that verb from every Role/ClusterRole granted to tenants, developers, and CI service accounts. If self-service Console deployment is a business requirement, gate it behind an admission controller instead of raw RBAC.
  3. Enforce image allowlisting at admission. Deploy an OPA/Gatekeeper or Kyverno policy that rejects any Console CR setting spec.containers.api.spec.image to a value outside an approved registry/pinned digest list. This closes the vector independent of the operator fix and defends against regression.
  4. Reduce operator blast radius. Review the ClusterRoleBindings identified in step 3. Where feasible, scope Strimzi operator permissions down, separate the Console workload's identity from the cluster operator's identity, and remove wildcard resource grants. The vulnerability is only as damaging as the token the substituted pod inherits.
  5. Rotate credentials if exposure is confirmed or suspected. If any Console CR with an unvetted image existed in your environment, assume the operator ServiceAccount token was readable: rotate all KafkaUser SCRAM/TLS credentials across every tenant, audit Kafka and KafkaRebalance resources for unauthorized patches, and review audit logs for token replay from unexpected source IPs.
  6. Enable and centralize Kubernetes audit logging. The detections above are only as good as your audit pipeline. Ensure kube-apiserver audit policy logs request/response bodies for custom resources in the console.strimzi.io group at minimum, and ship to a SIEM the attacker cannot reach from a compromised pod.
  7. Network segmentation. Apply NetworkPolicies restricting egress from Console/operator pods to only the Kubernetes API and required dependencies — a substituted image that cannot reach your registries, Kafka brokers, or exfiltration endpoints buys your IR team time.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.