ActiveMQ Security Hardening: TLS, JAAS, LDAP & CVE Patch Guide

meshIQ May 4, 2026

In October 2023, security researchers published CVE-2023-46604, a CVSS 10.0 remote code execution vulnerability in Apache ActiveMQ. Within days, it was being actively exploited in ransomware campaigns.  The attack required nothing more than network access to port 61616. No authentication, no credentials, no social engineering. The attacker connected to the standard ActiveMQ port and executed arbitrary code on the server.

The organizations hit hardest were those running ActiveMQ with no network segmentation and no patches applied. But patch status aside, many were also running their brokers with default credentials and no authentication, i.e.,  a configuration that creates a second, entirely separate attack surface even when the RCE vulnerability is patched.

This ActiveMQ security hardening guide covers the complete discipline: from patching the known CVEs to configuring transport layer security, JAAS authentication, LDAP authentication, destination-level authorization, admin console hardening security, and network isolation. We cover both Apache ActiveMQ® and Apache Artemis™. Security is the one area where “good enough” is not an engineering position, it is a liability.

Layer Zero: Patch First

Before any security hardening configuration is worth discussing, patch status takes priority. 

CVE-2023-46604: Critical RCE (CVSS 10.0)

The Java OpenWire protocol marshaller in Apache ActiveMQ® was vulnerable to Remote Code Execution. An attacker with network access to a Java-based OpenWire broker or client could run arbitrary shell commands by manipulating serialized class types in the OpenWire protocol, causing the broker to instantiate any class on the classpath. The attack required no authentication and was exploitable via port 61616.

Users of both Apache ActiveMQ® and Apache Artemis™ brokers are recommended to upgrade. Users of any Java-based OpenWire client (e.g., Maven dependency on activemq-client) are also recommended to upgrade regardless of which broker they are using.

Fixed versions: Apache ActiveMQ® 5.15.16, 5.16.7, 5.17.6, 5.18.3, and all later releases.

If immediate patching is not possible, the emergency mitigation is to firewall port 61616 to allow only known, trusted client IP addresses. This does not eliminate the vulnerability but removes unauthenticated internet exposure, which is how the ransomware campaigns operate.

CVE-2022-41678: Jolokia Authenticated RCE

A separate vulnerability in Apache ActiveMQ®: Jolokia, the JMX HTTP bridge that powers the web console, allowed authenticated users to perform Remote Code Execution via the web console. This underscores why default admin credentials are not just a convenience issue: an attacker who obtains the default admin/admin credentials gains RCE capability against unpatched brokers.

Hardening rule: treat CVE patches and credential management as the same category of security hardening requirement. Neither is optional. 

Layer 1: Transport Security: TLS for All Connections

Apache ActiveMQ®: ssl:// and mqtt+nio+ssl://

Transport layer security encrypts all message traffic in transit and, when mutual TLS is configured, authenticates client certificates before the JAAS layer even runs. Properly configured transport layer security prevents eavesdropping, man-in-the-middle attacks, and protects credentials transmitted during broker authentication. 

<!– activemq.xml — production TLS configuration –>
<broker xmlns=”http://activemq.apache.org/schema/core”
        brokerName=”prod-broker”>

  <!– SSL Context: configure once, applies to all SSL transports –>
  <sslContext>
    <sslContext
      keyStore=”/etc/activemq/certs/broker.ks”
      keyStorePassword=”${ssl.keystore.password}”
      trustStore=”/etc/activemq/certs/broker.ts”
      trustStorePassword=”${ssl.truststore.password}”
      keyStoreKeyPassword=”${ssl.key.password}”/>
  </sslContext>

  <transportConnectors>
    <!– Disable plaintext OpenWire — force all clients to TLS –>
    <!– <transportConnector name=”openwire” uri=”tcp://0.0.0.0:61616″/> –>

    <!– TLS OpenWire on standard port 61617 –>
    <transportConnector name=”ssl”
      uri=”ssl://0.0.0.0:61617?maximumConnections=2000
          &amp;transport.enabledProtocols=TLSv1.2,TLSv1.3
          &amp;transport.needClientAuth=false”/>

    <!– TLS MQTT on standard secure port 8883 –>
    <transportConnector name=”mqtt+ssl”
      uri=”mqtt+nio+ssl://0.0.0.0:8883
          ?maximumConnections=5000
          &amp;transport.enabledProtocols=TLSv1.2,TLSv1.3″/>

  </transportConnectors>

</broker>

Password externalization: Never embed keystore passwords as plaintext in activemq.xml. Use Spring property placeholders as shown (${ssl.keystore.password}), resolved from an external credentials.properties file with OS-level file permissions restricting read access to the activemq process user only. From Apache ActiveMQ® 5.4.1, encrypted passwords are supported via the Jasypt integration.

transport.enabledProtocols=TLSv1.2,TLSv1.3: Explicitly restrict transport layer security to TLS 1.2 and 1.3. TLS 1.0 and 1.1 are deprecated in all major security hardening standards and compliance frameworks, they should never be offered by a production broker. 

Keystore Setup

# 1. Generate broker keypair (2048-bit RSA minimum; 4096-bit for high-security)
keytool -genkey -alias broker -keyalg RSA -keysize 4096 \
  -validity 730 -keystore /etc/activemq/certs/broker.ks \
  -storepass “${STOREPASS}” \
  -dname “CN=activemq-broker.internal.example.com,O=ACME Corp,C=US”

# 2. Export broker certificate
keytool -export -alias broker \
  -keystore /etc/activemq/certs/broker.ks \
  -storepass “${STOREPASS}” \
  -file /etc/activemq/certs/broker.crt

# 3. Create client truststore importing broker’s CA certificate
keytool -import -alias broker-ca \
  -keystore /etc/activemq/certs/client.ts \
  -storepass “${STOREPASS}” \
  -file /path/to/ca.crt -noprompt

# 4. Set restrictive file permissions
chmod 600 /etc/activemq/certs/*.ks
chmod 600 /etc/activemq/certs/*.ts
chown activemq:activemq /etc/activemq/certs/*

Apache Artemis™: TLS Acceptor

<!– broker.xml — Artemis TLS acceptors –>
<acceptors>
  <!– Disable plaintext –>
  <!– <acceptor name=”all-protocols”>tcp://0.0.0.0:61616</acceptor> –>

  <!– TLS for all protocols –>
  <acceptor name=”tls”>tcp://0.0.0.0:61617
    ?ssl=true
    &amp;keyStorePath=/etc/activemq/certs/broker.ks
    &amp;keyStorePassword=${ssl.keystore.password}
    &amp;trustStorePath=/etc/activemq/certs/broker.ts
    &amp;trustStorePassword=${ssl.truststore.password}
    &amp;enabledProtocols=TLSv1.2,TLSv1.3
    &amp;needClientAuth=false</acceptor>

  <!– MQTT TLS –>
  <acceptor name=”mqtt-tls”>tcp://0.0.0.0:8883
    ?protocols=MQTT
    &amp;ssl=true
    &amp;keyStorePath=/etc/activemq/certs/broker.ks
    &amp;keyStorePassword=${ssl.keystore.password}
    &amp;enabledProtocols=TLSv1.2,TLSv1.3</acceptor>
</acceptors>

We covered the MQTT-specific TLS setup in detail in our post on ActiveMQ MQTT Protocol Setup Guide

For broker-to-broker TLS on Apache ActiveMQ® network connectors, we covered credential requirements in our Network of Brokers Configuration.

Running ActiveMQ Without TLS or Authentication in Production?

Running ActiveMQ Without TLS or Authentication in Production? Every day, a production broker runs with open plaintext ports and default credentials is a day a breach is one network scan away. meshIQ’s security advisory team can assess your current configuration and deliver a hardening plan tailored to your compliance requirements.

Request a Security Audit

Layer 2: Authentication: JAAS for Apache ActiveMQ®

Choosing the Right Authentication Plugin

Apache ActiveMQ® offers three authentication plugin options:

PluginUse CaseProduction Appropriate?
simpleAuthenticationPluginDev/test, small deployments, plaintext credentials in XMLNo, credentials in XML are visible in version control and process listings
jaasAuthenticationPlugin + PropertiesLoginModuleSmall-to-medium production; credentials in external filesYes, with appropriate file permissions
jaasAuthenticationPlugin + LDAPLoginModuleEnterprise; central user management, Active DirectoryYes, recommended for enterprise deployments

Never use simpleAuthenticationPlugin in production. It embeds credentials directly in activemq.xml in plaintext, which is typically committed to version control and visible in process listings.

Production JAAS Configuration: PropertiesLoginModule

<!– activemq.xml — JAAS authentication + authorization –>
<broker xmlns=”http://activemq.apache.org/schema/core”>
  <plugins>

    <!– JAAS authentication: points to login.config domain name –>
    <jaasAuthenticationPlugin configuration=”activemq-production”/>

    <!– Destination-level authorization –>
    <authorizationPlugin>
      <map>
        <authorizationMap>
          <authorizationEntries>

            <!– Service accounts: scoped to specific destinations –>
            <authorizationEntry queue=”orders.>”
              read=”orders-consumers” write=”orders-producers” admin=”admins”/>
            <authorizationEntry queue=”payments.>”
              read=”payments-consumers” write=”payments-producers” admin=”admins”/>
            <authorizationEntry topic=”events.>”
              read=”event-subscribers” write=”event-publishers” admin=”admins”/>

            <!– Admin: full access for management operations –>
            <authorizationEntry queue=”>”
              read=”admins” write=”admins” admin=”admins”/>
            <authorizationEntry topic=”>”
              read=”admins” write=”admins” admin=”admins”/>

            <!– Advisory topics: MUST have permissive access –>
            <!– Locking this down breaks connections and NoB –>
            <authorizationEntry topic=”ActiveMQ.Advisory.>”
              read=”admins,services” write=”admins,services” admin=”admins,services”/>

          </authorizationEntries>

          <!– Temporary destinations: restrict to admin only –>
          <tempDestinationAuthorizationEntry>
            <tempDestinationAuthorizationEntry
              read=”admins,services”
              write=”admins,services”
              admin=”admins”/>
          </tempDestinationAuthorizationEntry>

        </authorizationMap>
      </map>
    </authorizationPlugin>

  </plugins>
</broker>

# login.config (typically in $ACTIVEMQ_HOME/conf/ or on classpath)
activemq-production {
    org.apache.activemq.jaas.PropertiesLoginModule required
    org.apache.activemq.jaas.properties.user=”users.properties”
    org.apache.activemq.jaas.properties.group=”groups.properties”
    reload=true;
};

# users.properties
# Format: username=password (consider encrypted passwords via Jasypt)
orders-svc=changeme-orders
payments-svc=changeme-payments
admin=changeme-admin

# groups.properties
# Format: groupname=username1,username2
admins=admin
orders-producers=orders-svc
orders-consumers=orders-svc
payments-producers=payments-svc
payments-consumers=payments-svc
services=orders-svc,payments-svc

reload=true in login.config: From Apache ActiveMQ® 5.12 onward, properties files are NOT reloaded automatically unless reload=true is set. Without it, a password change requires a broker restart. Set reload=true to enable live credential updates without restart, important for rotating credentials as part of ongoing hardening security operations. 

The Advisory Topic Authorization Requirement

This is the most frequently encountered authorization misconfiguration in ActiveMQ security hardening. When authorization is enabled, teams often lock down all destinations using a blanket policy, including ActiveMQ.Advisory.>.

The result: client connections begin failing with javax.jms.JMSException: Not authorized even though the user has permission for their actual destination.

Advisory topics are used by ActiveMQ for connection management, temporary destination tracking, and the coordination of a network of brokers. They must have permissive authorization for all roles that connect to the broker. The configuration above handles this correctly with the read=”admins,services” entry on ActiveMQ.Advisory.>. Never use admin=”*” on advisory topics without also including your service account roles.

Apache ActiveMQ®: LDAP Authentication for Enterprise

For organizations with Active Directory or LDAP infrastructure, LDAP authentication via LDAPLoginModule centralizes credential management and eliminates the need to manage properties files per broker, making it the recommended ActiveMQ security hardening approach at enterprise scale: 

<!– activemq.xml — JAAS LDAP plugin –>
<plugins>
  <jaasAuthenticationPlugin configuration=”LdapConfiguration”/>
  <!– authorizationPlugin goes here as above –>
</plugins>

# login.config — LDAP module
LdapConfiguration {
    org.apache.activemq.jaas.LDAPLoginModule required
    debug=false
    initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
    connectionURL=”ldap://ldap.internal.example.com:389″
    connectionUsername=”cn=activemq-bind,ou=Services,dc=example,dc=com”
    connectionPassword=”{SSHA}bindpassword”
    connectionProtocol=s
    authentication=simple
    userBase=”ou=Users,ou=ActiveMQ,ou=systems,dc=example,dc=com”
    userSearchMatching=”uid={0}”
    userSearchSubtree=true
    roleBase=”ou=Groups,ou=ActiveMQ,ou=systems,dc=example,dc=com”
    roleName=cn
    roleSearchMatching=”(member={0})”
    roleSearchSubtree=true;
};

Layer 2: Authentication: Apache Artemis™ Security Settings

Artemis ships with security enabled by default via ActiveMQJAASSecurityManager. The default configuration uses PropertiesLoginModule reading from artemis-users.properties and artemis-roles.properties in the instance’s etc/ directory.

# etc/artemis-users.properties — REPLACE ALL DEFAULT VALUES
# Default content (e.g., admin = ENC(password)) is publicly known
admin = changeme-admin
orders-svc = changeme-orders
payments-svc = changeme-payments

# etc/artemis-roles.properties
admins = admin
orders-producers = orders-svc
orders-consumers = orders-svc
payments-producers = payments-svc
payments-consumers = payments-svc

<!– broker.xml — Artemis security settings (9 permission types vs Classic’s 3) –>
<security-settings>

  <!– Admins: full access to everything –>
  <security-setting match=”#”>
    <permission type=”createNonDurableQueue” roles=”admins”/>
    <permission type=”deleteNonDurableQueue” roles=”admins”/>
    <permission type=”createDurableQueue” roles=”admins”/>
    <permission type=”deleteDurableQueue” roles=”admins”/>
    <permission type=”createAddress” roles=”admins”/>
    <permission type=”deleteAddress” roles=”admins”/>
    <permission type=”consume” roles=”admins”/>
    <permission type=”browse” roles=”admins”/>
    <permission type=”send” roles=”admins”/>
    <permission type=”manage” roles=”admins”/>
  </security-setting>

  <!– Orders namespace: scoped producer + consumer access –>
  <security-setting match=”orders.#”>
    <permission type=”createNonDurableQueue” roles=”admins,orders-consumers”/>
    <permission type=”createDurableQueue” roles=”admins,orders-consumers”/>
    <permission type=”consume” roles=”admins,orders-consumers”/>
    <permission type=”browse” roles=”admins,orders-consumers”/>
    <permission type=”send” roles=”admins,orders-producers”/>
  </security-setting>

  <!– Payments namespace: scoped access –>
  <security-setting match=”payments.#”>
    <permission type=”createNonDurableQueue” roles=”admins,payments-consumers”/>
    <permission type=”createDurableQueue” roles=”admins,payments-consumers”/>
    <permission type=”consume” roles=”admins,payments-consumers”/>
    <permission type=”browse” roles=”admins,payments-consumers”/>
    <permission type=”send” roles=”admins,payments-producers”/>
  </security-setting>

</security-settings>

Apache ActiveMQ® vs Apache Artemis™ permission types: Apache ActiveMQ® uses 3 permission types (read, write, admin). Artemis uses 9 (createNonDurableQueue, deleteNonDurableQueue, createDurableQueue, deleteDurableQueue, createAddress, deleteAddress, send, consume, browse, manage). Artemis’s granularity enables enforcing the principle of least privilege at a much finer level, a key advantage for security hardening in high-compliance environments. 

Layer 3: Admin Console Hardening

The ActiveMQ web console (Hawtio/Jolokia) is a common attack vector. CVE-2022-41678 demonstrated that authenticated console access can lead to RCE. The default credentials (admin/admin) are publicly known, replacing them is the first step of any hardening security exercise. 

Apache ActiveMQ®: Jetty Realm Hardening

# conf/jetty-realm.properties — change IMMEDIATELY on deployment
# Format: username: password, role
admin: changeme-admin, admin
viewer: changeme-viewer, viewer

<!– conf/jetty.xml — restrict web console to internal interfaces –>
<Call name=”addConnector”>
  <Arg>
    <New class=”org.eclipse.jetty.server.ServerConnector”>
      <Arg><Ref refid=”Server”/></Arg>
      <!– Bind to loopback or internal management interface only –>
      <!– Never bind to 0.0.0.0 in production –>
      <Set name=”host”>127.0.0.1</Set>
      <Set name=”port”>8161</Set>
    </New>
  </Arg>
</Call>

Restricting Jolokia Access

Jolokia (the JMX HTTP bridge) is the most sensitive component of the web console. If you do not need external JMX access, restrict Jolokia to localhost only and consider disabling HTTP access entirely in favor of direct JMX:

<!– conf/jolokia-access.xml — restrict to localhost –>
<restrict>
  <remote>
    <!– Only allow access from loopback –>
    <host>127.0.0.1</host>
    <host>::1</host>
  </remote>
  <cors>
    <!– Restrict CORS origins –>
    <allow-origin>http://localhost:8161</allow-origin>
  </cors>
</restrict>

Secure JMX Access Without Exposing the Web Console

meshIQ Console provides secure, role-based monitoring and management of your ActiveMQ brokers, without requiring the Jolokia HTTP bridge to be internet-accessible. All management operations go through meshIQ’s secure API layer.

See It in Action

Layer 4: Network Hardening

Configuration is the foundation, but network architecture is the perimeter. Genuine security hardening requires both. 

Port Restriction

PortProtocolDefault ExposureHardened Exposure
61616OpenWire (TCP)0.0.0.0 (all interfaces)Internal app subnet only; never internet-facing
61617OpenWire (SSL)Not enabled by defaultInternal app subnet only
1883MQTTNot enabled by defaultIoT device network only; never plaintext in prod
8883MQTT (TLS)Not enabled by defaultIoT device network only
5672AMQPNot enabled by defaultInternal app subnet only
8161Web console (HTTP)0.0.0.0Management subnet only; bind to 127.0.0.1 or VPN
1099JMX/RMI0.0.0.0Management subnet only; bind to internal interface

The CVE-2023-46604 lesson: port 61616 exposed to the internet is a critical security hardening failure. Treat it the same as exposing a database port directly to the internet, never acceptable, regardless of the authentication configuration. 

Disabling Unused Transport Connectors

Every enabled transport connector is an attack surface. Disabling connectors for protocols your applications do not use is one of the simplest hardening security wins available: 

<!– activemq.xml — only enable what you actually use –>
<transportConnectors>
  <!– Only TLS OpenWire — all other connectors disabled –>
  <transportConnector name=”ssl” uri=”ssl://0.0.0.0:61617″/>
  <!– Add MQTT only if needed: –>
  <!– <transportConnector name=”mqtt+ssl” uri=”mqtt+nio+ssl://0.0.0.0:8883″/> –>
</transportConnectors>

advisorySupport and Security

If you have locked down advisory topics completely with the authorization plugin, you may observe client connection failures even from properly authorized clients. As we noted in the authorization configuration above, ActiveMQ.Advisory.> must have permissive access for all connecting service accounts.

An alternative for purely static deployments (no network of brokers, no dynamic consumer tracking) is to disable advisorySupport on the broker element: <broker advisorySupport=”false”>. This eliminates advisory topics entirely but also disables the NoB dynamic discovery mechanism. Only consider this if you have verified your applications do not depend on advisory messages.

The ActiveMQ Security Hardening Checklist

Apply every item before a production deployment. This security hardening checklist addresses the most critical risks first. 

Critical (do immediately):

  • Patch to CVE-2023-46604 fixed version (5.15.16+ / 5.16.7+ / 5.17.6+ / 5.18.3+)
  • Change all default credentials (admin/admin console, system/manager broker, artemis-users.properties)
  • Firewall port 61616 to trusted client subnets only, never internet-facing
  • Enable TLS on all transport connectors; disable plaintext equivalents
  • Restrict TLS to versions 1.2 and 1.3 per current security hardening standards 

High (complete within first sprint):

  • Replace simpleAuthenticationPlugin with jaasAuthenticationPlugin + LDAP authentication
  • Configure authorizationPlugin with least-privilege destination entries per service account
  • Ensure ActiveMQ.Advisory.> has permissive authorization for all service roles
  • Bind web console (port 8161) to internal management interface; never 0.0.0.0
  • Restrict Jolokia to localhost only via jolokia-access.xml

Operational (ongoing):

  • Externalize keystore passwords, never plaintext in activemq.xml
  • Set reload=true in login.config for live credential rotation without restart
  • Disable unused transport connectors (STOMP, AMQP, MQTT if not used)
  • Review security advisories at activemq.apache.org/security-advisories on each patch cycle
  • Enable JMX authentication (-Dcom.sun.jmx.remote.authenticate=true)

Security Is Not a One-Time Configuration

ActiveMQ security hardening is not a checkbox, it is an ongoing practice. CVE-2023-46604 was discovered in a broker that had been running in production for years, in organizations with other security controls in place. The specific failure was not firewall coverage, unpatched software, or port exposure in isolation: the combination of all three made exploitation trivial. 

This guide addresses all three categories: patching, configuration, and network isolation. Applying all of them, transport layer security on every connector, LDAP authentication for centralized credential management, and network segmentation aligned with security hardening standards, moves your broker from an easily exploitable default configuration to a defense-in-depth architecture that requires an attacker to defeat multiple independent controls simultaneously. 

meshIQ provides enterprise security hardening assessments for ActiveMQ deployments, covering configuration review, CVE exposure analysis, credential management, and compliance mapping for regulated industries. 

Get your ActiveMQ security configuration reviewed → Request a Security Audit

Frequently Asked Questions

Q1. Is ActiveMQ secure by default? 

No. Apache ActiveMQ® ships with no authentication and known default credentials. Artemis ships with security enabled, but with default credentials that must be replaced immediately. Both require explicit ActiveMQ security hardening before any production deployment. 

Q2. What is CVE-2023-46604, and how do I fix it? 

A CVSS 10.0 RCE vulnerability that allowed unauthenticated attackers to execute code via port 61616 through the OpenWire protocol. Exploited in HelloKitty ransomware campaigns in October 2023. Fix by upgrading to Apache ActiveMQ® 5.15.16, 5.16.7, 5.17.6, or 5.18.3 (or any later version). Emergency mitigation: firewall port 61616 to trusted subnets only.

Q3. How do I enable authentication in ActiveMQ? 

In Apache ActiveMQ®, add a jaasAuthenticationPlugin to the broker’s plugins section and configure login.config with PropertiesLoginModule or, for enterprise environments, LDAP authentication via LDAPLoginModule. In Artemis, security is already enabled. Replace the default credentials in artemis-users.properties and configure security-settings in broker.xml. 

Q4. How do I configure destination authorization in ActiveMQ? 

In Apache ActiveMQ®, add an authorizationPlugin with authorizationEntry elements per destination pattern specifying read, write, and admin role lists. In Artemis, configure security-setting elements in broker.xml with granular permission types (send, consume, browse, createDurableQueue, etc.) per address pattern.

Q5. How do I change the default admin password in ActiveMQ? 

In Apache ActiveMQ®: conf/jetty-realm.properties (web console), conf/credentials.properties (broker connection credentials), and conf/users.properties (JAAS users). In Artemis: etc/artemis-users.properties. Never leave any default credentials in production. CVE-2022-41678 demonstrated that authenticated console access enables RCE on unpatched brokers.

Cookies preferences

Others

Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.

Necessary

Necessary
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.

Advertisement

Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.

Analytics

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.

Functional

Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.

Performance

Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.