Berkner Tech

MQTT Broker Security for IoT Fleets

MQTT broker security testing pipeline for IoT fleets, from finding the broker to injecting commands

MQTT is the messaging backbone for most IoT fleets: lightweight, pub/sub, and built for thousands of devices talking to one broker. That central broker is also the single richest target in the whole system. If it trusts the wrong client, one connection reads every device and commands every device. Here is how I test an MQTT deployment and how to lock it down.

Why One Broker Is the Whole Fleet

In a pub/sub system every device publishes its status to the broker and subscribes to its commands from the broker. The broker sees all of it. Compromise a single device and you get one device. Compromise the broker’s trust model and you get the fleet: every sensor reading, every location, and every command channel, from one connection.

Step 1: Find the Broker

MQTT listens on 1883 in the clear and 8883 for TLS. A quick scan confirms the endpoint:

nmap -p 1883,8883 broker.example
Example output
PORT     STATE SERVICE
1883/tcp open  mqtt
8883/tcp closed secure-mqtt

Nmap done: 1 IP address (1 host up) scanned in 0.42 seconds

Port 1883 open and 8883 closed is the first finding on its own: this broker is speaking plaintext MQTT with no TLS option.

Step 2: Connect Anonymously and Subscribe to Everything

Try connecting with no credentials and subscribing to the wildcard topic. If the broker allows it, the entire fleet starts streaming to your terminal:

Anatomy of a mosquitto_sub MQTT wildcard subscribe command capturing every topic on the broker
mosquitto_sub -h broker.example -t '#' -v
Example output
fleet/lock-3F/status {"battery":82,"locked":true}
fleet/lock-3F/telemetry {"lat":37.77,"lon":-122.41}
fleet/band-7A/heartrate {"bpm":74}
fleet/cmd/lock-3F {"action":"lock"}

No username, no TLS, and the # wildcard handed over every topic from every device, including live location and the command channel. That is the whole fleet on one screen.

Step 3: From Reading to Controlling

Reading is bad; writing is worse. If the broker lets an anonymous client publish, you can issue commands the devices will obey:

mosquitto_pub -h broker.example \
  -t 'fleet/cmd/lock-3F' -m '{"action":"unlock"}'
Example output
# the wildcard subscriber immediately shows:
fleet/cmd/lock-3F {"action":"unlock"}

The command went through and the lock acted on it. With no per-device authentication and no topic access control, subscribing to read and publishing to control are equally open.

Common MQTT Misconfigurations

The same handful of broker settings cause most of the damage:

Three MQTT broker misconfigurations: anonymous access, wildcard subscribe, and plaintext transport

Securing an MQTT Deployment

Require TLS on the broker and give every device a unique credential, ideally a client certificate, not one shared username for the whole fleet. Enforce per-topic access control so a device can only publish and subscribe to its own topics, and never to the wildcard. With those in place, a stolen device credential exposes one device instead of all of them.

Where This Fits

Reviewing the broker’s authentication, transport, and topic access control, and proving what an anonymous client can actually see and do, is a standard part of an IoT penetration test. That fleet-level testing is the kind of work we do at Berkner Tech.


References and Further Reading