CVE-2025-66623 Overview
CVE-2025-66623 affects Strimzi, the Kubernetes operator that runs Apache Kafka clusters on Kubernetes and OpenShift. In versions from 0.47.0 through 0.49.0, Strimzi generates an incorrect Kubernetes Role for Kafka Connect and Kafka MirrorMaker 2 operands. The faulty role grants GET access to all Kubernetes Secrets in the namespace instead of restricting access to the specific TLS certificate secrets. This information disclosure flaw [CWE-200] allows the affected operand pods to read arbitrary secret material co-located in the namespace. Strimzi 0.49.1 corrects the role generation logic.
Critical Impact
Kafka Connect and MirrorMaker 2 service accounts can read every Kubernetes Secret in their namespace, exposing credentials, API tokens, and certificates beyond what the operator should authorize.
Affected Products
- Strimzi Kafka Operator 0.47.0 through 0.49.0
- Apache Kafka Connect deployments managed by affected Strimzi versions
- Apache Kafka MirrorMaker 2 deployments managed by affected Strimzi versions
Discovery Timeline
- 2025-12-05 - CVE-2025-66623 published to NVD
- 2026-03-04 - Last updated in NVD database
Technical Details for CVE-2025-66623
Vulnerability Analysis
The vulnerability resides in the role-generation logic for Kafka Connect and MirrorMaker 2 components within the Strimzi cluster operator. Strimzi constructs Kubernetes Role objects that authorize operand pods to read TLS certificate secrets required for cluster communication.
In vulnerable versions, when the list of certificate secret names (certSecretNames) is empty, the operator still creates a PolicyRule granting get on the secrets resource. Because the empty resourceNames list is treated as no restriction by Kubernetes RBAC, the rule expands to permit GET on every Secret in the namespace.
An attacker who compromises a Kafka Connect or MirrorMaker 2 pod, or any workload assuming its service account, can read credentials, database passwords, registry tokens, and TLS private keys belonging to unrelated workloads sharing the namespace.
Root Cause
The defect is a classic RBAC scoping error tied to an unchecked empty collection. Kubernetes RBAC treats a PolicyRule with no resourceNames as a wildcard, so an empty list silently broadens the authorization rather than denying it. The pre-patch code built the rule unconditionally without verifying that certSecretNames contained entries.
Attack Vector
Exploitation requires adjacent-network access from a workload that uses the operand service account. A malicious container, sidecar, or compromised application running with the Kafka Connect or MirrorMaker 2 identity can issue kubectl get secrets calls and exfiltrate all namespace secrets without triggering authorization denials.
// Vulnerable code path (pre-0.49.1) in KafkaCluster.java
// Source: https://github.com/strimzi/strimzi-kafka-operator/commit/c8a14935e99c91eb0dd865431f46515da9f82ccc
// BEFORE (vulnerable): Role created even when certSecretNames is empty,
// which Kubernetes interprets as GET on ALL secrets in the namespace.
List<PolicyRule> rules = List.of(new PolicyRuleBuilder()
.withApiGroups("")
.withResources("secrets")
.withVerbs("get")
.withResourceNames(certSecretNames.stream().toList())
.build());
return RbacUtils.createRole(componentName, namespace, rules, labels, ownerReference, null);
// AFTER (fixed in 0.49.1): Reject empty secret list before building the rule.
if (certSecretNames.isEmpty()) {
// This should never happen but just in case it does, we throw an error
throw new RuntimeException("No TLS certificate secrets found for the Kafka cluster.");
} else {
List<PolicyRule> rules = List.of(new PolicyRuleBuilder()
.withApiGroups("")
.withResources("secrets")
.withVerbs("get")
.withResourceNames(certSecretNames.stream().toList())
.build());
return RbacUtils.createRole(componentName, namespace, rules, labels, ownerReference, null);
}
Source: Strimzi commit c8a14935
Detection Methods for CVE-2025-66623
Indicators of Compromise
- Kubernetes Role objects owned by Strimzi where the rule for secrets has an empty resourceNames array
- Audit log entries showing the Kafka Connect or MirrorMaker 2 service account performing get requests on Secret objects unrelated to Kafka TLS certificates
- Service account token usage from Kafka Connect or MirrorMaker 2 pods accessing the Kubernetes API outside expected operational patterns
Detection Strategies
- Inventory all Role resources created by Strimzi for Kafka Connect and MirrorMaker 2 and verify each secrets rule explicitly lists certificate secret names in resourceNames.
- Enable Kubernetes API server audit logging at the Metadata level for secrets resources and alert on get calls from Strimzi operand service accounts that target non-certificate secrets.
- Run kubectl auth can-i get secrets --as=system:serviceaccount:<ns>:<connect-sa> to confirm scope, and treat a yes without specific resource names as an indicator of the vulnerable role.
Monitoring Recommendations
- Forward Kubernetes audit logs to a centralized analytics platform and build queries that group secret reads by service account and target namespace.
- Track the Strimzi operator version deployed in each cluster and alert when versions between 0.47.0 and 0.49.0 are detected.
- Monitor changes to RoleBinding and Role objects in namespaces hosting Kafka Connect or MirrorMaker 2 to detect drift from the patched configuration.
How to Mitigate CVE-2025-66623
Immediate Actions Required
- Upgrade the Strimzi cluster operator to version 0.49.1 or later in every cluster running Kafka Connect or MirrorMaker 2.
- Rotate any Kubernetes Secret that resided in a namespace alongside an affected Kafka Connect or MirrorMaker 2 deployment, including database credentials, API tokens, and TLS keys.
- Audit existing Strimzi-generated Role objects and delete or patch any rule that grants get on secrets without a populated resourceNames list.
Patch Information
The issue is fixed in Strimzi 0.49.1 via commit c8a14935e99c91eb0dd865431f46515da9f82ccc. The patch adds a guard that raises a RuntimeException when certSecretNames is empty, preventing creation of a wildcard secrets role. Refer to the GitHub Security Advisory GHSA-xrhh-hx36-485q for vendor guidance.
Workarounds
- Isolate Kafka Connect and MirrorMaker 2 workloads in dedicated namespaces that contain only the secrets they require, limiting blast radius until the upgrade is applied.
- Manually patch the generated Role for each affected operand to enumerate certificate secret names in resourceNames, removing the implicit wildcard.
- Apply a Kubernetes admission policy (for example, OPA Gatekeeper or Kyverno) that rejects Role objects granting get on secrets without explicit resourceNames.
# Verify the Strimzi operator version and inspect the operand role
kubectl -n kafka get deployment strimzi-cluster-operator \
-o jsonpath='{.spec.template.spec.containers[0].image}'
# List roles created for Kafka Connect / MirrorMaker 2 and confirm resourceNames is populated
kubectl -n kafka get role -l app.kubernetes.io/managed-by=strimzi-cluster-operator -o yaml \
| grep -A4 'resources:\s*\n\s*- secrets'
# Confirm the service account cannot list arbitrary secrets after upgrade
kubectl auth can-i get secret unrelated-app-secret \
--as=system:serviceaccount:kafka:my-connect-cluster-connect
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


