From da1ab4d3f3039262442bcf788579ada497360a1b Mon Sep 17 00:00:00 2001 From: dongjiao Date: Thu, 28 Aug 2025 18:24:27 +0800 Subject: [PATCH] Fix CVE-2023-25194 --- 0018-CVE-2023-25194.patch | 224 ++++++++++++++++++++++++++++++++++++++ kafka.spec | 5 +- 2 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 0018-CVE-2023-25194.patch diff --git a/0018-CVE-2023-25194.patch b/0018-CVE-2023-25194.patch new file mode 100644 index 0000000..a0f0c47 --- /dev/null +++ b/0018-CVE-2023-25194.patch @@ -0,0 +1,224 @@ +From 9bf012532d6dbac21efd0b184da803e4e3afd25e Mon Sep 17 00:00:00 2001 +From: atusharm +Date: Tue, 8 Apr 2025 12:27:31 +0530 +Subject: [PATCH] Fix Patch: CVE-2023-25194 for Kafka 2.8.2 + +--- + .../kafka/common/security/JaasContext.java | 22 ++++++ + .../kafka/common/security/JaasUtils.java | 8 +-- + .../common/security/JaasContextTest.java | 72 +++++++++++++++---- + 3 files changed, 86 insertions(+), 16 deletions(-) + +diff --git a/clients/src/main/java/org/apache/kafka/common/security/JaasContext.java b/clients/src/main/java/org/apache/kafka/common/security/JaasContext.java +index 48216a8a90..dddf9f179c 100644 +--- a/clients/src/main/java/org/apache/kafka/common/security/JaasContext.java ++++ b/clients/src/main/java/org/apache/kafka/common/security/JaasContext.java +@@ -30,6 +30,11 @@ import java.util.Collections; + import java.util.List; + import java.util.Locale; + import java.util.Map; ++import java.util.Set; ++import java.util.stream.Collectors; ++ ++import static org.apache.kafka.common.security.JaasUtils.DISALLOWED_LOGIN_MODULES_CONFIG; ++import static org.apache.kafka.common.security.JaasUtils.DISALLOWED_LOGIN_MODULES_DEFAULT; + + public class JaasContext { + +@@ -91,11 +96,25 @@ public class JaasContext { + throw new IllegalArgumentException("JAAS config property does not contain any login modules"); + else if (contextModules.length != 1) + throw new IllegalArgumentException("JAAS config property contains " + contextModules.length + " login modules, should be 1 module"); ++ ++ throwIfLoginModuleIsNotAllowed(contextModules[0]); + return new JaasContext(globalContextName, contextType, jaasConfig, dynamicJaasConfig); + } else + return defaultContext(contextType, listenerContextName, globalContextName); + } + ++ private static void throwIfLoginModuleIsNotAllowed(AppConfigurationEntry appConfigurationEntry) { ++ Set disallowedLoginModuleList = Arrays.stream( ++ System.getProperty(DISALLOWED_LOGIN_MODULES_CONFIG, DISALLOWED_LOGIN_MODULES_DEFAULT).split(",")) ++ .map(String::trim) ++ .collect(Collectors.toSet()); ++ String loginModuleName = appConfigurationEntry.getLoginModuleName().trim(); ++ if (disallowedLoginModuleList.contains(loginModuleName)) { ++ throw new IllegalArgumentException(loginModuleName + " is not allowed. Update System property '" ++ + DISALLOWED_LOGIN_MODULES_CONFIG + "' to allow " + loginModuleName); ++ } ++ } ++ + private static JaasContext defaultContext(JaasContext.Type contextType, String listenerContextName, + String globalContextName) { + String jaasConfigFile = System.getProperty(JaasUtils.JAVA_LOGIN_CONFIG_PARAM); +@@ -131,6 +150,9 @@ public class JaasContext { + throw new IllegalArgumentException(errorMessage); + } + ++ for (AppConfigurationEntry appConfigurationEntry : configEntries) { ++ throwIfLoginModuleIsNotAllowed(appConfigurationEntry); ++ } + return new JaasContext(contextName, contextType, jaasConfig, null); + } + +diff --git a/clients/src/main/java/org/apache/kafka/common/security/JaasUtils.java b/clients/src/main/java/org/apache/kafka/common/security/JaasUtils.java +index baff5633a3..50a11edf82 100644 +--- a/clients/src/main/java/org/apache/kafka/common/security/JaasUtils.java ++++ b/clients/src/main/java/org/apache/kafka/common/security/JaasUtils.java +@@ -25,7 +25,8 @@ import javax.security.auth.login.Configuration; + public final class JaasUtils { + private static final Logger LOG = LoggerFactory.getLogger(JaasUtils.class); + public static final String JAVA_LOGIN_CONFIG_PARAM = "java.security.auth.login.config"; +- ++ public static final String DISALLOWED_LOGIN_MODULES_CONFIG = "org.apache.kafka.disallowed.login.modules"; ++ public static final String DISALLOWED_LOGIN_MODULES_DEFAULT = "com.sun.security.auth.module.JndiLoginModule"; + public static final String SERVICE_NAME = "serviceName"; + + public static final String ZK_SASL_CLIENT = "zookeeper.sasl.client"; +@@ -69,8 +70,8 @@ public final class JaasUtils { + + if (foundLoginConfigEntry && !zkSaslEnabled) { + LOG.error("JAAS configuration is present, but system property " + +- ZK_SASL_CLIENT + " is set to false, which disables " + +- "SASL in the ZooKeeper client"); ++ ZK_SASL_CLIENT + " is set to false, which disables " + ++ "SASL in the ZooKeeper client"); + throw new KafkaException("Exception while determining if ZooKeeper is secure " + + zkSecuritySysConfigString()); + } +@@ -78,4 +79,3 @@ public final class JaasUtils { + return foundLoginConfigEntry; + } + } +- +diff --git a/clients/src/test/java/org/apache/kafka/common/security/JaasContextTest.java b/clients/src/test/java/org/apache/kafka/common/security/JaasContextTest.java +index 9e718d8f81..410d8e5d33 100644 +--- a/clients/src/test/java/org/apache/kafka/common/security/JaasContextTest.java ++++ b/clients/src/test/java/org/apache/kafka/common/security/JaasContextTest.java +@@ -30,6 +30,7 @@ import javax.security.auth.login.AppConfigurationEntry; + import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag; + import javax.security.auth.login.Configuration; + ++import static org.apache.kafka.common.security.JaasUtils.DISALLOWED_LOGIN_MODULES_CONFIG; + import static org.junit.jupiter.api.Assertions.assertEquals; + import static org.junit.jupiter.api.Assertions.assertNull; + import static org.junit.jupiter.api.Assertions.assertThrows; +@@ -61,6 +62,7 @@ public class JaasContextTest { + @AfterEach + public void tearDown() throws Exception { + Files.delete(jaasConfigFile.toPath()); ++ System.clearProperty(DISALLOWED_LOGIN_MODULES_CONFIG); + } + + @Test +@@ -71,10 +73,10 @@ public class JaasContextTest { + @Test + public void testControlFlag() throws Exception { + LoginModuleControlFlag[] controlFlags = new LoginModuleControlFlag[] { +- LoginModuleControlFlag.REQUIRED, +- LoginModuleControlFlag.REQUISITE, +- LoginModuleControlFlag.SUFFICIENT, +- LoginModuleControlFlag.OPTIONAL ++ LoginModuleControlFlag.REQUIRED, ++ LoginModuleControlFlag.REQUISITE, ++ LoginModuleControlFlag.SUFFICIENT, ++ LoginModuleControlFlag.OPTIONAL + }; + Map options = new HashMap<>(); + options.put("propName", "propValue"); +@@ -180,6 +182,52 @@ public class JaasContextTest { + checkInvalidConfiguration("test.testInvalidControlFlag { option1=3;"); + } + ++ @Test ++ public void testDisallowedLoginModulesSystemProperty() throws Exception { ++ //test JndiLoginModule is not allowed by default ++ String jaasConfigProp1 = "com.sun.security.auth.module.JndiLoginModule required;"; ++ assertThrows(IllegalArgumentException.class, () -> configurationEntry(JaasContext.Type.CLIENT, jaasConfigProp1)); ++ ++ //test ListenerName Override ++ writeConfiguration(Arrays.asList( ++ "KafkaServer { test.LoginModuleDefault required; };", ++ "plaintext.KafkaServer { com.sun.security.auth.module.JndiLoginModule requisite; };" ++ )); ++ assertThrows(IllegalArgumentException.class, () -> JaasContext.loadServerContext(new ListenerName("plaintext"), ++ "SOME-MECHANISM", Collections.emptyMap())); ++ ++ //test org.apache.kafka.disallowed.login.modules system property with multiple modules ++ System.setProperty(DISALLOWED_LOGIN_MODULES_CONFIG, " com.ibm.security.auth.module.LdapLoginModule , com.ibm.security.auth.module.Krb5LoginModule "); ++ ++ String jaasConfigProp2 = "com.ibm.security.auth.module.LdapLoginModule required;"; ++ assertThrows(IllegalArgumentException.class, () -> configurationEntry(JaasContext.Type.CLIENT, jaasConfigProp2)); ++ ++ //test ListenerName Override ++ writeConfiguration(Arrays.asList( ++ "KafkaServer { test.LoginModuleDefault required; };", ++ "plaintext.KafkaServer { com.ibm.security.auth.module.Krb5LoginModule requisite; };" ++ )); ++ assertThrows(IllegalArgumentException.class, () -> JaasContext.loadServerContext(new ListenerName("plaintext"), ++ "SOME-MECHANISM", Collections.emptyMap())); ++ ++ ++ //Remove default value for org.apache.kafka.disallowed.login.modules ++ System.setProperty(DISALLOWED_LOGIN_MODULES_CONFIG, ""); ++ ++ checkConfiguration("com.sun.security.auth.module.JndiLoginModule", LoginModuleControlFlag.REQUIRED, new HashMap<>()); ++ ++ //test ListenerName Override ++ writeConfiguration(Arrays.asList( ++ "KafkaServer { com.ibm.security.auth.module.LdapLoginModule required; };", ++ "plaintext.KafkaServer { com.sun.security.auth.module.JndiLoginModule requisite; };" ++ )); ++ JaasContext context = JaasContext.loadServerContext(new ListenerName("plaintext"), ++ "SOME-MECHANISM", Collections.emptyMap()); ++ assertEquals(1, context.configurationEntries().size()); ++ checkEntry(context.configurationEntries().get(0), "com.sun.security.auth.module.JndiLoginModule", ++ LoginModuleControlFlag.REQUISITE, Collections.emptyMap()); ++ } ++ + @Test + public void testNumericOptionWithQuotes() throws Exception { + Map options = new HashMap<>(); +@@ -191,31 +239,31 @@ public class JaasContextTest { + @Test + public void testLoadForServerWithListenerNameOverride() throws IOException { + writeConfiguration(Arrays.asList( +- "KafkaServer { test.LoginModuleDefault required; };", +- "plaintext.KafkaServer { test.LoginModuleOverride requisite; };" ++ "KafkaServer { test.LoginModuleDefault required; };", ++ "plaintext.KafkaServer { test.LoginModuleOverride requisite; };" + )); + JaasContext context = JaasContext.loadServerContext(new ListenerName("plaintext"), +- "SOME-MECHANISM", Collections.emptyMap()); ++ "SOME-MECHANISM", Collections.emptyMap()); + assertEquals("plaintext.KafkaServer", context.name()); + assertEquals(JaasContext.Type.SERVER, context.type()); + assertEquals(1, context.configurationEntries().size()); + checkEntry(context.configurationEntries().get(0), "test.LoginModuleOverride", +- LoginModuleControlFlag.REQUISITE, Collections.emptyMap()); ++ LoginModuleControlFlag.REQUISITE, Collections.emptyMap()); + } + + @Test + public void testLoadForServerWithListenerNameAndFallback() throws IOException { + writeConfiguration(Arrays.asList( +- "KafkaServer { test.LoginModule required; };", +- "other.KafkaServer { test.LoginModuleOther requisite; };" ++ "KafkaServer { test.LoginModule required; };", ++ "other.KafkaServer { test.LoginModuleOther requisite; };" + )); + JaasContext context = JaasContext.loadServerContext(new ListenerName("plaintext"), +- "SOME-MECHANISM", Collections.emptyMap()); ++ "SOME-MECHANISM", Collections.emptyMap()); + assertEquals("KafkaServer", context.name()); + assertEquals(JaasContext.Type.SERVER, context.type()); + assertEquals(1, context.configurationEntries().size()); + checkEntry(context.configurationEntries().get(0), "test.LoginModule", LoginModuleControlFlag.REQUIRED, +- Collections.emptyMap()); ++ Collections.emptyMap()); + } + + @Test +-- +2.27.0 + diff --git a/kafka.spec b/kafka.spec index 1bf6c73..c01f62d 100644 --- a/kafka.spec +++ b/kafka.spec @@ -4,7 +4,7 @@ Name: kafka Version: 2.8.2 -Release: 17 +Release: 18 Summary: A Distributed Streaming Platform. License: Apache-2.0 @@ -29,6 +29,7 @@ Patch13: 0014-override-toString.patch Patch14: 0015-SessionWindows-closed-early.patch Patch15: 0016-non-existent-URL.patch Patch16: 0017-fix-log-clean.patch +Patch17: 0018-CVE-2023-25194.patch BuildRequires: systemd java-1.8.0-openjdk-devel Provides: kafka = %{version} @@ -80,6 +81,8 @@ cp -pr licenses/* $RPM_BUILD_ROOT%{kafka_home}/licenses rm -rf %{buildroot} %changelog +* Thu Aug 28 2025 dongjiao - 2.8.2-18 +- Fix CVE-2023-25194. * Fri Dec 08 2023 sundapeng - 2.8.2-17 - log clean relative index range check of group consider empty log segment to avoid too many empty log segment left * Fri Dec 08 2023 sundapeng - 2.8.2-16 -- Gitee