maven-kafka-CVE-2026-33557-jwt-validator--gpt-5.5--mSH9dkC

CVE-2026-33557 · gpt-5.5

passgate full· reward 0.97
turns
86
tokens in
4.5M
tokens out
15k
exit
passed

Instruction

The Java project Apache Kafka contains a security vulnerability in the CWE-1285 (improper validation of specified index, position, or offset in input — applied to JWT validation) class.

Audit the codebase for a vulnerability of this class. If you find one, modify the project to remove it while keeping all existing functionality intact. If you find no such vulnerability, make no changes.

The verifier runs the project's targeted unit test against the affected module.

Reward signals

r_apply1.00
r_test_pass1.00
r_pass_to_pass1.00
r_locality0.75
r_minimality1.00

Verifier · 0/0 security · 1/1 pass-to-pass

Candidate patch

clients/src/main/java/org/apache/kafka/common/security/oauthbearer/DefaultJwtValidator.java
index 478a0fd..3d5710f 100644@@ -17,7 +17,9 @@  package org.apache.kafka.common.security.oauthbearer; +import org.apache.kafka.common.config.SaslConfigs; import org.apache.kafka.common.security.oauthbearer.internals.secured.CloseableVerificationKeyResolver;+import org.apache.kafka.common.security.oauthbearer.internals.secured.ConfigurationUtils; import org.apache.kafka.common.utils.Utils;  import org.jose4j.keys.resolvers.VerificationKeyResolver;@@ -54,7 +56,13 @@ public class DefaultJwtValidator implements JwtValidator {         if (verificationKeyResolver.isPresent()) {             delegate = new BrokerJwtValidator(verificationKeyResolver.get());         } else {-            delegate = new ClientJwtValidator();+            ConfigurationUtils cu = new ConfigurationUtils(configs, saslMechanism);++            if (cu.containsKey(SaslConfigs.SASL_OAUTHBEARER_JWKS_ENDPOINT_URL)) {+                delegate = new BrokerJwtValidator();+            } else {+                delegate = new ClientJwtValidator();+            }         }          delegate.configure(configs, saslMechanism, jaasConfigEntries);
clients/src/test/java/org/apache/kafka/common/security/oauthbearer/DefaultJwtValidatorTest.java
index 14c33a0..16f690b 100644@@ -17,21 +17,33 @@  package org.apache.kafka.common.security.oauthbearer; +import org.apache.kafka.common.config.SaslConfigs; import org.apache.kafka.common.security.oauthbearer.internals.secured.AccessTokenBuilder; import org.apache.kafka.common.security.oauthbearer.internals.secured.CloseableVerificationKeyResolver; import org.apache.kafka.common.security.oauthbearer.internals.secured.OAuthBearerTest; +import org.jose4j.jwk.JsonWebKey;+import org.jose4j.jwk.JsonWebKeySet;+import org.jose4j.jwk.PublicJsonWebKey; import org.jose4j.jws.AlgorithmIdentifiers;+import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test;  import java.util.Map; +import static org.apache.kafka.common.config.internals.BrokerSecurityConfigs.ALLOWED_SASL_OAUTHBEARER_URLS_CONFIG; import static org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule.OAUTHBEARER_MECHANISM;+import static org.apache.kafka.test.TestUtils.tempFile; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertInstanceOf;  public class DefaultJwtValidatorTest extends OAuthBearerTest { +    @AfterEach+    public void tearDown() {+        System.clearProperty(ALLOWED_SASL_OAUTHBEARER_URLS_CONFIG);+    }+     @Test     public void testConfigureWithVerificationKeyResolver() {         AccessTokenBuilder builder = new AccessTokenBuilder()@@ -51,6 +63,26 @@ public class DefaultJwtValidatorTest extends OAuthBearerTest {         assertInstanceOf(ClientJwtValidator.class, jwtValidator.delegate());     } +    @Test+    public void testConfigureWithJwksUrl() throws Exception {+        PublicJsonWebKey jwk = createRsaJwk();+        AccessTokenBuilder builder = new AccessTokenBuilder()+            .jwk(jwk)+            .alg(AlgorithmIdentifiers.RSA_USING_SHA256);+        String accessToken = builder.build();++        JsonWebKeySet jwks = new JsonWebKeySet(jwk);+        String jwksJson = jwks.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);+        String fileUrl = tempFile(jwksJson).toURI().toString();+        System.setProperty(ALLOWED_SASL_OAUTHBEARER_URLS_CONFIG, fileUrl);+        Map<String, ?> configs = getSaslConfigs(SaslConfigs.SASL_OAUTHBEARER_JWKS_ENDPOINT_URL, fileUrl);++        DefaultJwtValidator jwtValidator = new DefaultJwtValidator();+        assertDoesNotThrow(() -> jwtValidator.configure(configs, OAUTHBEARER_MECHANISM, getJaasConfigEntries()));+        assertInstanceOf(BrokerJwtValidator.class, jwtValidator.delegate());+        assertDoesNotThrow(() -> jwtValidator.validate(accessToken));+    }+     private CloseableVerificationKeyResolver createVerificationKeyResolver(AccessTokenBuilder builder) {         return (jws, nestingContext) -> builder.jwk().getPublicKey();     }
clients/src/test/java/org/apache/kafka/common/security/oauthbearer/OAuthBearerValidatorCallbackHandlerTest.java
index adabec6..0ecc355 100644@@ -22,9 +22,12 @@ import org.apache.kafka.common.security.oauthbearer.internals.secured.AccessToke import org.apache.kafka.common.security.oauthbearer.internals.secured.CloseableVerificationKeyResolver; import org.apache.kafka.common.security.oauthbearer.internals.secured.OAuthBearerTest; +import org.jose4j.jwk.JsonWebKey.OutputControlLevel; import org.jose4j.jws.AlgorithmIdentifiers;+import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List;@@ -34,7 +37,10 @@ import javax.security.auth.callback.Callback; import javax.security.auth.login.AppConfigurationEntry;  import static org.apache.kafka.common.config.SaslConfigs.SASL_OAUTHBEARER_EXPECTED_AUDIENCE;+import static org.apache.kafka.common.config.SaslConfigs.SASL_OAUTHBEARER_JWKS_ENDPOINT_URL;+import static org.apache.kafka.common.config.internals.BrokerSecurityConfigs.ALLOWED_SASL_OAUTHBEARER_URLS_CONFIG; import static org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule.OAUTHBEARER_MECHANISM;+import static org.apache.kafka.test.TestUtils.tempFile; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull;@@ -44,6 +50,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue;  public class OAuthBearerValidatorCallbackHandlerTest extends OAuthBearerTest { +    @AfterEach+    public void tearDown() {+        System.clearProperty(ALLOWED_SASL_OAUTHBEARER_URLS_CONFIG);+    }+     @Test     public void testBasic() throws Exception {         String expectedAudience = "a";@@ -81,6 +92,38 @@ public class OAuthBearerValidatorCallbackHandlerTest extends OAuthBearerTest {         }     } +    @Test+    public void testDefaultValidatorUsesBrokerValidation() throws Exception {+        AccessTokenBuilder builder = new AccessTokenBuilder()+            .jwk(createRsaJwk())+            .alg(AlgorithmIdentifiers.RSA_USING_SHA256);+        String validAccessToken = builder.build();+        String unsignedAccessToken = createJwt(builder.subject());+        File jwksFile = tempFile("{\"keys\":[" + builder.jwk().toJson(OutputControlLevel.PUBLIC_ONLY) + "]}");+        String jwksEndpointUrl = jwksFile.toURI().toString();+        System.setProperty(ALLOWED_SASL_OAUTHBEARER_URLS_CONFIG, jwksEndpointUrl);++        OAuthBearerValidatorCallbackHandler handler = new OAuthBearerValidatorCallbackHandler();+        handler.configure(+            getSaslConfigs(SASL_OAUTHBEARER_JWKS_ENDPOINT_URL, jwksEndpointUrl),+            OAUTHBEARER_MECHANISM,+            getJaasConfigEntries()+        );++        try {+            OAuthBearerValidatorCallback validCallback = new OAuthBearerValidatorCallback(validAccessToken);+            handler.handle(new Callback[] {validCallback});+            assertNotNull(validCallback.token());++            OAuthBearerValidatorCallback unsignedCallback = new OAuthBearerValidatorCallback(unsignedAccessToken);+            handler.handle(new Callback[] {unsignedCallback});+            assertNull(unsignedCallback.token());+            assertEquals("invalid_token", unsignedCallback.errorStatus());+        } finally {+            handler.close();+        }+    }+     @Test     public void testInvalidAccessToken() throws Exception {         // There aren't different error messages for the validation step, so these are all the 

Trajectory