mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(esp_http_server): fail the connection on an oversized WebSocket frame
This commit is contained in:
@@ -673,6 +673,9 @@ static esp_err_t httpd_ws_recv_frame_internal(httpd_req_t *req, httpd_ws_frame_t
|
|||||||
/* When reading entire packet at once, we only accept the incoming packet length that is smaller than the max_len (or it will overflow the buffer!) */
|
/* When reading entire packet at once, we only accept the incoming packet length that is smaller than the max_len (or it will overflow the buffer!) */
|
||||||
if (!partial) {
|
if (!partial) {
|
||||||
ESP_LOGW(TAG, LOG_FMT("WS Message too long"));
|
ESP_LOGW(TAG, LOG_FMT("WS Message too long"));
|
||||||
|
/* The payload is still queued in the socket. Fail the connection
|
||||||
|
* (RFC 6455 §7.4.1, close code 1009) so the session is torn down. */
|
||||||
|
httpd_ws_fail_connection(req, HTTPD_WS_CLOSE_CODE_TOO_BIG);
|
||||||
return ESP_ERR_INVALID_SIZE;
|
return ESP_ERR_INVALID_SIZE;
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, LOG_FMT("WS Message too long. User will have to call read again"));
|
ESP_LOGD(TAG, LOG_FMT("WS Message too long. User will have to call read again"));
|
||||||
|
|||||||
@@ -1072,6 +1072,35 @@ TEST_CASE("WS auto CLOSE reply echoes received payload", "[HTTP SERVER][websocke
|
|||||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_reply, ws_send_capture_ctx.data, sizeof(expected_reply));
|
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_reply, ws_send_capture_ctx.data, sizeof(expected_reply));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("WS recv oversized frame fails connection with CLOSE 1009", "[HTTP SERVER][websocket]")
|
||||||
|
{
|
||||||
|
/* A masked TEXT frame with a 4-byte payload, read with max_len = 2. The frame
|
||||||
|
* does not fit, and the payload is still queued in the socket. The library
|
||||||
|
* must fail the connection (CLOSE 1009). The scripted stream carries a second TEXT frame
|
||||||
|
* after the payload to represent that queued data. */
|
||||||
|
static const uint8_t ws_frame[] = {
|
||||||
|
0x84, 0x00, 0x00, 0x00, 0x00, 'd', 'a', 't', 'a', /* first frame, len 4, zero mask */
|
||||||
|
0x81, 0x80, 0x00, 0x00, 0x00, 0x00 /* a second frame that must never be read */
|
||||||
|
};
|
||||||
|
struct httpd_data hd = {0};
|
||||||
|
httpd_req_t req = {0};
|
||||||
|
struct httpd_req_aux aux = {0};
|
||||||
|
struct sock_db session = {0};
|
||||||
|
httpd_ws_frame_t frame = {0};
|
||||||
|
|
||||||
|
ws_setup_recv_fixture(&hd, &req, &aux, &session, ws_frame, sizeof(ws_frame));
|
||||||
|
aux.ws_type = HTTPD_WS_TYPE_TEXT;
|
||||||
|
aux.ws_final = true;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_SIZE, httpd_ws_recv_frame(&req, &frame, 2));
|
||||||
|
ws_assert_close_sent(&session, 1009);
|
||||||
|
|
||||||
|
/* The library must fail, not drain: only the length byte and the 4 mask
|
||||||
|
* bytes are consumed. The 4 payload bytes and the whole second frame stay
|
||||||
|
* unread. */
|
||||||
|
TEST_ASSERT_EQUAL(5, ws_scripted_recv_ctx.offset);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("WS recv rejects CLOSE frame with 1-byte payload", "[HTTP SERVER][websocket]")
|
TEST_CASE("WS recv rejects CLOSE frame with 1-byte payload", "[HTTP SERVER][websocket]")
|
||||||
{
|
{
|
||||||
/* CLOSE with 1-byte body — always invalid */
|
/* CLOSE with 1-byte body — always invalid */
|
||||||
|
|||||||
Reference in New Issue
Block a user