High severityNVD Advisory· Published Aug 24, 2015· Updated May 6, 2026
CVE-2014-3612
CVE-2014-3612
Description
The LDAPLoginModule implementation in the Java Authentication and Authorization Service (JAAS) in Apache ActiveMQ 5.x before 5.10.1 allows remote attackers to bypass authentication by logging in with an empty password and valid username, which triggers an unauthenticated bind. NOTE: this identifier has been SPLIT per ADT2 due to different vulnerability types. See CVE-2015-6524 for the use of wildcard operators in usernames.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.activemq:activemq-brokerMaven | >= 5.0.0, < 5.10.1 | 5.10.1 |
org.apache.activemq:activemq-jaasMaven | >= 5.0.0, < 5.10.1 | 5.10.1 |
Affected products
18cpe:2.3:a:apache:activemq:5.0.0:*:*:*:*:*:*:*+ 17 more
- cpe:2.3:a:apache:activemq:5.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.10.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.3.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.3.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.3.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.4.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.4.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.4.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.4.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.5.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.5.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.6.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.7.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.8.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.9.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:activemq:5.9.1:*:*:*:*:*:*:*
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 by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- activemq.apache.org/security-advisories.data/CVE-2014-3612-announcement.txtnvdVendor AdvisoryWEB
- github.com/advisories/GHSA-72m6-23ff-7q26ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2014-3612ghsaADVISORY
- rhn.redhat.com/errata/RHSA-2015-0137.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2015-0138.htmlnvdWEB
- seclists.org/oss-sec/2015/q1/427nvdWEB
- www.securityfocus.com/bid/72513nvdWEB
- github.com/apache/activemq/commit/22f2f3dde757d31307da772d579815c1d169bc39ghsaWEB
- issues.apache.org/jira/browse/AMQ-5345ghsaWEB
- lists.apache.org/thread.html/a859563f05fbe7c31916b3178c2697165bd9bbf5a65d1cf62aef27d2%40%3Ccommits.activemq.apache.org%3EnvdWEB
- lists.apache.org/thread.html/a859563f05fbe7c31916b3178c2697165bd9bbf5a65d1cf62aef27d2@%3Ccommits.activemq.apache.org%3EghsaWEB
News mentions
0No linked articles in our index yet.