Many hobbyists and professionals use common MQTT brokers and libraries, like “Mosquitto”, in their projects. We asked ourselves: are these implementations “safe”? Is there any security issue we can exploit?
This research is joint work with Edoardo Di Paolo and prof. Angelo Spognardi.
Let’s start with a concise overview of the protocol. If you already know MQTT, you can skip to the next part. If you want further details you can read the documentation on the official website.
MQTT is a simple protocol originally meant for telemetry. Very few resources are needed to implement this protocol, so it gained popularity in the IoT world. For example, even a very low-resources Arduino can use MQTT.
Key features of MQTT are:
- publish-subscribe pattern: there is no need for a publisher (e.g., an IoT sensor reading and sending the ambient temperature) to be aware of subscribers (e.g., an air conditioner looking for room temperature) or vice-versa;
- lightweight: minimal number of features and statuses to handle in the protocol itself;
- although lightweight, it has a basic QoS service: three levels (0, 1, and 2) defining the safeness of delivery for each message
- topic-based, with hierarchy and wildcard support
- other minor but useful features: “last-will” message (sent on behalf of the publisher when the connection drops), persistent messages, basic buffering, etc.
MQTT defines three roles in a network:
- publisher: a device sending (“publishing”) messages on one or more topics
- subscriber: a device receiving the message for particular topics (by “subscribing” to topics or wildcards)
- broker: a host in charge of getting published messages delivered to subscribers.
A client can be both publisher and subscriber: for example, an air conditioner might be subscribing to room temperature and sending out its status.
MQTT v3.1.1 is very common, although the latest version is MQTT v5. We will talk about MQTT v3.1.1 – for this post, differences are negligible.
We tested popular libraries for clients (paho, mqttools and mqtt.js) and brokers (Mosquitto, EMQ X, HiveMQ, Moquette, and Aedes) for undefined behaviors, unspecified states, and actions that are expected but not clearly defined in the standard. For these tests, we wrote a Python fuzzer that can emulate both a broker and a client (publisher/subscriber).
We also tested the fuzzer against a physical IoT device, a Shelly light bulb. Shelly uses a software MQTT implementation running on an MCU. While this implementation might be updated/fixed via OTA, this might never happen as users may not be aware of the need for an update by a light bulb.
Results are interesting: we found different violations of the standard, together with mishandling of MQTT states which, in some cases, might cause a Denial-of-Service (in one case, for the entire MQTT network).
Note that our model includes an attacker that can pose as a rouge broker or rogue client (subscriber/publisher). Some attacks are possible only if the attacker can modify the content of MQTT packets of an existing connection.
We didn’t consider TLS as many IoT sensors don’t support it or they have a weak TLS implementation.
The full paper is available here: http://ceur-ws.org/Vol-2940/paper40.pdf
Di Paolo, Edoardo, Enrico Bassetti, and Angelo Spognardi. “Security assessment of common open source MQTT brokers and clients.” – ITASEC Italian Conference on Cybersecurity 2021.