http: disallow >3-digit response codes

Make the built-in HTTP parser behave similar to hyper and reject any
HTTP response using more than 3 digits for the response code.

Updated test 1432 accordingly.
Enabled test 1432 in the hyper builds.

Closes #7641
This commit is contained in:
Daniel Stenberg 2021-08-26 16:04:50 +02:00
Родитель 14da6eb4e5
Коммит 5dc594e44f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
4 изменённых файлов: 41 добавлений и 30 удалений

Просмотреть файл

@ -4215,18 +4215,20 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* https://tools.ietf.org/html/rfc7230#section-3.1.2
*
* The response code is always a three-digit number in HTTP as the spec
* says. We try to allow any number here, but we cannot make
* says. We allow any three-digit number here, but we cannot make
* guarantees on future behaviors since it isn't within the protocol.
*/
char separator;
char twoorthree[2];
int httpversion = 0;
int digit4 = -1; /* should remain untouched to be good */
nc = sscanf(HEADER1,
" HTTP/%1d.%1d%c%3d",
" HTTP/%1d.%1d%c%3d%1d",
&httpversion_major,
&httpversion,
&separator,
&k->httpcode);
&k->httpcode,
&digit4);
if(nc == 1 && httpversion_major >= 2 &&
2 == sscanf(HEADER1, " HTTP/%1[23] %d", twoorthree, &k->httpcode)) {
@ -4235,6 +4237,14 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
separator = ' ';
}
/* There can only be a 4th response code digit stored in 'digit4' if
all the other fields were parsed and stored first, so nc is 5 when
digit4 is not -1 */
else if(digit4 != -1) {
failf(data, "Unsupported response code in HTTP response");
return CURLE_UNSUPPORTED_PROTOCOL;
}
if((nc == 4) && (' ' == separator)) {
httpversion += 10 * httpversion_major;
switch(httpversion) {

Просмотреть файл

@ -90,10 +90,8 @@
1288
1294
1417
1429
1430
1431
1432
1455
1456
1525

Просмотреть файл

@ -9,17 +9,17 @@ HTTP/0.9
<reply>
<data nocheck="yes">
HTTP/1.1 2345 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
HTTP/1.1 999 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</data>
</reply>
@ -32,10 +32,10 @@ http
</server>
<name>
HTTP GET with 4-digit response code
HTTP GET with 999 response code
</name>
<command>
http://%HOSTIP:%HTTPPORT/%TESTNUMBER --write-out '%{response_code}' --http0.9
http://%HOSTIP:%HTTPPORT/%TESTNUMBER --write-out '%{response_code}'
</command>
</client>
@ -43,19 +43,19 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER --write-out '%{response_code}' --http0.9
# Verify data after the test has been "shot"
<verify>
<stdout nonewline="yes">
HTTP/1.1 2345 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
HTTP/1.1 999 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
234
999
</stdout>
<protocol>
GET /%TESTNUMBER HTTP/1.1

Просмотреть файл

@ -48,5 +48,8 @@ User-Agent: curl/%VERSION
Accept: */*
</protocol>
<errorcode>
1
</errorcode>
</verify>
</testcase>