Skip to content

Latest commit

 

History

History
671 lines (580 loc) · 40.7 KB

File metadata and controls

671 lines (580 loc) · 40.7 KB

Apache ActiveMQ — Threat Model

STATUS: v0 DRAFT — for ActiveMQ PMC review. This document was drafted for the ActiveMQ maintainers as a starting point they will review, correct, and (if they choose) adopt. It is written in the project's own voice on the assumption that the PMC ratifies it; until then, every claim tagged (inferred) is a proposed answer awaiting maintainer confirmation, not an established project position.

§1 Header

  • Project: Apache ActiveMQ — the 5.x and 6.x message broker and its Java client.
  • Version binding: Written against the currently security-supported lines — 6.2.x and 5.19.x. (documented — SECURITY.md: "Only versions 6.2.x and 5.19.x receive security support"; 5.19.x carries the caveat "Except for EOL dependencies: Spring and Jetty".) A report against an older, unsupported line (5.18.x and earlier, 5.16/5.17) is triaged against that line's behavior but is not eligible for a fix on that line.
  • Date: 2026-07-04
  • Author: ASF Security team, drafted via the threat-model-producer (Scovetta) rubric at the ActiveMQ PMC's request (path 3).
  • Reporting cross-reference: Findings that violate a §8 property should be reported per the project's SECURITY.md and the ASF process at https://www.apache.org/security/. Findings that fall under §3 (out of scope) or §9 (properties not provided) will be closed citing this document. Existing advisories are published at https://activemq.apache.org/security-advisories.
  • Status: Draft / awaiting maintainer review — 2026-07-04.
  • Provenance legend: (documented) = stated in ActiveMQ's own docs, SECURITY.md, website, or default config; (maintainer) = confirmed by a PMC member through this process; (inferred) = reasoned from architecture, default config, or domain knowledge and not yet confirmed — every (inferred) claim has a matching numbered question in §14.
  • Draft confidence: ~54 (documented) citations / 0 (maintainer) / 22 (inferred) tags (mapping to the 10 §14 questions). This is a first public-artifact draft built from ActiveMQ's SECURITY.md, website, and default config; the balance should shift toward (maintainer) as the PMC reacts.

What ActiveMQ is. ActiveMQ is a Java message broker: a long-running server process that accepts connections from message producers and consumers over one or more wire protocols (OpenWire, AMQP, MQTT, STOMP, WebSocket), routes and stores messages on queues and topics, and enforces optional authentication and authorization. It ships a Java client library, a persistence layer (KahaDB or JDBC), a management surface (JMX plus a Jetty-hosted web console), and the ability to link brokers into a network-of-brokers. It is a network-facing daemon, not an in-process library — so the threat model is dominated by the boundary between untrusted network clients and the broker, and by the operator's configuration choices.


§2 Scope and intended use

ActiveMQ is deployed as a standalone or clustered broker daemon, typically as backing message infrastructure for an application or integration layer. It is also embedded in-process (broker + VM transport) inside host applications, and its client library is linked into producers and consumers. (documented — embedded broker and VM transport are first-class documented deployment modes)

Because it is a network service, there is no single "caller". The roles that matter, each with its own trust level:

  • Client / connection (untrusted by default): any party that can open a TCP (or WS/HTTP) connection to an enabled transport connector. Until an authentication plugin is configured, a client is anonymous. (documented — default activemq.xml ships auth/authz plugins disabled)
  • Authenticated principal (semi-trusted): a client that has passed JAAS or SimpleAuthenticationPlugin login and holds a set of group memberships, scoped by authorization entries. (documented — JAAS / authorization docs)
  • Operator / administrator (fully trusted): whoever controls activemq.xml, JAAS config, the filesystem, JMX, and the web console. Treated as trusted-by-design. (documented — SECURITY.md: attacks that require admin access are excluded "since admins can perform any action by design")
  • Peer broker (authenticated but adversarial): the other end of a network-of-brokers link. Holds a legitimate identity but can behave arbitrarily. (inferred — see §14 Q9)

Component-family table

Family Representative entry point Touches outside the process In this model?
OpenWire transport & protocol tcp://0.0.0.0:61616 OpenWire connector; activemq-openwire-legacy Network (untrusted clients) In
Alternate wire protocols AMQP 5672, STOMP 61613, MQTT 1883, WS 61614 connectors Network (untrusted clients) In (when enabled)
JMS ObjectMessage payload deserialization Java serialized message bodies; SERIALIZABLE_PACKAGES allow-list Network → JVM object graph In
Authentication & authorization JAAS login modules, SimpleAuthenticationPlugin, authorizationEntry Filesystem (property files), LDAP In
Web console / management REST Jetty admin app on 8161, Jolokia/JMX-over-REST Network (management plane) In
JMX management surface RMI/JMX MBean server Network / local management In
Persistence store KahaDB files, JDBC store Filesystem / database In (integrity/availability of stored messages)
Network-of-brokers networkConnector broker-to-broker links Network (peer brokers) In
Java client library ActiveMQConnectionFactory, OpenWire client marshaller Network (broker → client) In
Bundled examples / demos / conf/ samples examples/, sample activemq.xml, credentials.properties Varies Out — see §3

§3 Out of scope (explicit non-goals)

  • Deployments that did not configure authentication or authorization. The default distribution ships auth/authz disabled so the sample broker starts out of the box; an unauthenticated-access "exploit" against such a deployment is a configuration gap, not a broker vulnerability. (documented — SECURITY.md: "Exploits that are only possible because users did not configure authentication or authorization" are excluded)
  • Anything requiring administrator access. Admins can perform any action by design; a finding that presupposes admin/operator control (edit activemq.xml, write JAAS files, reach JMX, log into the web console with operator rights) is out of model. (documented — SECURITY.md)
  • Resource-exhaustion (OOM) DoS where the operator did not set the relevant bound. DoS by OOM "because users did not configure a maxDestinations, maxUncommittedCount, maxFrameSize or maxInflatedDataSize" is excluded — the knobs exist and the operator is expected to set them. (documented — SECURITY.md) (The default activemq.xml in fact ships wireFormat.maxFrameSize=10485760.)
  • JMS-specification behaviors that look like access-control gaps but are not: message selectors filtering within a destination the principal is already authorized for; ClientId identifier semantics per the JMS spec; durable-subscription access by an already-authorized connection. (documented — SECURITY.md "not security issues" list)
  • BlobMessage URI fetching. The URIs a BlobMessage references are the client's responsibility to validate; the broker does not vouch for them. (documented — SECURITY.md)
  • Bundled examples, demos, and the sample conf/ files (including the admin/admin web-console credentials and credentials.properties placeholders). These exist for out-of-the-box startup and local experimentation and are not a production posture; they are threat-modeled separately (i.e. not at all as a security guarantee). (confirmed — see §14 Q1)
  • Third-party JAAS back-ends, LDAP servers, JDBC databases, and the JVM/TLS stack themselves. ActiveMQ integrates with them; their own vulnerabilities are out of this model (though our use of them is in scope). (confirmed — see §14 Q2)
  • ActiveMQ Artemis. Separate codebase, separate model. (documented)

§4 Trust boundaries and data flow

The primary trust boundary is the transport connector: the moment bytes arrive from a network client and are unmarshalled into broker-internal protocol commands and message objects. Everything a client sends — protocol frames, headers, destination names, selectors, and message bodies — is untrusted until an authentication plugin has established a principal, and remains authorization-scoped thereafter. (confirmed — see §14 Q3)

Secondary boundaries:

  • Management plane (web console / JMX / Jolokia) vs. broker core. The management surface is intended for operators, not clients; reaching it is a distinct boundary from reaching a transport connector. (confirmed — see §14 Q4)
  • Broker vs. persistence store. KahaDB files and the JDBC database are trusted storage: the broker assumes it is the only writer and that the store has not been tampered with out of band. (confirmed — see §14 Q5)
  • Broker vs. peer broker. A network-of-brokers link crosses into another administrative domain's broker. (confirmed — see §14 Q9)

Reachability precondition per family (the test a triager applies before anything else):

  • OpenWire / AMQP / MQTT / STOMP / WS finding — in-model only if reachable from bytes an unauthenticated or authenticated client can send to an enabled connector. A finding in activemq-openwire-legacy reachable from a crafted OpenWire command is the canonical in-model case (this is the CVE-2023-46604 class). (documented — advisory history)
  • ObjectMessage deserialization finding — in-model only if the offending class is inside the configured SERIALIZABLE_PACKAGES allow-list (or the operator/client has widened it). A gadget outside the allow-list that is nonetheless deserialized is a VALID allow-list-bypass finding; a gadget the operator explicitly allow-listed is out of model. (documented — allow-list docs; see §11a)
  • Authorization finding — in-model only if a principal reaches a destination or operation their granted read/write/admin entries should forbid. (documented — authorization docs)
  • Web-console / JMX finding — in-model only if reachable without operator credentials on a surface intended to require them. (confirmed — see §14 Q4)

§5 Assumptions about the environment

  • Runtime: a JVM of the version the release line targets, with a conformant TLS provider. Java serialization semantics are assumed to be the standard JDK's. (confirmed — see §14 Q6)
  • Clock / TLS: message expiry, TLS certificate validation, and JAAS credential checks assume a correct system clock and a correctly configured trust store. (confirmed — see §14 Q6)
  • Filesystem: the KahaDB data directory, JAAS property files (users.properties, groups.properties), keystores, and activemq.xml are on storage writable only by the broker's OS user and trusted operators. The broker assumes exclusive ownership of its KahaDB directory. (confirmed — see §14 Q5)
  • Network placement: the broker expects the operator to place it behind appropriate network controls; the project's stance is defense-in-depth (authentication, SSL/TLS, network restrictions, OS-level permissions) and the defaults are for developer testing, not production. (documented — SECURITY.md: "Users are expected to secure their environments")
  • Credential reload: from 5.12 onward, JAAS property files are re-read only if reload=true is set; otherwise credentials are read once at startup. An operator who expects live credential revocation without that flag is mis-assuming. (documented — security docs)

What the broker does to its host (negative-side-effect inventory). The broker does open listening sockets (per enabled connectors), open outbound sockets (network-of-brokers, LDAP, JDBC, BlobMessage fetch by clients), read and write its KahaDB directory, read environment (ACTIVEMQ_OPTS, ACTIVEMQ_HOME), and start a JMX/RMI server and a Jetty container when those are enabled. It is a full daemon and makes no "no-side-effects" promise. The relevant question for an integrator is not whether it touches the host but which connectors and management surfaces are enabled. (confirmed — see §14 Q7)

§5a Build-time and configuration variants

ActiveMQ's security envelope is dominated by runtime configuration, and several load-bearing knobs ship in their less-secure state so the sample broker starts unattended. This is the crux of the model: most "vulnerabilities" reported against a default install are configuration gaps (§3), and the maintainer stance below is what licenses that call.

Knob Default Effect on the model Maintainer stance
Authentication plugin (JAAS / SimpleAuthenticationPlugin) disabled in sample activemq.xml With it off, all clients are anonymous Dev-convenience; operator must enable — (documented, SECURITY.md)
Authorization plugin (authorizationPlugin / authorizationEntry) disabled in sample config With it off, any connected client can use any destination Dev-convenience; operator must enable — (documented)
Enabled transport connectors only OpenWire tcp://0.0.0.0:61616 enabled; AMQP/STOMP/MQTT/WS commented out Each enabled connector is a new untrusted surface Operator opts in per protocol — (documented, default config)
wireFormat.maxFrameSize 10485760 (10 MB) in default OpenWire URI Caps a single frame; unset → unbounded-frame OOM Operator-tunable; OOM when unset is out of model — (documented, SECURITY.md)
maxInflatedDataSize operator-set Caps decompressed payload; unset → decompression-bomb OOM Operator must set; OOM when unset is out of model — (documented, SECURITY.md)
org.apache.activemq.SERIALIZABLE_PACKAGES (via ACTIVEMQ_OPTS) a default broker-necessary allow-list Widening (esp. =*) re-opens ObjectMessage RCE Narrow list is the supported posture; * is explicitly unsafe — (documented)
Client setTrustAllPackages(true) / setTrustedPackages(...) trustAll off; default trusted list Client-side deserialization allow-list; trustAll disables it For testing only per docs — (documented)
Web-console authenticate (jetty.xml) + jetty-realm.properties console present, admin/admin sample creds Unauthenticated or default-cred console = full operator access Operator must change creds / enable auth / restrict — (documented, web-console docs)
Anonymous access (anonymousAccessAllowed) off unless set (5.4.0+) Permits unauthenticated connections as anonymous Explicit operator opt-in — (documented)
SSL/TLS vs. plain connectors plain TCP OpenWire in default config Plain connectors carry traffic unencrypted Operator chooses ssl:///nio+ssl:// for production — (documented)

Insecure-default ruling. Per SECURITY.md, the disabled-auth/authz and unset-resource-bound defaults are dev-conveniences the operator is expected to change, so a report against them is OUT-OF-MODEL: non-default-build (non-default posture), not VALID. This ruling reshapes §8, §10, §11a, and §13 and is confirmed documented — but §14 Q1/Q8 ask the PMC to ratify the exact boundary (e.g. is the admin/admin web-console credential in the same bucket?).


§6 Assumptions about inputs

The broker accepts protocol frames from network clients, message bodies (including serialized Java objects), management requests, JAAS credentials, and peer-broker traffic. The following table is the per-surface trust matrix a triager uses to look up a specific reported sink.

Surface / message Parameter Attacker-controllable? Caller/operator must enforce
OpenWire connector (:61616) protocol command bytes, class-type fields yes (any client to enabled connector) enable authn; keep SERIALIZABLE_PACKAGES narrow; patch OpenWire marshaller
OpenWire / all connectors frame size yes set wireFormat.maxFrameSize
Compressed payloads inflated size yes set maxInflatedDataSize
Any connector destination name, headers, selector string yes authorization entries; treat selectors as filters not access control
ObjectMessage body serialized Java object graph yes allow-list packages; never SERIALIZABLE_PACKAGES=* in production
BlobMessage referenced URI yes (from producer) client validates URI before fetch
AMQP / MQTT / STOMP / WS protocol-specific frames yes (when enabled) enable authn; per-protocol limits
JAAS login username / password / TLS cert yes correct login-module config; reload=true for live revocation
Authorization principal's group memberships derived from trusted JAAS back-end keep JAAS store authoritative
Web console / Jolokia (:8161) HTTP requests, MBean operations yes if reachable require auth; change default creds; restrict network
JMX MBean invocations yes if RMI port exposed restrict/authenticate JMX; do not expose
Network-of-brokers peer commands, forwarded messages yes (peer is adversarial) authenticate the link; scope forwarded destinations
KahaDB / JDBC store on-disk / in-DB records no — trusted storage OS/DB permissions; exclusive broker ownership

Size/shape/rate: messages are streamed and may be large; the broker relies on maxDestinations, maxUncommittedCount, maxFrameSize, maxInflatedDataSize, maximumConnections (default 1000 on the sample OpenWire connector), producer flow control, and memory/store limits to bound resource use — all of which are operator-tuned. (documented for the named knobs; §14 Q8 for the completeness of this list)


§7 Adversary model

Primary in-scope adversary: a network client that can reach an enabled transport connector on a broker where the operator has configured authentication and authorization. The adversary may be fully unauthenticated (if the operator allows anonymous or a connector is exposed) or an authenticated low-privilege principal trying to exceed their granted read/write/admin scope. Capabilities: send arbitrary protocol frames and message bodies, open many connections, craft malformed or oversized frames, craft serialized-object payloads, and replay. (confirmed — see §14 Q3)

Also in scope: a network attacker on the path of a plaintext connector (observe/modify traffic where TLS was not used — though the operator's choice to run plaintext bounds this), and an authenticated-but-Byzantine peer broker on a network-of-brokers link. (confirmed — see §14 Q3, Q9)

Explicitly out of scope:

  • The operator/administrator. Anyone who can edit activemq.xml, write JAAS files, reach JMX, or log into the web console as operator has already won — admin actions are by design. (documented — SECURITY.md)
  • A client attacking a broker with auth/authz turned off. That is a configuration gap, not an adversary the model defends against. (documented)
  • A local attacker with filesystem access to the KahaDB directory, keystores, or credential files. Storage is trusted. (confirmed — see §14 Q5)
  • Attackers exploiting the operator's failure to set documented resource bounds. OOM from unset maxUncommittedCount, maxDestinations, maxFrameSize/maxInflatedDataSize is excluded. (documented)

§8 Security properties the project provides

Each property holds only under the configuration the operator is expected to apply (§5a, §10). "Given valid configuration" below means: an authentication plugin is enabled, an authorization plugin with appropriate entries is enabled, resource bounds are set, and SERIALIZABLE_PACKAGES is kept narrow.

  1. Client authentication. Given a configured JAAS or SimpleAuthenticationPlugin, the broker rejects connections that do not present valid credentials (or a valid TLS client cert, per config). Violation symptom: an unauthenticated connection performs authenticated-only operations. Severity: security-critical (auth bypass → CVE). (documented — authentication docs)
  2. Destination authorization. Given a configured authorization plugin, a principal may only read/write/admin destinations permitted by its group's authorizationEntry set (wildcards included), and advisory-topic access follows the documented rules. Violation symptom: a principal consumes from / produces to / creates a destination outside its granted scope. Severity: security-critical (authz bypass → CVE). (documented — authorization docs)
  3. Deserialization allow-listing for ObjectMessage. With the default (or a narrowed) SERIALIZABLE_PACKAGES list, the broker and client refuse to deserialize classes outside the allow-list, blocking arbitrary-gadget ObjectMessage RCE. Violation symptom: a class outside the configured allow-list is instantiated during message unmarshalling. Severity: security-critical (RCE — this control exists because of CVE-2015-5254). (documented — allow-list docs) 3a. OpenWire protocol unmarshalling does not instantiate arbitrary classpath classes. The OpenWire marshaller must not be coercible into reflectively constructing attacker-named classes from protocol fields. Violation symptom: a crafted OpenWire command causes arbitrary class instantiation / command execution. Severity: security-critical (this is the CVE-2023-46604 class; the property is the post-fix guarantee). (documented — advisory history)
  4. Transport confidentiality/integrity when TLS is configured. On ssl:// / nio+ssl:// connectors with a correct keystore/truststore, client-broker (and broker-broker) traffic is encrypted and the endpoint authenticated. Violation symptom: traffic readable/modifiable on a connector configured for TLS, or accepted cert that should be rejected. Severity: security-critical. (documented — SSL transport docs)
  5. Management-surface access control when enabled. With web-console authentication enabled and non-default credentials, and with JMX restricted, the management plane is reachable only by operators. Violation symptom: an unauthenticated party reads/mutates broker state via the console, Jolokia, or JMX on a surface configured to require auth. Severity: security-critical. (inferred — see §14 Q4)
  6. Resource bounds are honored once set. When the operator sets maxUncommittedCount, maxDestinations, maxFrameSize, maxInflatedDataSize, maximumConnections, memory/store limits, and flow control, the broker enforces them; a single client cannot exceed the configured frame/inflation/connection ceilings. Violation symptom: the broker exceeds a configured bound (accepts an oversized frame, inflates past the cap). Severity: security-relevant (DoS) only when a bound is set and breached; unset-bound OOM is out of model per §3. (documented — SECURITY.md, default config)
  7. Message durability/integrity of the persistence store. Given exclusive, uncorrupted storage, persistent messages survive restart and are delivered per their QoS. Violation symptom: acknowledged persistent messages lost or corrupted absent hardware/OS fault. Severity: correctness-critical (data loss); not a confidentiality/authz property. (confirmed — see §14 Q5)

§9 Security properties the project does not provide

  • No security from the default distribution. Out of the box the broker has authentication and authorization disabled and ships sample credentials; it is not secure until configured. The defaults are for developer testing. (documented — SECURITY.md, default config)
  • No protection for operators against themselves. The model provides nothing against an admin, and nothing against a client on an unconfigured broker. (documented)
  • No unbounded-resource defense by default. Without maxUncommittedCount, maxDestinations, maxFrameSize / maxInflatedDataSize (and connection/memory limits) set, a client can drive the broker to OOM; that is explicitly the operator's bound to set. (documented — SECURITY.md)
  • No safety when the deserialization allow-list is widened. Setting SERIALIZABLE_PACKAGES=* or client setTrustAllPackages(true), or allow-listing a package that contains a gadget, re-opens ObjectMessage deserialization RCE. The allow-list is only as safe as its contents. (documented — allow-list docs)
  • No transport security on plaintext connectors. Plain tcp:// OpenWire (the default), and plain AMQP/STOMP/MQTT/WS, carry credentials and message bodies in cleartext; confidentiality/integrity require the operator to choose an SSL variant. (documented — OpenWire docs warn "traffic is unencrypted")

False friends (things that look like a security control but are not):

  • JMS message selectors are a filter, not an access-control boundary. Selectors filter messages within a destination the principal is already authorized for; they do not restrict which destinations a principal may reach. Reporting "a selector let me see a message" on an authorized destination is not a vuln. (documented — SECURITY.md)
  • ClientId is an identifier, not an authentication token. Its behavior follows the JMS spec; do not treat it as proof of identity. (documented — SECURITY.md)
  • The SERIALIZABLE_PACKAGES allow-list is a package gate, not a gadget-chain analysis. It bounds which packages may deserialize; it does not certify that every class in an allowed package is gadget-free. (inferred — see §14 Q10)
  • The web console / Jolokia is a management tool, not a client authorization layer. Reaching it is operator-equivalent; it is not scoped by JMS authorizationEntry permissions. (inferred — see §14 Q4)
  • BlobMessage URIs are not validated by the broker. They look like broker data but the fetch and its target are the client's trust decision. (documented — SECURITY.md)
  • XA Transaction scope lives across connections XA Transactions are designed (by specification) to be resumed or modified across client connections, provided each connection is authenticated and authorized appropriately. XA Transaction Ids are similar to a web session id and are designed to be secret between unrelated clients, hard to guess, and short-lived.

Well-known attack classes left to the caller/operator: Java deserialization gadget-chain RCE (bounded, not eliminated, by the allow-list); SSRF via client-controlled URIs (BlobMessage, and any operator-configured outbound fetch); XXE/entity attacks in any XML the operator feeds the broker; credential-stuffing/brute-force against enabled auth (rate limiting is the operator's); amplification/DoS from unbounded connections or subscriptions when limits are unset. (confirmed except where cited above — see §14 Q10)


§10 Downstream (operator) responsibilities

The broker's §8 properties hold only if the operator/deployer does the following. This is a contract, not a how-to.

  1. Enable authentication (JAAS or SimpleAuthenticationPlugin) before exposing any connector beyond localhost. (documented)
  2. Enable authorization with authorizationEntry rules scoped to least privilege, including correct ActiveMQ.Advisory.> grants. (documented)
  3. Set resource bounds: maxUncommittedCount, maxDestinations, wireFormat.maxFrameSize, maxInflatedDataSize, maximumConnections, memory/store usage limits, and producer flow control. Unset bounds are your DoS exposure, not the broker's bug. (documented)
  4. Keep SERIALIZABLE_PACKAGES as narrow as possible; never =* in production; never setTrustAllPackages(true) outside testing. Only allow-list packages you trust to be gadget-free. (documented)
  5. Patch promptly — especially the OpenWire marshaller (CVE-2023-46604 class) and client library; run a supported line (6.2.x / 5.19.x). (documented — SECURITY.md)
  6. Use TLS (ssl:// / nio+ssl://) for any connector carrying credentials or sensitive payloads; the default plain OpenWire connector is not encrypted. (documented)
  7. Lock down the management plane: change the admin/admin web-console credentials, enable console authentication, do not expose Jolokia/JMX to untrusted networks, and prefer binding the console to a management interface. (documented — web-console docs; §14 Q4 for exact defaults)
  8. Enable only the connectors you need — AMQP/STOMP/MQTT/WS are off by default; each you enable is a new untrusted surface to authenticate and bound. (documented — default config)
  9. Protect storage and credential files: restrict OS permissions on the KahaDB directory, keystores, JAAS property files, and activemq.xml; the broker assumes exclusive, trusted storage. Set reload=true if you need live credential revocation. (documented for reload; §14 Q5 for storage)
  10. Authenticate and scope network-of-brokers links; treat a peer broker as adversarial. (confirmed — see §14 Q9)

§11 Known misuse patterns

  • Running the sample/default broker in production with auth/authz disabled and sample credentials — treating the developer-convenience defaults as a deployment posture. (documented — defaults are for testing)
  • Exposing the OpenWire (or any) connector directly to the public internet without authentication or TLS. (confirmed — see §14 Q3)
  • Widening the deserialization allow-list (SERIALIZABLE_PACKAGES=* or setTrustAllPackages(true)) to "make ObjectMessage work", re-opening RCE. (documented)
  • Treating JMS selectors or ClientId as security controls — using a selector to "hide" messages or a ClientId as authentication. (documented)
  • Leaving the web console / Jolokia / JMX reachable on an untrusted network with default or no authentication. (confirmed — see §14 Q4)
  • Not setting resource bounds and then treating the resulting OOM as a broker vulnerability. (documented)
  • Fetching BlobMessage URIs without client-side validation, enabling SSRF/arbitrary-fetch from the consumer. (documented)

§11a Known non-findings (recurring false positives)

These are patterns scanners, fuzzers, and AI analyzers repeatedly flag that are not bugs under this model. This section is the highest-leverage input for suppressing scan noise.

  • "Authentication/authorization can be bypassed on the default broker." The default ships auth/authz disabled by design; this is OUT-OF-MODEL: non-default-build, licensed by §3 and SECURITY.md. (documented)
  • "Default web-console credentials admin/admin." Sample credential in the distribution meant to be changed; OUT-OF-MODEL: unsupported-component / non-default posture per §3. (documented — sample creds; §14 Q1)
  • "Unbounded memory / OOM on large or compressed messages." If the reporter did not set maxUncommittedCount, maxDestinations, maxFrameSize / maxInflatedDataSize, this is BY-DESIGN: property-disclaimed per §3/§9. If a configured bound is breached, it is VALID. (documented)
  • "Java deserialization RCE via ObjectMessage." If the class is outside a reasonable SERIALIZABLE_PACKAGES list, the allow-list already blocks it — KNOWN-NON-FINDING unless a genuine allow-list bypass is shown (then VALID). If the operator set SERIALIZABLE_PACKAGES=*, it is OUT-OF-MODEL: non-default-build. (documented)
  • "Plaintext credentials/traffic on the OpenWire connector." The default connector is plain TCP by documented design; using TLS is the operator's choice — BY-DESIGN per §9 unless a configured TLS connector fails to encrypt (then VALID). (documented)
  • "A message selector returned a message I filtered on" / "ClientId reuse" / "durable subscriber saw messages" on an authorized destination — explicit non-issues per SECURITY.md; BY-DESIGN per §9. (documented)
  • "BlobMessage SSRF." URI validation is the client's job; BY-DESIGN per §3/§9. (documented)
  • Findings in examples/ or bundled demos. OUT-OF-MODEL: unsupported-component per §3. (inferred — see §14 Q1)
  • CVE history against unsupported lines (5.18.x and earlier). Triaged against that line but not fix-eligible; run a supported line. (documented — SECURITY.md supported-versions)

§12 Conditions that would change this model

  • A new transport protocol or wire-format command, or a change to OpenWire unmarshalling.
  • A change to the default posture — e.g. shipping auth/authz enabled, or changing which connectors or resource bounds default on. (This would move several §11a items from out-of-model toward VALID.)
  • A change to the deserialization allow-list default set or mechanism.
  • A new management surface or a change to web-console / Jolokia / JMX default authentication.
  • A change to the supported-version set in SECURITY.md.
  • Model-incompleteness evidence: any report that cannot be routed to a single §13 disposition is a MODEL-GAP and triggers a revision of §8/§9 rather than an ad-hoc call.

§13 Triage dispositions

Disposition Meaning Licensed by
VALID Violates a §8 property via an in-scope adversary/input on a properly-configured broker (e.g. authz bypass, OpenWire-marshaller RCE, allow-list bypass, TLS failure on a TLS connector, breach of a configured resource bound). §8, §6, §7
VALID-HARDENING No §8 property broken, but the API/config makes a §11 misuse easy enough to warrant hardening. Fixed at maintainer discretion; typically no CVE. §11
OUT-OF-MODEL: trusted-input Requires control of an input the model marks trusted (KahaDB/JDBC store, JAAS back-end data, activemq.xml). §6
OUT-OF-MODEL: adversary-not-in-scope Requires operator/admin access or local filesystem access. §7
OUT-OF-MODEL: unsupported-component Lands in examples/, demos, or sample conf/. §3
OUT-OF-MODEL: non-default-build Only manifests with auth/authz disabled, resource bounds unset, SERIALIZABLE_PACKAGES widened, or other discouraged non-default posture. §5a, §3
BY-DESIGN: property-disclaimed Concerns a property §9 explicitly does not provide (plaintext default, selector-as-ACL, BlobMessage URI, unset-bound OOM). §9
KNOWN-NON-FINDING Matches a §11a recurring false positive. §11a
MODEL-GAP Cannot be routed to any of the above; triggers a §12 revision. §12

§14 Open questions for the maintainers

Each question states a proposed answer for the PMC to confirm, correct, or strike, and names where the answer lands. Grouped in waves.

Wave 1 — scope & the insecure-default boundary (reshapes §3, §5a, §11a, §13):

  1. (→ §3, §11a) We treat the bundled examples/, demos, sample activemq.xml, and the admin/admin web-console credential / credentials.properties placeholders as out of model (developer convenience, not a production posture), so findings there are OUT-OF-MODEL. Is the admin/admin credential specifically in that bucket, or do you consider a shipped default credential a VALID-HARDENING item?

    Users are expected to reset password. The use of admin/admin default credentials is to provide a working out-of-the-box developer and administrator experience.

  2. (→ §3) We put third-party JAAS back-ends, LDAP/JDBC servers, and the JVM/TLS stack out of model (our use of them stays in). Correct?

    Correct, ActiveMQ is a consumer of those systems.

  3. (→ §4, §7, §11) We state the primary trust boundary is the transport connector and the primary adversary is a network client reaching an enabled connector on an auth-configured broker (plus a path-plaintext attacker where TLS was not chosen). Confirm this is the right framing and that "exposing a connector to the internet unauthenticated" is a §11 misuse, not a broker defect.

    Correct.

Wave 2 — management plane & storage (reshapes §4, §5, §8, §9):

  1. (→ §4, §8, §9) We model the web console (Jetty, :8161), Jolokia, and JMX as an operator-only management plane whose access control is separate from JMS authorizationEntry permissions, and we're unsure of the exact shipped defaults (does the console ship with authenticate=true? does it bind to 0.0.0.0 or localhost? is Jolokia exposed by default?). Please confirm the default authentication state and bind address of the management surfaces.

    Jetty and Jolokia are configured to only listen on localhost (127.0.0.1) by default and are configured to require authentication and authorization.

  2. (→ §4, §5, §7, §8) We assume the KahaDB directory, JDBC store, keystores, and credential files are trusted storage with the broker as exclusive writer, and that a local-filesystem attacker is out of scope. Confirm; and confirm that message durability/integrity (§8 #7) is a correctness — not a confidentiality/authz — guarantee.

    Correct.

  3. (→ §5) We assume a conformant JVM, correct system clock, and correctly configured TLS trust store as environmental preconditions. Anything else load-bearing (specific JDK floor per line, RMI/JMX assumptions)?

    Non-localhost network access to RMI/JMX must be secured as an environmental pre-condition. ActiveMQ does not have the ability to control IP filtering, rate limiting or request limits of RMI/JMX operations.

  4. (→ §5) Our "what the broker does to the host" inventory says it opens listening + outbound sockets, owns its KahaDB dir, reads ACTIVEMQ_OPTS, and starts JMX/Jetty when enabled — and makes no no-side-effects promise. Is that inventory complete and correct?

    Yes. Administrators are responsible to ensure proper system sizing and configuration to meet the expected workload. Running out of file descriptors, using too much memory due to high thread counts or running out of disk space through normal broker operations is not a DoS, but a misconfiguration of system sizing to the workload.

Wave 3 — resource bounds, peers, deserialization edges (reshapes §6, §8, §9):

  1. (→ §5a, §6) Is the resource-bound set we list (maxUncommittedCount, maxDestinations, maxFrameSize, maxInflatedDataSize, maximumConnections, memory/store limits, producer flow control) the complete set an operator must set to make DoS in-model, or are there others (per-destination limits, connection-rate limits)? And is "breach of a configured bound" the correct line for VALID vs BY-DESIGN?

    Add 'maximumProducersAllowedPerConnection' and 'maximumConsumersAllowedPerConnection'. Per-destination limits are needed
    for a shared, multi-tenant, or for traffic shaping to settle down noisy neighbors. Valid application traffic causing noisy-neighbor disruption to other applications is not a valid security report for degrading service.

  2. (→ §2, §7, §8, §10) We model a network-of-brokers peer as authenticated-but-adversarial and expect operators to authenticate/scope the link. Do you provide any safety guarantee across a broker link (e.g. forwarded-message authorization), or is a compromised/malicious peer wholly the operator's trust decision?

    Yes, compromised/malicious peer is the operator's trust decision.

    Peer connections are authenticated and authorized with two-way TLS being the recommended security method. Messages cannot be forwarded unless the peer is authenticated and authorized to the destinations.

  3. (→ §9) We frame SERIALIZABLE_PACKAGES as a package-level gate, not a gadget-chain guarantee — an allow-listed package containing a gadget is the operator's risk, and only an allow-list bypass (a class outside the list getting deserialized) is VALID. Confirm this is the right line, and confirm the default trusted-package list is considered gadget-safe by the project.

Correct


End of v0 draft. Provenance counts and every §14 answer should be folded back in as the PMC reviews; promote (inferred)(maintainer) and retire the matching question as each is resolved.