websockets: check for negative payload lengths

- in en- and decoding, check the websocket frame payload lengths for
  negative values (from curl_off_t) and error the operation in that case
- add test 2307 to verify

Closes #12707
This commit is contained in:
Stefan Eissing 2024-01-15 13:02:34 +01:00 committed by Daniel Stenberg
parent 9034a16d97
commit 49ca84144e
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 85 additions and 1 deletions

View File

@ -225,6 +225,10 @@ static CURLcode ws_dec_read_head(struct ws_decoder *dec,
dec->payload_len = (dec->head[2] << 8) | dec->head[3];
break;
case 10:
if(dec->head[2] > 127) {
failf(data, "WS: frame length longer than 64 signed not supported");
return CURLE_RECV_ERROR;
}
dec->payload_len = ((curl_off_t)dec->head[2] << 56) |
(curl_off_t)dec->head[3] << 48 |
(curl_off_t)dec->head[4] << 40 |
@ -410,6 +414,13 @@ static ssize_t ws_enc_write_head(struct Curl_easy *data,
size_t hlen;
ssize_t n;
if(payload_len < 0) {
failf(data, "WS: starting new frame with negative payload length %"
CURL_FORMAT_CURL_OFF_T, payload_len);
*err = CURLE_SEND_ERROR;
return -1;
}
if(enc->payload_remain > 0) {
/* trying to write a new frame before the previous one is finished */
failf(data, "WS: starting new frame with %zd bytes from last one"

View File

@ -81,6 +81,8 @@
2301
2302
2305
# response body seem not to be handled by hyper
2307
%endif
2043
# The CRL test (313) doesn't work with rustls because rustls doesn't support

View File

@ -244,7 +244,7 @@ test2100 \
\
test2200 test2201 test2202 test2203 test2204 test2205 \
\
test2300 test2301 test2302 test2303 test2304 test2305 test2306 \
test2300 test2301 test2302 test2303 test2304 test2305 test2306 test2307 \
\
test2400 test2401 test2402 test2403 test2404 \
\

71
tests/data/test2307 Normal file
View File

@ -0,0 +1,71 @@
<testcase>
<info>
<keywords>
WebSockets
</keywords>
</info>
#
# Sends a PING with overlong payload
<reply>
<data nocheck="yes" nonewline="yes">
HTTP/1.1 101 Switching to WebSockets
Server: test-server/fake
Upgrade: websocket
Connection: Upgrade
Something: else
Sec-WebSocket-Accept: HkPsVga7+8LuxM4RGQ5p9tZHeYs=
%hex[%19%7f%ff%30%30%30%30%30%30%30%30%30%30%30%30]hex%
</data>
# allow upgrade
<servercmd>
upgrade
</servercmd>
</reply>
#
# Client-side
<client>
# require debug for the forced CURL_ENTROPY
<features>
debug
ws
!hyper
</features>
<server>
http
</server>
<name>
WebSockets, overlong PING payload
</name>
<tool>
lib2302
</tool>
<command>
ws://%HOSTIP:%HTTPPORT/%TESTNUMBER
</command>
</client>
#
# PONG with no data and the 32 bit mask
#
<verify>
<protocol nocheck="yes" nonewline="yes">
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: webbie-sox/3
Accept: */*
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: NDMyMTUzMjE2MzIxNzMyMQ==
</protocol>
# 23 == CURLE_WRITE_ERROR
<errorcode>
23
</errorcode>
</verify>
</testcase>