moquette is reachable by untrusted MQTT clients (anonymous by default), so every byte from any client, including pre-authentication, is untrusted. This is a memory-safe JVM: the ceiling is authorization/ACL bypass + denial of service + cross-session integrity, not RCE (I did not find one and do not claim one). Audited at commit da7f719a6bab9829d520b5838e13ea7b1f9be3ef, module broker/.
pattern-based ACLs across tenants. In AuthorizationsCollector.canDoOperation (AuthorizationsCollector.java:116-131, esp. line 123) the clientId/username is substituted raw into a pattern ACL rule and then wildcard-matched, and the clientId is never validated for MQTT wildcard characters +/# at CONNECT (MQTTConnection.processConnect):Topic substitutedTopic = new Topic(auth.topic.toString().replace("%c", client).replace("%u", username)); if (topic.match(substitutedTopic)) return true;
A client that connects with clientId + turns sensor/%c/# into the filter sensor/+/#, gaining cross-tenant read AND write. (Precondition: pattern ACL rules configured — a common multi-tenant setup.)
(High) Crash the whole broker. SessionEventLoop (SessionEventLoop.java:40-54) catches only InterruptedException and is never restarted (SessionEventLoopGroup), so any uncaught exception on it wedges every co-located client. Trivially reachable inputs: malformed $share/grp SUBSCRIBE (SharedSubscriptionUtils.extractShareName -> StringIndexOutOfBoundsException), deeply nested topic (CTrie recursion -> StackOverflowError), and ACL NPE below. Unbounded subscriptions / retained / in-flight / topic-alias / interceptor state (BrokerInterceptor uses an unbounded queue) also allow OOM; durable stores allow disk exhaustion.
(High) NPE in ACL sink on clientId # (invalid filter sensor/#/# -> null tokens -> Topic.match NPE at Topic.java:173).
(High) Will-message authorization bypass. Last-Will topic is published (PostOffice.publishWill) without canWrite/reserved-topic checks used for normal PUBLISH.
(Medium) Cross-session durable corruption. H2PersistentQueue opens queue_"+clientId and queue_"+clientId+"_meta; client id sensor_meta collides with victim sensor metadata map -> corrupts head/tail.
(Medium) Fail-open if authenticator/authorizator class fails to load -> PermitAll/AcceptAll (Server.java:483-531).
Source-only, no network; PoCs run on JDK 17:
Cross-tenant eavesdropping and injection, whole-broker DoS, unauthorized Will publishes, and cross-session durable corruption.
{
"cwe_ids": [],
"github_reviewed": true,
"github_reviewed_at": "2026-09-23T16:11:18Z",
"nvd_published_at": null,
"severity": "CRITICAL"
}