cURL MQTT客户端剩余长度漏洞分析:服务器可控的长时间等待

本报告揭示了cURL MQTT实现中的一个协议强化问题。恶意服务器可通过声明巨大的“剩余长度”字段,导致cURL客户端无限期等待数据,造成客户端拒绝服务。

HackerOne报告 #3488278 - MQTT:传入剩余长度缺失上限导致服务器可控的长时间等待

报告详情

  • 提交者:gaurav_7777
  • 提交时间:2026年1月6日
  • 报告状态:已公开

漏洞描述

cURL的MQTT实现接受服务器通告的任何有效的“剩余长度”字段,但没有明确的上限约束(仅受MQTT规范最大值268,435,455字节的限制)。恶意服务器可以发送一个声明此最大长度的PUBLISH数据包,但仅提供极少量的实际负载,从而导致cURL无限期地等待剩余数据的到来。

这是一个低严重性的客户端拒绝服务(挂起)问题,可通过--max-time--max-filesize等选项缓解。由于数据是以小块缓冲处理的,不会发生内存耗尽。

受影响的代码

lib/mqtt.c(大约第737行):

1
2
data->req.size = remlen;
mq->npacket = remlen;

概念验证

一个恶意的MQTT服务器发送一个声明了过大剩余长度的PUBLISH数据包。 虽然标记为 0xFF FF FF 7F(等于 268,435,455 字节),但系统仅传输了几个字节。这种不一致发生在初始大小声明之后。大多数情况下,实际数据量保持极少。大小指示并不总是反映传输的内容。看似庞大的数据可能只携带极少信息。 cURL不加验证地接受了声明的剩余长度,并据此调整其预期;只有在通信结束或超时发生时,它才会做出响应。虽然其设计遵循协议,但在边缘情况下依赖外部信号可能导致非预期的行为。

附加的截图显示:

  1. 恶意服务器发送了一个夸大的剩余长度。
  2. cURL日志显示剩余数据量:268435455 字节。

影响

  • 低严重性 / 协议强化问题
  • 无崩溃
  • 无内存损坏
  • 无过多内存分配
  • 恶意服务器可导致cURL等待非常大量的数据传输
  • 部分可由现有选项(如 --max-time--max-filesize)缓解

建议的强化措施

对传入的数据包应用与传出数据包相同的 MAX_MQTT_MESSAGE_SIZE 限制。

1
2
3
4
5
6
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;
}

项目方回应与状态

bagder (curl staff) 于5天前关闭了报告并将状态更改为“不适用”:

这基本上是一种slowloris攻击。服务器也可以只是停止发送,而cURL会坐着等待更多数据。这不是一个安全问题,这是cURL按设计工作的结果。

bagder (curl staff) 于5天前请求公开此报告:

根据项目透明度政策,我们希望所有报告都被公开。

gaurav_7777 于5天前同意公开此报告。该报告随后被公开。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计