Skip to main content
Vulnerability Database/CVE-2026-95843

CVE-2026-95843: Moquette Java MQTT Broker DOS Vulnerability

CVE-2026-95843 is a denial of service flaw in Moquette Java MQTT broker that allows remote clients to crash the event loop via malformed subscription filters. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-95843 Overview

CVE-2026-95843 is a denial of service vulnerability in Moquette, a lightweight Java Message Queuing Telemetry Transport (MQTT) broker. Versions prior to 0.18.1 fail to validate the structure of shared-subscription filters before parsing them. A remote unauthenticated client can send a malformed filter such as $share/grp that lacks the required /{topicFilter} portion. The broker invokes SharedSubscriptionUtils.extractShareName, which throws a StringIndexOutOfBoundsException and terminates command handling on the shared session event loop. All other client sessions assigned to that event loop are denied service. The issue is tracked as [CWE-20] Improper Input Validation and is fixed in version 0.18.1.

Critical Impact

An unauthenticated remote attacker can crash the shared session event loop with a single malformed SUBSCRIBE packet, denying MQTT service to all co-located client sessions.

Affected Products

  • Moquette MQTT Broker versions prior to 0.18.1
  • Java applications embedding the vulnerable Moquette broker library
  • MQTT deployments accepting MQTT 5 SUBSCRIBE packets from untrusted clients

Discovery Timeline

  • 2026-09-23 - CVE-2026-95843 published to the National Vulnerability Database
  • 2026-09-23 - Last updated in NVD database

Technical Details for CVE-2026-95843

Vulnerability Analysis

The vulnerability resides in the PostOffice.subscribe method within the Moquette broker. When a client sends an MQTT 5 SUBSCRIBE packet containing a shared subscription filter, the broker parses the share name by calling SharedSubscriptionUtils.extractShareName before validating the overall $share/{shareName}/{topicFilter} structure.

The extractShareName implementation assumes a / delimiter exists after the share name. When the delimiter is absent, the method executes substring(7, -1), which throws a StringIndexOutOfBoundsException. The uncaught exception propagates up the Netty event loop that services the shared session pipeline. All MQTT client sessions bound to that event loop lose command handling, producing a denial of service condition that extends well beyond the offending connection.

Root Cause

The root cause is improper input validation ([CWE-20]) in the ordering of parsing and validation. SharedSubscriptionUtils.validateShareName only checked the share-name substring after extraction. It never verified that the topic filter contained the second / separator or a non-empty topic-filter component. Any filter matching the $share/ prefix but missing the trailing structure reached the parser before the validator.

Attack Vector

The attack requires network access to the MQTT listener and no authentication, provided the broker accepts anonymous MQTT 5 connections. An attacker establishes an MQTT 5 session and sends a SUBSCRIBE packet containing a topic filter of $share/grp or any other $share/<name> string lacking a trailing /topic. The broker throws the unchecked exception, and the affected event loop stops processing further commands for its assigned sessions.

java
// Patch: PostOffice.java validates the shared-subscription filter
// BEFORE parsing it, and disconnects malformed clients per MQTT-4.13.1-1.

// Validate the shared-subscription format BEFORE parsing it. A filter such as "$share/grp"
// (a share name with no "/{topicFilter}" part) would make extractShareName() evaluate
// substring(7, -1) and throw StringIndexOutOfBoundsException while building the subscription.
// MQTT-4.13.1-1 / MQTT-4.8.2: disconnect on a malformed shared subscription instead.
Optional<MqttTopicSubscription> invalidSharedSubscription = msg.payload().topicSubscriptions().stream()
    .filter(s -> SharedSubscriptionUtils.isSharedSubscription(s.topicFilter()))
    .filter(s -> !SharedSubscriptionUtils.isValidSharedSubscription(s.topicFilter()))
    .findFirst();

if (invalidSharedSubscription.isPresent()) {
    // this is a malformed packet, MQTT-4.13.1-1, disconnect it
    LOG.info("{} used a malformed shared subscription {}, disconnecting",
             clientID, invalidSharedSubscription.get().topicFilter());
    session.disconnectFromBroker();
    return;
}

Source: GitHub Commit affdc71

Detection Methods for CVE-2026-95843

Indicators of Compromise

  • Broker log entries containing StringIndexOutOfBoundsException originating from SharedSubscriptionUtils.extractShareName or PostOffice.subscribe.
  • After the patch, log messages of the form <clientID> used a malformed shared subscription <filter>, disconnecting indicating attempted exploitation.
  • Sudden loss of responsiveness across multiple MQTT client sessions that share a Netty event loop.

Detection Strategies

  • Inspect MQTT SUBSCRIBE packets for topic filters beginning with $share/ that lack a second / separator or a non-empty topic-filter suffix.
  • Correlate StringIndexOutOfBoundsException stack traces in broker logs with client identifiers and source IP addresses from connection logs.
  • Alert on abnormal termination of Netty event-loop threads or spikes in disconnected MQTT sessions clustered in time.

Monitoring Recommendations

  • Forward Moquette broker logs and JVM exception traces to a centralized SIEM or data lake for correlation across sessions and time.
  • Track MQTT session health metrics such as active session count, subscribe error rate, and per-loop command throughput.
  • Monitor network-layer telemetry for repeated SUBSCRIBE traffic from a single source that precedes broker-side exceptions.

How to Mitigate CVE-2026-95843

Immediate Actions Required

  • Upgrade Moquette to version 0.18.1 or later on all broker instances.
  • Restrict network access to the MQTT listener using firewalls or network policies until the upgrade is deployed.
  • Enable client authentication and disable anonymous MQTT connections where operationally feasible.
  • Review broker logs for prior StringIndexOutOfBoundsException events to identify past exploitation attempts.

Patch Information

The fix is included in Moquette 0.18.1. It introduces SharedSubscriptionUtils.isValidSharedSubscription, which validates the full $share/{shareName}/{topicFilter} structure before parsing. Malformed shared subscriptions now trigger a broker-initiated disconnect per MQTT specification clauses MQTT-4.13.1-1 and MQTT-4.8.2. See the GitHub Security Advisory GHSA-5f42-97gr-vfhq, Pull Request #962, and Release v0.18.1 for full details.

Workarounds

  • Terminate MQTT connections at a protocol-aware proxy that rejects SUBSCRIBE payloads with malformed $share/ filters.
  • Disable MQTT 5 support if the deployment can operate on MQTT 3.1.1, which does not process shared subscriptions the same way.
  • Require authenticated clients and use access control lists to limit which principals can issue SUBSCRIBE commands.
bash
# Update Maven dependency to the patched Moquette release
# pom.xml
# <dependency>
#   <groupId>io.moquette</groupId>
#   <artifactId>moquette-broker</artifactId>
#   <version>0.18.1</version>
# </dependency>

mvn versions:set-property -Dproperty=moquette.version -DnewVersion=0.18.1
mvn clean verify

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.