HACKERONE

curl: MQTT: Missing upper bound on incoming Remaining Length allows server-controlled long wait_H1:3488278

Description

Curl's MQTT implementation accepts any valid Remaining Length advertised by the server without an explicit upper bound (beyond the MQTT spec maximum of 268,435,455 bytes). A malicious server can send a PUBLISH packet claiming this maximum size but provide only minimal payload, causing curl to wait indefinitely for the remaining data.

This is a low-severity client-side DoS (hang), mitigated by --max-time and --max-filesize. No memory exhaustion occurs as data is processed in small buffered chunks.

##Affected Code:
`lib/mqtt.c` (around line 737)
```c
data->req.size = remlen;
mq->npacket = remlen;
```

##Proof of Concept:

A Malicious MQTT Server Sends a Publish Packet With an Excessive Remaining Length
Although labeled as 0xFF FF FF 7F, which equals 268,435,455 bytes, the system transmits just several bytes. This discrepancy occurs despite the initial size declaration. From time to time, actual data volume stays minimal. Size indications do not always reflect transmitted content. What appears large may carry little information.

Curl accepts the stated Remaining Length without verification, adjusting its expectations accordingly; only when communication ends or time expires does it respond. Though designed to follow protocol, reliance on external signals leaves room for unintended behavior under edge conditions.

Attached screenshots show:
- From beyond, the harmful server transmits an exaggerated Remaining Length
- Logs from curl show remaining data volume: 268435455 bytes

## Impact

- Low severity / protocol hardening issue
- No crash
- No memory corruption
- No excessive memory allocation
- A malicious server can cause curl to wait for a very large transfer
- Partially mitigated by existing options such as --max-time and --max-filesize

##Recommended Hardening:
Apply the same MAX_MQTT_MESSAGE_SIZE limit to incoming packets as is already used for outgoing packets.
```c
if(remlen > MAX_MQTT_MESSAGE_SIZE) {
failf(data, "MQTT message too large (%zu bytes, max %d)",
remlen, MAX_MQTT_MESSAGE_SIZE);
result = CURLE_WEIRD_SERVER_REPLY;
goto end;
}
```
Visit Original Source

Basic Information

ID H1:3488278
Published Jan 6, 2026 at 08:51
Modified Jan 6, 2026 at 08:55

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.