GHSA-hp64-f44f-wjw6: MQTT WebSocket setter ABI mismatch may disclose memory or cause a crash
GHSA ID |
|
|---|---|
CVE ID |
CVE‑2026‑102717 |
Severity |
High |
CVSS score |
7.4 ( |
CWE |
|
Published |
2026‑10‑02 |
Last updated |
2026‑10‑02 |
Affected packages
| Package | Vulnerable versions | Patched versions |
|---|---|---|
NetX Duo |
>= 6.4.4, ⇐ 6.5.1.202602 |
6.5.2.202603 |
Description
Summary
With MQTT over WebSocket enabled, the public nxd_mqtt_client_websocket_set API declares a five argument contract while the internal implementations behind it accepted two further bearer arguments. An application and the library therefore compile incompatible declarations of the same C symbol. At run time the callee reads two arguments the caller never passed and stores them as the WebSocket bearer pointer and length, which a later connection transmits to the configured peer.
Details
The public prototype in nxd_mqtt_client.h takes a client pointer, a host and its length, and a URI path and its length. Both _nxd_mqtt_client_websocket_set and its error checking counterpart _nxde_mqtt_client_websocket_set took those five plus a bearer pointer and a bearer length, and the public name is a macro onto one of the two depending on whether error checking is compiled in. Nothing in the build rejects the mismatch, because the application and the library are separate translation units and the symbol name matches.
The callee reads the sixth and seventh arguments from wherever the ABI places them, which the caller never set, and stores both in the client structure. A subsequent MQTT WebSocket connection passes them to the WebSocket request builder, which treats the pointer as bearer data of the recorded length.
Both error checking and non error checking builds are affected, since both internal functions carried the longer contract.
Impact
The bearer pointer and length are whatever the target ABI leaves in the corresponding registers or stack slots. Reading through that pointer either faults, which denies service, or succeeds and copies unrelated process memory into the request, which sends it to the configured WebSocket peer as bearer credentials.
Which of the two occurs is not controllable and not predictable from the source. It depends on the calling convention of the target and on what the surrounding code left in those locations, so the same application can behave differently on two architectures or between builds.
Affected configurations
A build that defines NXD_MQTT_OVER_WEBSOCKET and an application that calls nxd_mqtt_client_websocket_set. Builds without MQTT over WebSocket never reach the setter, and a build that does not call it is unaffected whatever the ABI.
Releases 6.4.4 through 6.5.1.202602 are affected. The mismatch arrived in 6.4.4, when bearer references were added to the internal setters without the public prototype following.
Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:H, 7.4, High.
Attack complexity is high because neither outcome is under anyone’s control: whether the stale slots hold a faulting address or a readable one is a property of the target ABI and of unrelated surrounding code. The vector is scored for the disclosure reaching the configured peer, which is the more damaging of the two outcomes.
Patches
Fixed in NetX Duo 6.5.2.202603.
Both internal setters return to the five argument contract that the public header has always declared, and the bearer pointer and length are initialised to NX_NULL and zero rather than taken from the caller. No public API changes, so applications need no source change.
The blocking and non-blocking MQTT WebSocket regression tests, netx_mqtt_websocket_block_test and netx_mqtt_websocket_non_block_test, cover the setter and the connection that consumes its result.