From 5dc594e44f73b1726cabca6a4395323f972e416d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 26 Aug 2021 16:04:50 +0200 Subject: 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 --- lib/http.c | 16 +++++++++++++--- tests/data/DISABLED | 2 -- tests/data/test1429 | 50 +++++++++++++++++++++++++------------------------- tests/data/test1432 | 3 +++ 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/lib/http.c b/lib/http.c index d0026c4da..65750d17d 100644 --- a/lib/http.c +++ b/lib/http.c @@ -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) { diff --git a/tests/data/DISABLED b/tests/data/DISABLED index 09d4118eb..c2e10dd37 100644 --- a/tests/data/DISABLED +++ b/tests/data/DISABLED @@ -90,10 +90,8 @@ 1288 1294 1417 -1429 1430 1431 -1432 1455 1456 1525 diff --git a/tests/data/test1429 b/tests/data/test1429 index 9fc3cd246..2f9dfb931 100644 --- a/tests/data/test1429 +++ b/tests/data/test1429 @@ -9,17 +9,17 @@ HTTP/0.9 -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- @@ -32,10 +32,10 @@ http -HTTP GET with 4-digit response code +HTTP GET with 999 response code -http://%HOSTIP:%HTTPPORT/%TESTNUMBER --write-out '%{response_code}' --http0.9 +http://%HOSTIP:%HTTPPORT/%TESTNUMBER --write-out '%{response_code}' @@ -43,19 +43,19 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER --write-out '%{response_code}' --http0.9 # Verify data after the test has been "shot" -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 GET /%TESTNUMBER HTTP/1.1 diff --git a/tests/data/test1432 b/tests/data/test1432 index ab76e94b0..d134688a3 100644 --- a/tests/data/test1432 +++ b/tests/data/test1432 @@ -48,5 +48,8 @@ User-Agent: curl/%VERSION Accept: */* + +1 + -- cgit v1.2.1