aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2024-01-27 13:54:10 +0100
committerDaniel Stenberg <daniel@haxx.se>2024-01-27 21:49:20 +0100
commit066ed4e51417492605ac3465cb052e62f322d78b (patch)
tree2781b8e13d25594ce3b9ed78c97f2dca0f1a4cd4
parent6422ab6745c37f491d83c897ddb70b1bf782790e (diff)
downloadcurl-066ed4e51417492605ac3465cb052e62f322d78b.tar.gz
http: only act on 101 responses when they are HTTP/1.1
For 101 responses claiming to be any other protocol, bail out. This would previously trigger an assert. Add test 1704 to verify. Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66184 Closes #12811
-rw-r--r--lib/http.c56
-rw-r--r--tests/data/Makefile.inc2
-rw-r--r--tests/data/test170466
3 files changed, 98 insertions, 26 deletions
diff --git a/lib/http.c b/lib/http.c
index 0c2a46090..679931e4b 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -4036,34 +4036,40 @@ static CURLcode http_rw_headers(struct Curl_easy *data,
}
break;
case 101:
- /* Switching Protocols */
- if(k->upgr101 == UPGR101_H2) {
- /* Switching to HTTP/2 */
- DEBUGASSERT(conn->httpversion < 20);
- infof(data, "Received 101, Switching to HTTP/2");
- k->upgr101 = UPGR101_RECEIVED;
-
- /* we'll get more headers (HTTP/2 response) */
- k->header = TRUE;
- k->headerline = 0; /* restart the header line counter */
- switch_to_h2 = TRUE;
- }
+ if(conn->httpversion == 11) {
+ /* Switching Protocols only allowed from HTTP/1.1 */
+ if(k->upgr101 == UPGR101_H2) {
+ /* Switching to HTTP/2 */
+ infof(data, "Received 101, Switching to HTTP/2");
+ k->upgr101 = UPGR101_RECEIVED;
+
+ /* we'll get more headers (HTTP/2 response) */
+ k->header = TRUE;
+ k->headerline = 0; /* restart the header line counter */
+ switch_to_h2 = TRUE;
+ }
#ifdef USE_WEBSOCKETS
- else if(k->upgr101 == UPGR101_WS) {
- /* verify the response */
- result = Curl_ws_accept(data, buf, blen);
- if(result)
- return result;
- k->header = FALSE; /* no more header to parse! */
- *pconsumed += blen; /* ws accept handled the data */
- blen = 0;
- if(data->set.connect_only)
- k->keepon &= ~KEEP_RECV; /* read no more content */
- }
+ else if(k->upgr101 == UPGR101_WS) {
+ /* verify the response */
+ result = Curl_ws_accept(data, buf, blen);
+ if(result)
+ return result;
+ k->header = FALSE; /* no more header to parse! */
+ *pconsumed += blen; /* ws accept handled the data */
+ blen = 0;
+ if(data->set.connect_only)
+ k->keepon &= ~KEEP_RECV; /* read no more content */
+ }
#endif
+ else {
+ /* Not switching to another protocol */
+ k->header = FALSE; /* no more header to parse! */
+ }
+ }
else {
- /* Not switching to another protocol */
- k->header = FALSE; /* no more header to parse! */
+ /* invalid for other HTTP versions */
+ failf(data, "unexpected 101 response code");
+ return CURLE_WEIRD_SERVER_REPLY;
}
break;
default:
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 5b9e3a9ed..c3d496f64 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -215,7 +215,7 @@ test1670 test1671 \
\
test1680 test1681 test1682 test1683 \
\
-test1700 test1701 test1702 test1703 \
+test1700 test1701 test1702 test1703 test1704 \
\
test1800 test1801 \
\
diff --git a/tests/data/test1704 b/tests/data/test1704
new file mode 100644
index 000000000..a8f285eea
--- /dev/null
+++ b/tests/data/test1704
@@ -0,0 +1,66 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP/2
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/2 101 OK
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+
+-maa-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+h2c
+</features>
+<server>
+http
+</server>
+<name>
+HTTP/1 doing HTTP/2 Upgrade: getting a HTTP/2 101 response
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER --http2
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^X-Forwarded-Proto:.*
+^Via:.*
+</strip>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+Connection: Upgrade, HTTP2-Settings
+Upgrade: h2c
+HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA
+
+</protocol>
+
+# CURLE_WEIRD_SERVER_REPLY (8)
+<errorcode>
+8
+</errorcode>
+</verify>
+</testcase>