Skip to content

CVE-2026-33557: Verified Repro With Script Download

CVE-2026-33557: Apache Kafka SASL/OAUTHBEARER accepts unvalidated JWTs

CVE-2026-33557 is verified against Apache Kafka · maven. Affected versions: 4.1.0 through 4.1.1. Vulnerability class: Auth Bypass. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00281.

REPRO-2026-00281 Apache Kafka · maven Auth Bypass Variant found Jul 11, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.1
Confidence
HIGH
Reproduced in
44m 25s
Tool calls
414
Spend
$10.59
01 · Overview

What Is CVE-2026-33557?

CVE-2026-33557 is a critical, suspected authentication weakness in Apache Kafka's broker-side SASL/OAUTHBEARER handling, where the default JWT validator may fail to properly enforce token expiration on replay. Pruva reproduced it (reproduction REPRO-2026-00281).

02 · Severity & CVSS

CVE-2026-33557 Severity & CVSS Score

CVE-2026-33557 is rated critical severity, with a CVSS base score of 9.1 out of 10.

CRITICAL threat level
9.1 / 10 CVSS base
Weakness CWE-1285

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected Apache Kafka Versions

Apache Kafka · maven versions 4.1.0 through 4.1.1 are affected.

How to Reproduce CVE-2026-33557

$ pruva-verify REPRO-2026-00281
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00281/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-33557

Authorization bypass — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

expired JWT replayed directly in Kafka SASL/OAUTHBEARER initial client response

Attack chain
  1. TCP connection to Kafka broker
  2. SaslHandshake(OAUTHBEARER)
  3. SaslAuthenticate(auth=Bearer <expired JWT>)
  4. OAuthBearerValidatorCallbackHandler
  5. DefaultJwtValidator
Variants tested

Alternate trigger on Apache Kafka 4.1.0 broker SASL/OAUTHBEARER: non-expired JWTs with wrong issuer, wrong audience, or untrusted signature are accepted through the same DefaultJwtValidator -> ClientJwtValidator broker path. Kafka 4.1.2 rejects all tested variants, so this is not a fixed-version bypass.

How the agent worked 987 events · 414 tool calls · 44 min
44 minDuration
414Tool calls
273Reasoning steps
987Events
Agent activity over 44 min
Support
22
Repro
716
Judge
139
Variant
105
0:0044:25

Root Cause and Exploit Chain for CVE-2026-33557

Versions: Apache Kafka 4.1.0 through 4.1.1 according to the Apache advisory for CVE-2026-33557.Fixed: Apache Kafka 4.1.2 and 4.2.0+.

Apache Kafka 4.1.0/4.1.1 broker-side SASL/OAUTHBEARER validation can accept attacker-supplied JWTs through the network authentication path when the default broker validator is used. The current reproduction focuses on the judge-requested observable vulnerable-vs-fixed divergence for an expired JWT replayed directly over Kafka's TCP SASL boundary: Kafka 4.1.0 returns a successful SaslAuthenticate response for the expired replayed JWT, while Kafka 4.1.2 rejects the same token with invalid_token and broker-side BrokerJwtValidator expiration evidence. This avoids Kafka client-side expiry enforcement by using a raw Kafka protocol client only for the SASL frames.

  • Package/component affected: Apache Kafka broker SASL/OAUTHBEARER authentication, specifically org.apache.kafka.common.security.oauthbearer.DefaultJwtValidator used by OAuthBearerValidatorCallbackHandler.
  • Affected versions: Apache Kafka 4.1.0 through 4.1.1 according to the Apache advisory for CVE-2026-33557.
  • Fixed versions: Apache Kafka 4.1.2 and 4.2.0+.
  • Risk level and consequences: Important/high authentication validation weakness. The advisory impact is that a broker using the default validator may accept JWTs without validating signature, issuer, or audience. In this run, the expired-token replay path demonstrates that the vulnerable broker accepts an expired JWT at the SASL authentication step, while the fixed broker rejects it.

Impact Parity

  • Disclosed/claimed maximum impact: authz_bypass / authentication validation bypass for Kafka SASL/OAUTHBEARER.
  • Reproduced impact from this run: network-protocol authentication divergence on the real Kafka broker TCP listener. The vulnerable broker returns SaslAuthenticate(error_code=0) for an expired JWT replayed directly in the SASL initial client response; the fixed broker returns an invalid-token challenge and logs expiration validation failure.
  • Parity: full for the broker-side token validation bypass at the SASL/OAUTHBEARER TCP authentication boundary.
  • Not demonstrated: The proof does not require a Kafka CLI client to use the expired credential because the standard client enforces expiry before replay. The primary proof intentionally bypasses that client-side behavior with raw Kafka SASL frames to test the broker-side validator directly.

Root Cause

Kafka 4.1.0's DefaultJwtValidator.configure() always delegates to ClientJwtValidator when no explicit verification key resolver is passed. ClientJwtValidator performs only structural and claim-presence checks for scope, exp, sub, and iat; it does not verify the JWT signature and does not reject an exp timestamp that is already in the past. Therefore, the broker-side OAuthBearerValidatorCallbackHandler can receive a replayed JWT over TCP and treat it as valid.

Kafka 4.1.2 changes DefaultJwtValidator.configure() so that when sasl.oauthbearer.jwks.endpoint.url is present, the default delegate becomes BrokerJwtValidator, which performs signature and claims validation, including expiration. The fix commit referenced by the advisory is 01d8e7db8d08dbd538892b409457ea6bfcc2a422.

Reproduction Steps

  1. Run bundle/repro/reproduction_steps.sh.
  2. The script installs required Python dependencies, reuses or downloads Kafka 4.1.0 and Kafka 4.1.2 binaries, starts a real mock JWKS/OAuth issuer, starts real Kafka KRaft brokers with SASL/OAUTHBEARER enabled, and sends raw Kafka SaslHandshake and SaslAuthenticate TCP frames containing the same expired attacker-controlled JWT.
  3. Expected evidence of reproduction:
    • Kafka 4.1.0: expired JWT replay receives SaslAuthenticate success (error_code=0, no invalid-token auth bytes).
    • Kafka 4.1.2: the same expired JWT receives an invalid-token response and broker logs show BrokerJwtValidator rejecting the exp claim as expired.
    • Valid JWT controls are also run so the fixed broker's rejection is not caused by a broken test setup.

Evidence

Primary evidence is written under bundle/logs/:

  • bundle/logs/evidence.log: summary, decoded JWT claims, version comparison, and key protocol outcomes.
  • bundle/logs/raw_vulnerable_expired.json: parsed raw Kafka SASL response showing vulnerable acceptance of the expired JWT.
  • bundle/logs/raw_fixed_expired.json: parsed raw Kafka SASL response showing fixed rejection of the same expired JWT.
  • bundle/logs/broker_vulnerable.log: real Kafka 4.1.0 broker runtime log.
  • bundle/logs/broker_fixed.log: real Kafka 4.1.2 broker runtime log with expiration rejection details.
  • bundle/logs/mock_oauth_server.log: generated expired/valid JWTs and JWKS requests.

Key expected excerpts:

  • Vulnerable parsed response: "sasl_authenticate_error_code": 0, "accepted_by_broker": true, and an expired JWT claim where exp < replay_time.
  • Fixed parsed response: "rejected_by_broker": true with "invalid_token" in the auth bytes/error payload.
  • Fixed broker log: The JWT is no longer valid ... Expiration Time ... from BrokerJwtValidator.

Environment details captured include Java version, Kafka binary versions, mock issuer/JWKS URL, decoded token timestamps, and the raw TCP proof JSON files.

Recommendations / Next Steps

  • Upgrade affected Kafka deployments to 4.1.2, 4.2.0, or later.
  • If upgrade is not immediately possible, explicitly configure sasl.oauthbearer.jwt.validator.class=org.apache.kafka.common.security.oauthbearer.BrokerJwtValidator for brokers using SASL/OAUTHBEARER and configure a trusted sasl.oauthbearer.jwks.endpoint.url.
  • Add integration tests that replay expired, wrong-issuer, wrong-audience, and unsigned/tampered JWTs directly against the broker-side SASL/OAUTHBEARER listener, not only through Kafka clients.

Additional Notes

The reproduction script is designed to be idempotent: it creates isolated per-run KRaft data directories, uses unique ports per attempt where practical, kills broker/mock processes on exit, and writes fresh runtime evidence on every run. The proof intentionally uses a raw Kafka TCP client after broker startup because the standard Kafka CLI client refuses to replay expired credentials locally; using it would mask the broker-side validator path that this ticket asks to verify.

Variant Analysis & Alternative Triggers for CVE-2026-33557

Versions: versions as tested: Apache Kafka 4.1.0 binary distribution, release tag commit 13f70256db3c994c590e5d262a7cc50b9e973204.Fixed: version as tested: Apache Kafka 4.1.2 binary distribution, release tag commit c82fd9b934b4c1e6fa799e3f1dcc8f08d997740c.

A distinct alternate trigger was confirmed on the vulnerable Apache Kafka 4.1.0 broker-side SASL/OAUTHBEARER path, but no bypass of the Kafka 4.1.2 fix was found. Instead of replaying an expired JWT, this variant matrix used non-expired JWTs with (1) an unexpected issuer, (2) an unexpected audience, and (3) a signature produced by an untrusted key while retaining the trusted kid. Kafka 4.1.0 accepted all three invalid tokens over the real network SASL/OAUTHBEARER broker listener because DefaultJwtValidator delegated to ClientJwtValidator; Kafka 4.1.2 rejected the same inputs because the fixed DefaultJwtValidator selected BrokerJwtValidator when sasl.oauthbearer.jwks.endpoint.url was configured. Therefore this is an alternate trigger on the vulnerable version, not a fixed-version bypass.

Fix Coverage / Assumptions

The fix relies on the invariant that a broker configured for secured OAuth/OIDC validation has sasl.oauthbearer.jwks.endpoint.url in the effective listener-prefixed configuration, and that this should cause the default validator to instantiate BrokerJwtValidator instead of ClientJwtValidator.

The relevant source-level change between Kafka 4.1.0 and 4.1.2 is in:

  • clients/src/main/java/org/apache/kafka/common/security/oauthbearer/DefaultJwtValidator.java
    • Kafka 4.1.0: if no injected CloseableVerificationKeyResolver is present, DefaultJwtValidator.configure() always uses new ClientJwtValidator().
    • Kafka 4.1.2: if no injected resolver is present, DefaultJwtValidator.configure() constructs ConfigurationUtils and checks SaslConfigs.SASL_OAUTHBEARER_JWKS_ENDPOINT_URL; when present it uses new BrokerJwtValidator(), otherwise it falls back to new ClientJwtValidator().

The runtime proof also captures the shipped bytecode comparison in:

  • bundle/logs/vuln_variant/javap_defaultjwtvalidator_4.1.0.txt
  • bundle/logs/vuln_variant/javap_defaultjwtvalidator_4.1.2.txt

The fix explicitly covers the production broker path using OAuthBearerValidatorCallbackHandler plus a configured JWKS endpoint. It does not attempt to remove all uses of ClientJwtValidator, because that class remains appropriate for client-side token parsing and for configurations that intentionally do not provide JWKS. The tested broker path was configured with:

  • listener.name.sasl_plaintext.oauthbearer.sasl.server.callback.handler.class=org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackHandler
  • listener.name.sasl_plaintext.oauthbearer.sasl.oauthbearer.jwks.endpoint.url=<mock JWKS URL>
  • sasl.oauthbearer.expected.issuer=https://mock-idp.example.com
  • sasl.oauthbearer.expected.audience=kafka-broker

The Apache Kafka security model treats broker listener authentication as in scope when security is enabled. It also states that security is off by default and that trusted operators, classpath/JAR loading, and intentionally unsecured/development tooling are out of scope. This variant stays inside the in-scope boundary: an untrusted network peer sends a JWT over a broker SASL listener configured for OAUTHBEARER validation.

Variant / Alternate Trigger

The parent reproduction demonstrated an expired JWT replay. The variant matrix tested three materially different token-validation failures that reach the same sink from the same network trust boundary:

  1. wrong_issuer: JWT has a valid future exp, trusted signature, and correct audience, but iss=https://attacker-idp.example.net instead of the configured expected issuer.
  2. wrong_audience: JWT has a valid future exp, trusted signature, and correct issuer, but aud=other-service instead of kafka-broker.
  3. tampered_signature: JWT has valid future exp, correct issuer, and correct audience, but is signed with an untrusted RSA key while using the trusted key id.

Exact entry point:

  • Network protocol: TCP connection to Kafka broker listener.
  • Kafka API messages: SaslHandshake(OAUTHBEARER) followed by SaslAuthenticate containing the RFC 7628 initial client response auth=Bearer <JWT>.
  • Target callback path: OAuthBearerValidatorCallbackHandler.handle() -> handleValidatorCallback() -> DefaultJwtValidator.validate().

Specific code paths:

  • clients/src/main/java/org/apache/kafka/common/network/SaslChannelBuilder.java: selects the broker SASL callback handler. The default OAUTHBEARER server handler is the unsecured test handler unless the operator configures sasl.server.callback.handler.class; this test configures the secured OAuthBearerValidatorCallbackHandler.

  • clients/src/main/java/org/apache/kafka/common/security/oauthbearer/OAuthBearerValidatorCallbackHandler.java: receives the attacker-supplied token from the SASL exchange and delegates to the configured JwtValidator.

  • clients/src/main/java/org/apache/kafka/common/security/oauthbearer/DefaultJwtValidator.java: vulnerable-vs-fixed delegate selection.

  • clients/src/main/java/org/apache/kafka/common/security/oauthbearer/ClientJwtValidator.java: parses claims and requires claim presence but does not validate issuer, audience, signature trust, or current-time expiry.

  • clients/src/main/java/org/apache/kafka/common/security/oauthbearer/BrokerJwtValidator.java: fixed broker validator using jose4j with signature verification, expected issuer/audience checks, required exp/iat, and expiration enforcement.

  • Package/component affected: Apache Kafka broker SASL/OAUTHBEARER authentication, specifically the default broker-side JWT validator selected behind OAuthBearerValidatorCallbackHandler.

  • Affected versions as tested: Apache Kafka 4.1.0 binary distribution, release tag commit 13f70256db3c994c590e5d262a7cc50b9e973204.

  • Fixed version as tested: Apache Kafka 4.1.2 binary distribution, release tag commit c82fd9b934b4c1e6fa799e3f1dcc8f08d997740c.

  • Consequences: On the vulnerable version, a network peer can authenticate to the broker with a token that should be rejected for issuer, audience, or signature trust reasons. This is an authentication validation bypass at the broker listener boundary.

Impact Parity

  • Disclosed/claimed maximum impact for the parent: authz_bypass / broker-side SASL/OAUTHBEARER authentication validation bypass.
  • Reproduced impact from this variant run: Kafka 4.1.0 accepted invalid but non-expired JWTs over the production broker TCP SASL path; Kafka 4.1.2 rejected the same invalid inputs.
  • Parity: full for the vulnerable-version broker-side JWT validation bypass, because the invalid tokens were accepted by the broker authentication handshake.
  • Not demonstrated: No fixed-version bypass was demonstrated. The proof does not demonstrate post-auth topic read/write operations; it proves SASL authentication success/failure at the broker boundary.

Root Cause

The same underlying bug is reached because Kafka 4.1.0's DefaultJwtValidator.configure() used ClientJwtValidator whenever no explicit verification-key resolver was injected. In the secured broker callback handler path, this meant a broker with sasl.oauthbearer.jwks.endpoint.url, expected issuer, and expected audience configured still ended up using a validator intended for client-side token parsing. ClientJwtValidator extracts scope, exp, sub, and iat and constructs a BasicOAuthBearerToken, but it does not verify the token signature, compare iss to the expected issuer, compare aud to the expected audience, or enforce current-time expiration.

Kafka 4.1.2 closes the tested path by changing DefaultJwtValidator.configure() to instantiate BrokerJwtValidator when sasl.oauthbearer.jwks.endpoint.url is present. BrokerJwtValidator.configure() builds a jose4j JwtConsumer with DISALLOW_NONE, setRequireExpirationTime(), setRequireIssuedAt(), setVerificationKeyResolver(...), and optional expected issuer/audience. The fixed broker logs show BrokerJwtValidator rejection evidence for the tested invalid issuer/audience/signature tokens.

Fix reference from the parent reproduction: 01d8e7db8d08dbd538892b409457ea6bfcc2a422 was identified as the advisory fix commit, while the tested fixed release tag resolves to c82fd9b934b4c1e6fa799e3f1dcc8f08d997740c.

Reproduction Steps

  1. Run bundle/vuln_variant/reproduction_steps.sh.
  2. The script downloads or reuses Kafka 4.1.0 and Kafka 4.1.2 binary distributions, starts a mock OAuth/JWKS issuer, starts isolated real Kafka KRaft brokers configured with SASL/OAUTHBEARER and OAuthBearerValidatorCallbackHandler, and sends raw Kafka SaslHandshake/SaslAuthenticate frames with valid and invalid JWTs.
  3. Expected evidence:
    • Kafka 4.1.0 accepts all three variant tokens: wrong issuer, wrong audience, and tampered signature.
    • Kafka 4.1.2 accepts the valid control token but rejects all three variant tokens with invalid_token and broker log evidence from BrokerJwtValidator.
    • The script exits 1 by design because no fixed-version bypass is reproduced; this is still a successful negative-bypass / alternate-trigger run.

The script was executed twice successfully and produced the same verdict both times: alternate trigger confirmed on Kafka 4.1.0, no bypass on Kafka 4.1.2.

Evidence

Primary evidence locations:

  • bundle/logs/vuln_variant/reproduction_steps.log: full latest execution log.
  • bundle/logs/vuln_variant/variant_evidence.log: summarized variant matrix and raw response excerpts.
  • bundle/logs/vuln_variant/raw_vulnerable_wrong_issuer.json
  • bundle/logs/vuln_variant/raw_vulnerable_wrong_audience.json
  • bundle/logs/vuln_variant/raw_vulnerable_tampered_signature.json
  • bundle/logs/vuln_variant/raw_fixed_wrong_issuer.json
  • bundle/logs/vuln_variant/raw_fixed_wrong_audience.json
  • bundle/logs/vuln_variant/raw_fixed_tampered_signature.json
  • bundle/logs/vuln_variant/broker_vulnerable.log
  • bundle/logs/vuln_variant/broker_fixed.log
  • bundle/logs/vuln_variant/fixed_version.txt: exact tested release/tag identity.

Key evidence from the latest run:

{
  "alternate_trigger_confirmed_on_vulnerable": true,
  "bypass_confirmed_on_fixed": false,
  "valid_controls_ok": true,
  "vulnerable_variant_accepts": {
    "wrong_issuer": true,
    "wrong_audience": true,
    "tampered_signature": true
  },
  "fixed_variant_rejects": {
    "wrong_issuer": true,
    "wrong_audience": true,
    "tampered_signature": true
  },
  "fixed_variant_accepts": {
    "wrong_issuer": false,
    "wrong_audience": false,
    "tampered_signature": false
  }
}

The fixed broker returned invalid_token for all three variant inputs. For example, the wrong-issuer raw response has accepted_by_broker=false, rejected_by_broker=true, and SASL auth bytes {"status":"invalid_token"}. The fixed broker log includes rejection from BrokerJwtValidator with: Issuer (iss) claim value (https://attacker-idp.example.net) doesn't match expected value of https://mock-idp.example.com.

Environment details captured by the script include Java version, Kafka binary paths, release tag commits, mock issuer/JWKS URL, token claims, raw Kafka response JSON, and broker runtime logs.

Recommendations / Next Steps

  • Treat the Kafka 4.1.2 fix as covering the tested secured broker callback path. No additional patch is required for the wrong-issuer, wrong-audience, or tampered-signature data paths when sasl.oauthbearer.jwks.endpoint.url is configured.
  • Keep regression tests for more than expiration. The fix should remain covered by integration tests that send raw SASL/OAUTHBEARER frames for expired tokens, wrong issuer, wrong audience, unsigned/none algorithm tokens, and tokens signed by untrusted keys.
  • Document and lint broker configurations so production deployments using OAUTHBEARER do not accidentally use OAuthBearerUnsecuredValidatorCallbackHandler or omit the JWKS endpoint while expecting production-grade JWT validation.
  • Consider an operator-facing warning when a broker listener uses OAUTHBEARER without a secured server callback handler or without JWKS configuration, because Kafka's security model permits insecure configurations but operators may misinterpret them.

Additional Notes

The reproduction script is idempotent: it creates per-run working directories under bundle/vuln_variant/artifacts/, chooses fresh local ports, and kills mock/broker processes on exit. Both required verification runs completed without crashing; both returned exit code 1 because the fixed version rejected every variant input, which is the expected negative-bypass outcome. The Killed messages in the log correspond to deliberate broker shutdown with kill -9 during cleanup after successful probes, not an infrastructure failure.

CVE-2026-33557 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:43
0:00
session startedaccounts/fireworks/routers/glm-5p2-fast · CVE-2026-KAFKA · REPRO-20
0:02
0:04
web search
0:05
web search
0:07
0:09
web search
0:11
web search
0:14
0:15
web search
0:16
0:19
0:20
0:22
web search
0:36
0:36
extract_facts
no facts extracted
0:37
0:37
0:37
supportrepro
0:39
0:39
0:39
0:39
0:40
0:40
0:40
0:42
0:42
0:42
0:43
0:43

Artifacts and Evidence for CVE-2026-33557

Scripts, logs, diffs, and output captured during the reproduction.

bundle/artifact_promotion_manifest.json12.3 KB
bundle/artifact_promotion_report.json12.4 KB
bundle/vuln_variant/source_identity.json0.8 KB
bundle/vuln_variant/root_cause_equivalence.json1.4 KB
bundle/repro/reproduction_steps.sh26.2 KB
bundle/repro/rca_report.md6.1 KB
bundle/logs/evidence.log7.7 KB
bundle/logs/broker_secured.log83.5 KB
bundle/repro/runtime_manifest.json1.0 KB
bundle/repro/validation_verdict.json0.8 KB
bundle/logs/reproduction_steps.log7.3 KB
bundle/logs/raw_vulnerable_expired.json0.9 KB
bundle/logs/raw_vulnerable_valid.json0.9 KB
bundle/logs/raw_fixed_expired.json1.3 KB
bundle/logs/raw_fixed_valid.json0.9 KB
bundle/logs/broker_vulnerable.log71.4 KB
bundle/logs/broker_fixed.log75.4 KB
bundle/logs/mock_oauth_server.log5.6 KB
bundle/logs/javap_defaultjwtvalidator_4.1.0.txt4.9 KB
bundle/logs/javap_defaultjwtvalidator_4.1.2.txt6.0 KB
bundle/vuln_variant/reproduction_steps.sh28.3 KB
bundle/vuln_variant/rca_report.md12.4 KB
bundle/vuln_variant/patch_analysis.md9.7 KB
bundle/vuln_variant/variant_manifest.json4.6 KB
bundle/vuln_variant/validation_verdict.json2.2 KB
bundle/logs/vuln_variant/variant_evidence.log16.9 KB
bundle/vuln_variant/runtime_manifest.json1.2 KB
bundle/logs/vuln_variant/reproduction_steps.log12.6 KB
bundle/logs/vuln_variant/fixed_version.txt0.4 KB
bundle/logs/vuln_variant/raw_vulnerable_wrong_issuer.json0.9 KB
bundle/logs/vuln_variant/raw_vulnerable_wrong_audience.json0.9 KB
bundle/logs/vuln_variant/raw_vulnerable_tampered_signature.json0.9 KB
bundle/logs/vuln_variant/raw_fixed_wrong_issuer.json1.3 KB
bundle/logs/vuln_variant/raw_fixed_wrong_audience.json1.3 KB
bundle/logs/vuln_variant/raw_fixed_tampered_signature.json1.3 KB
bundle/logs/vuln_variant/broker_vulnerable.log71.6 KB
bundle/logs/vuln_variant/broker_fixed.log83.0 KB
bundle/logs/vuln_variant/mock_oauth_server.log4.8 KB
08 · How to Fix

How to Fix CVE-2026-33557

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-33557 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-33557

How does the CVE-2026-33557 replay attack work?

The reproduction connects to the broker with a raw Kafka protocol client that bypasses client-side expiry enforcement, then replays an already-expired SASL/OAUTHBEARER JWT over the TCP SASL boundary. Kafka 4.1.0 returns a successful SaslAuthenticate response for the expired token, while Kafka 4.1.2 rejects it with invalid_token and broker-side BrokerJwtValidator expiration evidence.

Which Kafka versions are affected by CVE-2026-33557, and where is it fixed?

Apache Kafka 4.1.0 through 4.1.1 are affected when using the broker's default SASL/OAUTHBEARER JWT validator; it is fixed in Kafka 4.1.2 and 4.2.0+.

How severe is CVE-2026-33557?

It is tracked as critical severity, though the underlying advisory language describes it as an important/high authentication-validation weakness in the default JWT validator.

How can I reproduce CVE-2026-33557?

Download the verified script and run it in an isolated environment against a Kafka 4.1.0-4.1.1 broker using the default SASL/OAUTHBEARER validator; it replays an expired JWT over a raw Kafka protocol client's SASL frames and shows the broker accepting it, then confirms Kafka 4.1.2 rejects the same token.
11 · References

References for CVE-2026-33557

Authoritative sources for CVE-2026-33557 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.