deps: reject interior blanks in Content-Length
Original commit message follows: Before this commit `Content-Length: 4 2` was accepted as a valid header and recorded as `parser->content_length = 42`. Now it is a parse error that fails with error `HPE_INVALID_CONTENT_LENGTH`. Downstream users that inspect `parser->content_length` and naively parse the string value using `strtoul()` might get confused by the discrepancy between the two values. Resolve that by simply not letting it happen. Fixes: https://github.com/nodejs-private/security/issues/178 PR-URL: https://github.com/nodejs-private/http-parser-private/pull/1 Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rod Vagg <rod@vagg.org>
This commit is contained in:
parent
32050065f1
commit
38b48a62b8
19
deps/http_parser/http_parser.c
vendored
19
deps/http_parser/http_parser.c
vendored
@ -370,6 +370,8 @@ enum header_states
|
|||||||
|
|
||||||
, h_connection
|
, h_connection
|
||||||
, h_content_length
|
, h_content_length
|
||||||
|
, h_content_length_num
|
||||||
|
, h_content_length_ws
|
||||||
, h_transfer_encoding
|
, h_transfer_encoding
|
||||||
, h_upgrade
|
, h_upgrade
|
||||||
|
|
||||||
@ -1406,6 +1408,7 @@ reexecute:
|
|||||||
|
|
||||||
parser->flags |= F_CONTENTLENGTH;
|
parser->flags |= F_CONTENTLENGTH;
|
||||||
parser->content_length = ch - '0';
|
parser->content_length = ch - '0';
|
||||||
|
parser->header_state = h_content_length_num;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case h_connection:
|
case h_connection:
|
||||||
@ -1493,10 +1496,18 @@ reexecute:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case h_content_length:
|
case h_content_length:
|
||||||
|
if (ch == ' ') break;
|
||||||
|
h_state = h_content_length_num;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case h_content_length_num:
|
||||||
{
|
{
|
||||||
uint64_t t;
|
uint64_t t;
|
||||||
|
|
||||||
if (ch == ' ') break;
|
if (ch == ' ') {
|
||||||
|
h_state = h_content_length_ws;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (UNLIKELY(!IS_NUM(ch))) {
|
if (UNLIKELY(!IS_NUM(ch))) {
|
||||||
SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
|
SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
|
||||||
@ -1519,6 +1530,12 @@ reexecute:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case h_content_length_ws:
|
||||||
|
if (ch == ' ') break;
|
||||||
|
SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
|
||||||
|
parser->header_state = h_state;
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* Transfer-Encoding: chunked */
|
/* Transfer-Encoding: chunked */
|
||||||
case h_matching_transfer_encoding_chunked:
|
case h_matching_transfer_encoding_chunked:
|
||||||
parser->index++;
|
parser->index++;
|
||||||
|
21
deps/http_parser/test.c
vendored
21
deps/http_parser/test.c
vendored
@ -4168,6 +4168,27 @@ main (void)
|
|||||||
test_invalid_header_field_token_error(HTTP_RESPONSE);
|
test_invalid_header_field_token_error(HTTP_RESPONSE);
|
||||||
test_invalid_header_field_content_error(HTTP_RESPONSE);
|
test_invalid_header_field_content_error(HTTP_RESPONSE);
|
||||||
|
|
||||||
|
test_simple_type(
|
||||||
|
"POST / HTTP/1.1\r\n"
|
||||||
|
"Content-Length: 42 \r\n" // Note the surrounding whitespace.
|
||||||
|
"\r\n",
|
||||||
|
HPE_OK,
|
||||||
|
HTTP_REQUEST);
|
||||||
|
|
||||||
|
test_simple_type(
|
||||||
|
"POST / HTTP/1.1\r\n"
|
||||||
|
"Content-Length: 4 2\r\n"
|
||||||
|
"\r\n",
|
||||||
|
HPE_INVALID_CONTENT_LENGTH,
|
||||||
|
HTTP_REQUEST);
|
||||||
|
|
||||||
|
test_simple_type(
|
||||||
|
"POST / HTTP/1.1\r\n"
|
||||||
|
"Content-Length: 13 37\r\n"
|
||||||
|
"\r\n",
|
||||||
|
HPE_INVALID_CONTENT_LENGTH,
|
||||||
|
HTTP_REQUEST);
|
||||||
|
|
||||||
//// RESPONSES
|
//// RESPONSES
|
||||||
|
|
||||||
test_simple_type("HTP/1.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
|
test_simple_type("HTP/1.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user