CVE-2026-45541
Description
A NULL-pointer dereference in Espressif's ESP-IDF WebSocket server can be triggered by a malformed header, crashing the device.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A NULL-pointer dereference in Espressif's ESP-IDF WebSocket server can be triggered by a malformed header, crashing the device.
Vulnerability
A NULL-pointer dereference exists in the WebSocket subprotocol-negotiation path of the esp_http_server component within Espressif's ESP-IDF. This vulnerability affects versions 5.2.6, 5.3.5, 5.4.4, 5.5.4, and 6.0. The issue occurs when parsing the Sec-WebSocket-Protocol request header during the WebSocket handshake; a malformed header value can lead to a crash because the tokenization result is dereferenced without a NULL check. This vulnerability is only reachable when the application is built with WebSocket support enabled and registers a WebSocket URI handler that performs subprotocol negotiation [1].
Exploitation
An unauthenticated remote network attacker can exploit this vulnerability by sending a specially crafted Sec-WebSocket-Protocol header during the WebSocket handshake. The attacker needs network access to the HTTP(S) server endpoint. Upon receiving the malformed header, the server will crash before any application-level authentication can occur. Server-side TLS does not mitigate this issue [1].
Impact
Successful exploitation of this vulnerability results in a denial of service, causing the target device to crash. There are no reported information disclosure or write side-effects. The scope of the compromise is limited to crashing the affected server process [1].
Mitigation
This vulnerability has been patched in ESP-IDF versions 5.2.7, 5.3.6, 5.4.5, 5.5.5, and 6.0.1. The fix involves restructuring the parsing loop in httpd_ws_get_response_subprotocol() to include a NULL check before dereferencing the tokenization result. If an upgrade is not immediately possible, exposure can be reduced by registering WebSocket URI handlers without subprotocol negotiation. The specific fix commits are available in references [2], [3], and [4].
AI Insight generated on Jun 10, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
6dc46dc513597fix: fixes websocket server possible null dereference
1 file changed · +7 −4
components/esp_http_server/src/httpd_ws.c+7 −4 modified@@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -80,12 +80,15 @@ static bool httpd_ws_get_response_subprotocol(const char *supported_subprotocol, /* Get first subprotocol from comma seperated list */ char *rest = NULL; char *s = strtok_r(subprotocol, ", ", &rest); - do { - if (strncmp(s, supported_subprotocol, sizeof(subprotocol)) == 0) { + int supported_subprotocol_len = strlen(supported_subprotocol); + while (s != NULL) { + if (strlen(s) == supported_subprotocol_len && + strncmp(s, supported_subprotocol, supported_subprotocol_len) == 0) { ESP_LOGD(TAG, "Requested subprotocol supported: %s", s); return true; } - } while ((s = strtok_r(NULL, ", ", &rest)) != NULL); + s = strtok_r(NULL, ", ", &rest); + } ESP_LOGW(TAG, "Sec-WebSocket-Protocol %s not supported, supported subprotocol is %s", subprotocol, supported_subprotocol);
f88a47e4f37ffix: fixes websocket server possible null dereference
1 file changed · +7 −4
components/esp_http_server/src/httpd_ws.c+7 −4 modified@@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -82,12 +82,15 @@ static bool httpd_ws_get_response_subprotocol(const char *supported_subprotocol, /* Get first subprotocol from comma separated list */ char *rest = NULL; char *s = strtok_r(subprotocol, ", ", &rest); - do { - if (strncmp(s, supported_subprotocol, sizeof(subprotocol)) == 0) { + int supported_subprotocol_len = strlen(supported_subprotocol); + while (s != NULL) { + if (strlen(s) == supported_subprotocol_len && + strncmp(s, supported_subprotocol, supported_subprotocol_len) == 0) { ESP_LOGD(TAG, "Requested subprotocol supported: %s", s); return true; } - } while ((s = strtok_r(NULL, ", ", &rest)) != NULL); + s = strtok_r(NULL, ", ", &rest); + } ESP_LOGW(TAG, "Sec-WebSocket-Protocol %s not supported, supported subprotocol is %s", subprotocol, supported_subprotocol);
9fc0ca13b3b8fix: fixes websocket server possible null dereference
1 file changed · +7 −4
components/esp_http_server/src/httpd_ws.c+7 −4 modified@@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -82,12 +82,15 @@ static bool httpd_ws_get_response_subprotocol(const char *supported_subprotocol, /* Get first subprotocol from comma separated list */ char *rest = NULL; char *s = strtok_r(subprotocol, ", ", &rest); - do { - if (strncmp(s, supported_subprotocol, strlen(supported_subprotocol)) == 0) { + int supported_subprotocol_len = strlen(supported_subprotocol); + while (s != NULL) { + if (strlen(s) == supported_subprotocol_len && + strncmp(s, supported_subprotocol, supported_subprotocol_len) == 0) { ESP_LOGD(TAG, "Requested subprotocol supported: %s", s); return true; } - } while ((s = strtok_r(NULL, ", ", &rest)) != NULL); + s = strtok_r(NULL, ", ", &rest); + } ESP_LOGW(TAG, "Sec-WebSocket-Protocol %s not supported, supported subprotocol is %s", subprotocol, supported_subprotocol);
00a2f7fbbbd8fix: fixes websocket server possible null dereference
1 file changed · +7 −4
components/esp_http_server/src/httpd_ws.c+7 −4 modified@@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -82,12 +82,15 @@ static bool httpd_ws_get_response_subprotocol(const char *supported_subprotocol, /* Get first subprotocol from comma separated list */ char *rest = NULL; char *s = strtok_r(subprotocol, ", ", &rest); - do { - if (strncmp(s, supported_subprotocol, sizeof(subprotocol)) == 0) { + int supported_subprotocol_len = strlen(supported_subprotocol); + while (s != NULL) { + if (strlen(s) == supported_subprotocol_len && + strncmp(s, supported_subprotocol, supported_subprotocol_len) == 0) { ESP_LOGD(TAG, "Requested subprotocol supported: %s", s); return true; } - } while ((s = strtok_r(NULL, ", ", &rest)) != NULL); + s = strtok_r(NULL, ", ", &rest); + } ESP_LOGW(TAG, "Sec-WebSocket-Protocol %s not supported, supported subprotocol is %s", subprotocol, supported_subprotocol);
0dc4ee7537f3fix: fixes websocket server possible null dereference
1 file changed · +7 −4
components/esp_http_server/src/httpd_ws.c+7 −4 modified@@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -82,12 +82,15 @@ static bool httpd_ws_get_response_subprotocol(const char *supported_subprotocol, /* Get first subprotocol from comma separated list */ char *rest = NULL; char *s = strtok_r(subprotocol, ", ", &rest); - do { - if (strncmp(s, supported_subprotocol, strlen(supported_subprotocol)) == 0) { + int supported_subprotocol_len = strlen(supported_subprotocol); + while (s != NULL) { + if (strlen(s) == supported_subprotocol_len && + strncmp(s, supported_subprotocol, supported_subprotocol_len) == 0) { ESP_LOGD(TAG, "Requested subprotocol supported: %s", s); return true; } - } while ((s = strtok_r(NULL, ", ", &rest)) != NULL); + s = strtok_r(NULL, ", ", &rest); + } ESP_LOGW(TAG, "Sec-WebSocket-Protocol %s not supported, supported subprotocol is %s", subprotocol, supported_subprotocol);
37508ab91124fix: fixes websocket server possible null dereference
1 file changed · +7 −4
components/esp_http_server/src/httpd_ws.c+7 −4 modified@@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -82,12 +82,15 @@ static bool httpd_ws_get_response_subprotocol(const char *supported_subprotocol, /* Get first subprotocol from comma separated list */ char *rest = NULL; char *s = strtok_r(subprotocol, ", ", &rest); - do { - if (strncmp(s, supported_subprotocol, sizeof(subprotocol)) == 0) { + int supported_subprotocol_len = strlen(supported_subprotocol); + while (s != NULL) { + if (strlen(s) == supported_subprotocol_len && + strncmp(s, supported_subprotocol, supported_subprotocol_len) == 0) { ESP_LOGD(TAG, "Requested subprotocol supported: %s", s); return true; } - } while ((s = strtok_r(NULL, ", ", &rest)) != NULL); + s = strtok_r(NULL, ", ", &rest); + } ESP_LOGW(TAG, "Sec-WebSocket-Protocol %s not supported, supported subprotocol is %s", subprotocol, supported_subprotocol);
Vulnerability mechanics
Root cause
"A NULL-pointer dereference occurs when parsing the Sec-WebSocket-Protocol header without a prior NULL check."
Attack vector
A remote network attacker can trigger this vulnerability by sending a malformed `Sec-WebSocket-Protocol` request header during the WebSocket handshake. This malformed header causes a NULL-pointer dereference in the `esp_http_server` component. The server crashes before any application-level authentication can occur, leading to a denial of service. This attack is possible when the application is built with WebSocket support and registers a WebSocket URI handler that performs subprotocol negotiation [ref_id=1].
Affected code
The vulnerability resides in the `esp_http_server` component, specifically within the `httpd_ws_get_response_subprotocol()` function located in `components/esp_http_server/src/httpd_ws.c`. The issue arises during the parsing of the `Sec-WebSocket-Protocol` request header during the WebSocket handshake [ref_id=1].
What the fix does
The patch restructures the parsing loop in `httpd_ws_get_response_subprotocol()` to include a NULL check before dereferencing the tokenisation result [ref_id=1]. This ensures that if the header yields no tokens, it is handled gracefully, similar to a request for an unsupported subprotocol. The handshake then completes without a `Sec-WebSocket-Protocol` response header, preventing the crash. Additionally, the fix tightens subprotocol matching from a prefix comparison to an exact-length comparison for improved correctness [ref_id=1].
Preconditions
- configThe application must be built with WebSocket support enabled.
- configAt least one WebSocket URI handler must be registered that performs subprotocol negotiation (i.e., supplies a non-NULL supported_subprotocol).
- networkThe attacker must be able to reach the HTTP(S) server endpoint.
Generated on Jun 10, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/espressif/esp-idf/commit/00a2f7fbbbd8fe6d04729022e1d5c9a49435bfe8nvd
- github.com/espressif/esp-idf/commit/0dc4ee7537f3b12350f5966cecacd59bba840ec6nvd
- github.com/espressif/esp-idf/commit/37508ab91124ef426a7396d30f79eba1162700c7nvd
- github.com/espressif/esp-idf/commit/9fc0ca13b3b85b98d32b98cd9dc8ff9d82642b7bnvd
- github.com/espressif/esp-idf/commit/dc46dc51359749e50617eb70d6f9ae298adc4fffnvd
- github.com/espressif/esp-idf/commit/f88a47e4f37fb11ae4b0908cd5c80059d83198c6nvd
- github.com/espressif/esp-idf/security/advisories/GHSA-3j8v-xgrq-5vg8nvd
News mentions
0No linked articles in our index yet.