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

CVE-2026-95848: Moquette MQTT Broker Auth Bypass Vulnerability

CVE-2026-95848 is an authentication bypass flaw in Moquette Java MQTT broker that disables security controls when authenticator classes fail to load. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-95848 Overview

Moquette is a lightweight Java Message Queuing Telemetry Transport (MQTT) broker used in Internet of Things (IoT) and messaging deployments. CVE-2026-95848 affects Moquette versions prior to 0.18.1. When the broker cannot load a configured authenticator or authorizator class, Server.initializeAuthenticator and Server.initializeAuthorizatorPolicy silently fall back to AcceptAllAuthenticator or PermitAllAuthorizatorPolicy. A misspelled class name, missing dependency, constructor failure, or classpath problem causes the broker to start with authentication and authorization effectively disabled. Operators who configured access controls receive no runtime rejection and may not detect the permissive fallback until an unauthorized client publishes or subscribes.

Critical Impact

The broker fails open, allowing unauthenticated network clients to publish and subscribe to MQTT topics that operators intended to restrict.

Affected Products

  • Moquette MQTT broker versions prior to 0.18.1
  • Deployments configuring authenticator_class or authorizator_class properties
  • IoT platforms and messaging backends embedding Moquette as a library

Discovery Timeline

  • 2026-09-23 - CVE-2026-95848 published to National Vulnerability Database (NVD)
  • 2026-09-23 - Last updated in NVD database

Technical Details for CVE-2026-95848

Vulnerability Analysis

The vulnerability is a fail-open security design flaw classified as [CWE-636] Not Failing Securely. Moquette's Server startup logic reads authenticator_class and authorizator_class from configuration properties and calls a loadClass helper. When class loading returns null due to any reflection or classpath error, the calling code does not distinguish between the operator-configured-nothing case and the class-load-failed case. Both paths take the default branch that installs AcceptAllAuthenticator and PermitAllAuthorizatorPolicy, permitting all MQTT CONNECT, PUBLISH, and SUBSCRIBE operations from any network client.

Root Cause

The root cause is missing state discrimination in the authenticator and authorizator initialization paths. The code checks whether the resulting policy object is null without also checking whether a class name was configured but failed to instantiate. Any exception during class resolution, constructor invocation, or dependency wiring produces the same outcome as a blank configuration property.

Attack Vector

An unauthenticated remote attacker with network reachability to the MQTT listener can connect, publish arbitrary payloads to any topic, and subscribe to sensitive topics. Exploitation does not require a crafted payload. The attacker only needs the broker to have been started with a broken authenticator configuration. Impact scales with the sensitivity of the data flowing through the broker and any downstream automation triggered by MQTT messages.

java
        String authorizatorClassName = props.getProperty(IConfig.AUTHORIZATOR_CLASS_NAME, "");
        if (authorizatorPolicy == null && !authorizatorClassName.isEmpty()) {
            authorizatorPolicy = loadClass(authorizatorClassName, IAuthorizatorPolicy.class, IConfig.class, props);
            if (authorizatorPolicy == null) {
                throw new IllegalArgumentException("Unable to load configured " + IConfig.AUTHORIZATOR_CLASS_NAME
                    + " '" + authorizatorClassName + "'; rejecting to start. "
                    + "Check the class name and classpath (see the WARN log above for the cause).");
            }
        }

        if (authorizatorPolicy == null) {
// Source: https://github.com/moquette-io/moquette/commit/14a2f4fd280c8f6a791600c306cbccecb7c67007

The patch adds an explicit guard that throws IllegalArgumentException when a configured class fails to load, converting a silent fail-open into a fail-closed startup rejection.

Detect Identity Attacks the Moment Authentication Fails

Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.

Stop Identity Attacks

Detection Methods for CVE-2026-95848

Indicators of Compromise

  • MQTT CONNECT packets accepted from source addresses outside expected client ranges
  • PUBLISH or SUBSCRIBE activity on restricted topics without a preceding authenticated session context
  • Broker log entries containing WARN messages about class loading immediately before successful client connections
  • Unexpected clients using empty or arbitrary client-id, username, or password fields on production listeners

Detection Strategies

  • Parse Moquette startup logs for WARN messages referencing authenticator_class or authorizator_class and correlate with subsequent client acceptance
  • Baseline the set of legitimate MQTT client identifiers and alert on deviation
  • Perform an authenticated post-start health check that attempts a connection with known-invalid credentials; a successful connection indicates fail-open state
  • Monitor for the strings AcceptAllAuthenticator or PermitAllAuthorizatorPolicy appearing in broker logs on hosts intended to enforce access control

Monitoring Recommendations

  • Forward broker startup and connection logs to a centralized logging pipeline for retention and correlation
  • Alert on any MQTT broker restart followed by connection acceptance without matching authentication events
  • Track the software version of every Moquette instance in the estate and flag hosts still running versions prior to 0.18.1

How to Mitigate CVE-2026-95848

Immediate Actions Required

  • Upgrade Moquette to version 0.18.1, which fails startup when a configured authenticator or authorizator class cannot be loaded
  • Audit current broker instances by intentionally attempting connections with invalid credentials to verify authentication is enforced
  • Review Moquette startup logs for prior WARN messages indicating silent class-load failures on production brokers
  • Restrict network exposure of MQTT listeners to trusted client subnets until the upgrade is confirmed

Patch Information

The fix is available in Moquette 0.18.1. The patch modifies broker/src/main/java/io/moquette/broker/Server.java to throw IllegalArgumentException when authenticator_class or authorizator_class is configured but cannot be loaded. See the GitHub Security Advisory GHSA-5f42-97gr-vfhq, the GitHub commit, and the v0.18.1 release notes for full details.

Workarounds

  • Validate the authenticator and authorizator class names and confirm all dependencies are present on the classpath before starting the broker
  • Wrap broker startup with an external smoke test that attempts an unauthorized CONNECT and terminates the process if the connection succeeds
  • Restrict MQTT listener exposure via firewall rules or mutual Transport Layer Security (mTLS) so unauthenticated clients cannot reach the broker
bash
# Post-start verification: an invalid-credential CONNECT should be rejected.
# If this command succeeds, the broker is running in fail-open state.
mosquitto_pub -h broker.example.internal -p 1883 \
    -u invalid_user -P invalid_pass \
    -t 'healthcheck/authz' -m 'probe' \
    && echo 'FAIL-OPEN DETECTED: rotate broker offline and upgrade to 0.18.1'

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.