]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http: disallow >3-digit response codes
authorDaniel Stenberg <daniel@haxx.se>
Thu, 26 Aug 2021 14:04:50 +0000 (16:04 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 26 Aug 2021 20:43:38 +0000 (22:43 +0200)
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
tests/data/DISABLED
tests/data/test1429
tests/data/test1432

index d0026c4dadcd8dbc10d587fd69137b7725ae8b20..65750d17d67defd63ad7f8cbce5e56e7917bda74 100644 (file)
@@ -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) {
index 09d4118eb949b98c9ed5f6c296fe766e71dc9077..c2e10dd37fd8d975552f42cba279c41e54eb96ee 100644 (file)
 1288
 1294
 1417
-1429
 1430
 1431
-1432
 1455
 1456
 1525
index 9fc3cd24666a3e38e9482b3539c37d207416acaa..2f9dfb931120075ada1d7ea1f95c5c6df23f21ba 100644 (file)
@@ -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\r
+Date: Tue, 09 Nov 2010 14:49:00 GMT\r
+Server: test-server/fake\r
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT\r
+ETag: "21025-dc7-39462498"\r
+Accept-Ranges: bytes\r
+Content-Length: 6\r
+Connection: close\r
+Content-Type: text/html\r
+Funny-head: yesyes\r
+\r
 -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\r
+Date: Tue, 09 Nov 2010 14:49:00 GMT\r
+Server: test-server/fake\r
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT\r
+ETag: "21025-dc7-39462498"\r
+Accept-Ranges: bytes\r
+Content-Length: 6\r
+Connection: close\r
+Content-Type: text/html\r
+Funny-head: yesyes\r
+\r
 -foo-
-234
+999
 </stdout>
 <protocol>
 GET /%TESTNUMBER HTTP/1.1\r
index ab76e94b085edad5cb23a5df526c995afaca45ea..d134688a31405709ac4f26ace8580727162732d2 100644 (file)
@@ -48,5 +48,8 @@ User-Agent: curl/%VERSION
 Accept: */*\r
 \r
 </protocol>
+<errorcode>
+1
+</errorcode>
 </verify>
 </testcase>