summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2021-08-26 16:04:50 +0200
committerDaniel Stenberg <daniel@haxx.se>2021-08-26 16:28:38 +0200
commit5a82f543a4d00834a2efa2c802a0ad6bbe29044b (patch)
treebf91b19b59b054fa965931833c34c2a2819aaea6
parent9df52bf17ae23f22ca6d573d3992bcbbecf5eddc (diff)
downloadcurl-5a82f543a4d00834a2efa2c802a0ad6bbe29044b.tar.gz
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
-rw-r--r--lib/http.c16
-rw-r--r--tests/data/DISABLED1
-rw-r--r--tests/data/test14323
3 files changed, 16 insertions, 4 deletions
diff --git a/lib/http.c b/lib/http.c
index d0026c4da..8191967af 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 */
+ 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..dce2d195b 100644
--- a/tests/data/DISABLED
+++ b/tests/data/DISABLED
@@ -93,7 +93,6 @@
1429
1430
1431
-1432
1455
1456
1525
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: */*
</protocol>
+<errorcode>
+1
+</errorcode>
</verify>
</testcase>