curl/tests/data/test2206
Raymond Steen 2bb5c9b555
mqtt: validate PINGRESP and DISCONNECT have remaining_length == 0
Per MQTT 3.1.1 sections 3.13.1 and 3.14.1, PINGRESP and DISCONNECT fixed
headers must have remaining_length set to zero. The previous code
dispatched to mqtt->nextstate based on the queued state alone without
validating remaining_length for these no-payload packet types, allowing
a malicious broker to send a PINGRESP with non-zero remaining_length
whose trailing bytes would be interpreted as the payload of whatever
message type was queued (CONNACK, SUBACK, etc.).

The exploitation path turned out to be narrow — curl sends data to the
server the user chose to talk to — but the spec violation and the
resulting protocol-state error are real. Reject the malformed packets
with CURLE_WEIRD_SERVER_REPLY before state dispatch.

Reported-by: Raymond Steen <raymond@vortiqxconsilium.com>
Found by VORTIQ-X VXF Framework
Bug: https://hackerone.com/reports/3702718

Signed-off-by: Raymond Steen <raymond@vortiqxconsilium.com>
Closes #21465
2026-04-30 14:14:44 +02:00

59 lines
1.1 KiB
XML

<?xml version="1.0" encoding="US-ASCII"?>
<testcase>
<info>
<keywords>
MQTT
MQTT SUBSCRIBE
</keywords>
</info>
# Server-side
<reply>
<data nocheck="yes">
hello
</data>
# Send a PINGRESP (0xD0) with remaining_length=2 in place of the
# expected CONNACK. MQTT 3.1.1 s. 3.13.1 requires PINGRESP to have
# remaining_length == 0. Curl must reject this with
# CURLE_WEIRD_SERVER_REPLY rather than dispatching to the CONNACK
# handler.
<servercmd>
PINGRESP-as-CONNACK TRUE
</servercmd>
</reply>
# Client-side
<client>
<features>
mqtt
</features>
<server>
mqtt
</server>
<name>
MQTT reject PINGRESP with nonzero remaining_length in place of CONNACK
</name>
<command option="binary-trace">
mqtt://%HOSTIP:%MQTTPORT/%TESTNUMBER
</command>
</client>
# Verify data after the test has been "shot"
<verify>
# Strip out the random part of the client id from the CONNECT message
# before comparison
<strippart>
s/^(.* 00044d5154540402003c000c6375726c).*/$1/
</strippart>
<protocol>
client CONNECT 18 00044d5154540402003c000c6375726c
server PINGRESP-as-CONNACK 2 d0020000
</protocol>
# 8 is CURLE_WEIRD_SERVER_REPLY
<errorcode>
8
</errorcode>
</verify>
</testcase>