Moderate severityNVD Advisory· Published Aug 24, 2015· Updated May 6, 2026
CVE-2015-6524
CVE-2015-6524
Description
The LDAPLoginModule implementation in the Java Authentication and Authorization Service (JAAS) in Apache ActiveMQ 5.x before 5.10.1 allows wildcard operators in usernames, which allows remote attackers to obtain credentials via a brute force attack. NOTE: this identifier was SPLIT from CVE-2014-3612 per ADT2 due to different vulnerability types.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.activemq:activemq-brokerMaven | >= 5.0.0, < 5.10.2 | 5.10.2 |
org.apache.activemq:activemq-jaasMaven | >= 5.0.0, < 5.10.2 | 5.10.2 |
Affected products
2- ghsa-coords2 versions
>= 5.0.0, < 5.10.2+ 1 more
- (no CPE)range: >= 5.0.0, < 5.10.2
- (no CPE)range: >= 5.0.0, < 5.10.2
Patches
122f2f3dde757https://issues.apache.org/jira/browse/AMQ-5345 - improve ldap communication
10 files changed · +225 −10
activemq-broker/src/main/java/org/apache/activemq/network/LdapNetworkConnector.java+10 −2 modified@@ -210,8 +210,16 @@ public void start() throws Exception { env.put(Context.SECURITY_AUTHENTICATION, "none"); } else { LOG.debug(" login credentials [{}:******]", user); - env.put(Context.SECURITY_PRINCIPAL, user); - env.put(Context.SECURITY_CREDENTIALS, password); + if (user != null && !"".equals(user)) { + env.put(Context.SECURITY_PRINCIPAL, user); + } else { + throw new Exception("Empty username is not allowed"); + } + if (password != null && !"".equals(password)) { + env.put(Context.SECURITY_CREDENTIALS, password); + } else { + throw new Exception("Empty password is not allowed"); + } } boolean isConnected = false; while (!isConnected) {
activemq-broker/src/main/java/org/apache/activemq/security/LDAPAuthorizationMap.java+6 −2 modified@@ -469,11 +469,15 @@ protected DirContext open() throws NamingException { try { Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); - if (connectionUsername != null || !"".equals(connectionUsername)) { + if (connectionUsername != null && !"".equals(connectionUsername)) { env.put(Context.SECURITY_PRINCIPAL, connectionUsername); + } else { + throw new NamingException("Empty username is not allowed"); } - if (connectionPassword != null || !"".equals(connectionPassword)) { + if (connectionPassword != null && !"".equals(connectionPassword)) { env.put(Context.SECURITY_CREDENTIALS, connectionPassword); + } else { + throw new NamingException("Empty password is not allowed"); } env.put(Context.SECURITY_PROTOCOL, connectionProtocol); env.put(Context.PROVIDER_URL, connectionURL);
activemq-broker/src/main/java/org/apache/activemq/security/SimpleCachedLDAPAuthorizationMap.java+6 −2 modified@@ -125,11 +125,15 @@ public Thread newThread(Runnable r) { protected DirContext createContext() throws NamingException { Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); - if (connectionUsername != null || !"".equals(connectionUsername)) { + if (connectionUsername != null && !"".equals(connectionUsername)) { env.put(Context.SECURITY_PRINCIPAL, connectionUsername); + } else { + throw new NamingException("Empty username is not allowed"); } - if (connectionPassword != null || !"".equals(connectionPassword)) { + if (connectionPassword != null && !"".equals(connectionPassword)) { env.put(Context.SECURITY_CREDENTIALS, connectionPassword); + } else { + throw new NamingException("Empty password is not allowed"); } env.put(Context.SECURITY_PROTOCOL, connectionProtocol); env.put(Context.PROVIDER_URL, connectionURL);
activemq-jaas/src/main/java/org/apache/activemq/jaas/LDAPLoginModule.java+8 −3 modified@@ -190,7 +190,7 @@ protected boolean authenticate(String username, String password) throws LoginExc try { String filter = userSearchMatchingFormat.format(new String[] { - username + doRFC2254Encoding(username) }); SearchControls constraints = new SearchControls(); if (userSearchSubtreeBool) { @@ -319,7 +319,7 @@ protected List<String> getRoles(DirContext context, String dn, String username, return list; } String filter = roleSearchMatchingFormat.format(new String[] { - doRFC2254Encoding(dn), username + doRFC2254Encoding(dn), doRFC2254Encoding(username) }); SearchControls constraints = new SearchControls(); @@ -459,9 +459,14 @@ protected DirContext open() throws NamingException { env.put(Context.INITIAL_CONTEXT_FACTORY, getLDAPPropertyValue(INITIAL_CONTEXT_FACTORY)); if (isLoginPropertySet(CONNECTION_USERNAME)) { env.put(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME)); + } else { + throw new NamingException("Empty username is not allowed"); } + if (isLoginPropertySet(CONNECTION_PASSWORD)) { env.put(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD)); + } else { + throw new NamingException("Empty password is not allowed"); } env.put(Context.SECURITY_PROTOCOL, getLDAPPropertyValue(CONNECTION_PROTOCOL)); env.put(Context.PROVIDER_URL, getLDAPPropertyValue(CONNECTION_URL)); @@ -484,7 +489,7 @@ private String getLDAPPropertyValue (String propertyName){ private boolean isLoginPropertySet(String propertyName) { for (int i=0; i < config.length; i++ ) { - if (config[i].getPropertyName() == propertyName && config[i].getPropertyValue() != null) + if (config[i].getPropertyName() == propertyName && (config[i].getPropertyValue() != null && !"".equals(config[i].getPropertyValue()))) return true; } return false;
activemq-jaas/src/test/java/org/apache/activemq/jaas/LDAPLoginModuleTest.java+27 −0 modified@@ -41,7 +41,9 @@ import java.util.HashSet; import java.util.Hashtable; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; @RunWith ( FrameworkRunner.class ) @CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port=1024)}) @@ -121,4 +123,29 @@ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallback context.logout(); } + @Test + public void testUnauthenticated() throws LoginException { + LoginContext context = new LoginContext("UnAuthenticatedLDAPLogin", new CallbackHandler() { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (int i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof NameCallback) { + ((NameCallback) callbacks[i]).setName("first"); + } else if (callbacks[i] instanceof PasswordCallback) { + ((PasswordCallback) callbacks[i]).setPassword("secret".toCharArray()); + } else { + throw new UnsupportedCallbackException(callbacks[i]); + } + } + } + }); + try { + context.login(); + } catch (LoginException le) { + assertEquals(le.getCause().getMessage(), "Empty password is not allowed"); + return; + } + fail("Should have failed authenticating"); + } + + }
activemq-jaas/src/test/resources/login.config+19 −0 modified@@ -40,6 +40,25 @@ LDAPLogin { ; }; +UnAuthenticatedLDAPLogin { + org.apache.activemq.jaas.LDAPLoginModule required + debug=true + initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory + connectionURL="ldap://localhost:1024" + connectionUsername="uid=admin,ou=system" + connectionPassword="" + connectionProtocol=s + authentication=simple + userBase="ou=system" + userSearchMatching="(uid={0})" + userSearchSubtree=false + roleBase="ou=system" + roleName=dummyRoleName + roleSearchMatching="(uid={1})" + roleSearchSubtree=false + ; +}; + ExpandedLDAPLogin { org.apache.activemq.jaas.LDAPLoginModule required debug=true
activemq-unit-tests/src/test/java/org/apache/activemq/security/LDAPAuthenticationTest.java+83 −0 added@@ -0,0 +1,83 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.security; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import javax.jms.Connection; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.broker.BrokerFactory; +import org.apache.activemq.broker.BrokerService; +import org.apache.directory.server.annotations.CreateLdapServer; +import org.apache.directory.server.annotations.CreateTransport; +import org.apache.directory.server.core.annotations.ApplyLdifFiles; +import org.apache.directory.server.core.integ.AbstractLdapTestUnit; +import org.apache.directory.server.core.integ.FrameworkRunner; +import org.apache.directory.server.ldap.LdapServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + + +@RunWith( FrameworkRunner.class ) +@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port=1024)}) +@ApplyLdifFiles( + "org/apache/activemq/security/activemq.ldif" +) +public class LDAPAuthenticationTest extends AbstractLdapTestUnit { + + public BrokerService broker; + + public static LdapServer ldapServer; + + @Before + public void setup() throws Exception { + System.setProperty("ldapPort", String.valueOf(getLdapServer().getPort())); + + broker = BrokerFactory.createBroker("xbean:org/apache/activemq/security/activemq-ldap-auth.xml"); + broker.start(); + broker.waitUntilStarted(); + } + + @After + public void shutdown() throws Exception { + broker.stop(); + broker.waitUntilStopped(); + } + + @Test + public void testWildcard() throws Exception { + ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); + Connection conn = factory.createQueueConnection("*", "sunflower"); + try { + conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + } catch (Exception e) { + e.printStackTrace(); + return; + } + fail("Should have failed connecting"); + } +} \ No newline at end of file
activemq-unit-tests/src/test/java/org/apache/activemq/security/LDAPSecurityTest.java+1 −1 modified@@ -44,7 +44,7 @@ @RunWith( FrameworkRunner.class ) -@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP")}) +@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port=1024)}) @ApplyLdifFiles( "org/apache/activemq/security/activemq.ldif" )
activemq-unit-tests/src/test/resources/login.config+19 −0 modified@@ -65,4 +65,23 @@ broker2 { debug=true org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users2.properties" org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties"; +}; + +LDAPLogin { + org.apache.activemq.jaas.LDAPLoginModule required + debug=true + initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory + connectionURL="ldap://localhost:1024" + connectionUsername="uid=admin,ou=system" + connectionPassword=secret + connectionProtocol=s + authentication=simple + userBase="ou=User,ou=ActiveMQ,ou=system" + userSearchMatching="(uid={0})" + userSearchSubtree=false + roleBase="ou=Group,ou=ActiveMQ,ou=system" + roleName=cn + roleSearchMatching="(uid={1})" + roleSearchSubtree=true + ; }; \ No newline at end of file
activemq-unit-tests/src/test/resources/org/apache/activemq/security/activemq-ldap-auth.xml+46 −0 added@@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- START SNIPPET: xbean --> +<beans + xmlns="http://www.springframework.org/schema/beans" + xmlns:amq="http://activemq.apache.org/schema/core" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd + http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> + + <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> + + <broker useJmx="false" xmlns="http://activemq.apache.org/schema/core" persistent="false"> + + <destinations> + <queue physicalName="ADMIN.FOO" /> + </destinations> + + <plugins> + <jaasAuthenticationPlugin configuration="LDAPLogin"/> + </plugins> + + + <transportConnectors> + <transportConnector uri="tcp://localhost:61616"/> + </transportConnectors> + + </broker> + +</beans> +<!-- END SNIPPET: xbean -->
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- activemq.apache.org/security-advisories.data/CVE-2014-3612-announcement.txtnvdVendor AdvisoryWEB
- lists.fedoraproject.org/pipermail/package-announce/2015-October/168094.htmlnvdThird Party AdvisoryWEB
- lists.fedoraproject.org/pipermail/package-announce/2015-October/168651.htmlnvdThird Party AdvisoryWEB
- github.com/advisories/GHSA-23cr-5hr4-rgwvghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2015-6524ghsaADVISORY
- github.com/apache/activemq/commit/22f2f3dde757d31307da772d579815c1d169bc39ghsaWEB
News mentions
0No linked articles in our index yet.