]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
*) mod_http2: when a h2 request carries a ':scheme' pseudoheader,
authorStefan Eissing <icing@apache.org>
Tue, 8 Feb 2022 13:38:49 +0000 (13:38 +0000)
committerStefan Eissing <icing@apache.org>
Tue, 8 Feb 2022 13:38:49 +0000 (13:38 +0000)
    it gives a 400 response if the scheme does not match the
    connection. Fixes <https://github.com/icing/mod_h2/issues/230>.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1897872 13f79535-47bb-0310-9956-ffa450edef68

changes-entries/http2_request_scheme.txt [new file with mode: 0644]
modules/http2/h2_stream.c
test/modules/http2/test_003_get.py

diff --git a/changes-entries/http2_request_scheme.txt b/changes-entries/http2_request_scheme.txt
new file mode 100644 (file)
index 0000000..93a6d63
--- /dev/null
@@ -0,0 +1,3 @@
+  *) mod_http2: when a h2 request carries a ':scheme' pseudoheader,
+    it gives a 400 response if the scheme does not match the
+    connection. Fixes <https://github.com/icing/mod_h2/issues/230>.
index b29a7d57afdce92b875c48e011ecacab1d437c0a..2a277b8ee09a3b73fb5f0d491f4ff9d6b87ddabf 100644 (file)
@@ -23,6 +23,7 @@
 #include <http_core.h>
 #include <http_connection.h>
 #include <http_log.h>
+#include <http_ssl.h>
 
 #include <nghttp2/nghttp2.h>
 
@@ -773,12 +774,10 @@ apr_status_t h2_stream_end_headers(h2_stream *stream, int eos, size_t raw_bytes)
     status = h2_request_end_headers(stream->rtmp, stream->pool, eos, raw_bytes);
     if (APR_SUCCESS == status) {
         set_policy_for(stream, stream->rtmp);
-        stream->request = stream->rtmp;
-        stream->rtmp = NULL;
-        
+
         ctx.maxlen = stream->session->s->limit_req_fieldsize;
         ctx.failed_key = NULL;
-        apr_table_do(table_check_val_len, &ctx, stream->request->headers, NULL);
+        apr_table_do(table_check_val_len, &ctx, stream->rtmp->headers, NULL);
         if (ctx.failed_key) {
             if (!h2_stream_is_ready(stream)) {
                 ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c1,
@@ -790,6 +789,15 @@ apr_status_t h2_stream_end_headers(h2_stream *stream, int eos, size_t raw_bytes)
             /* keep on returning APR_SUCCESS, so that we send a HTTP response and
              * do not RST the stream. */
         }
+        if (stream->rtmp->scheme && strcasecmp(stream->rtmp->scheme,
+            ap_ssl_conn_is_ssl(stream->session->c1)? "https" : "http")) {
+                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c1,
+                              H2_STRM_LOG(APLOGNO(), stream,"Request :scheme '%s' and "
+                              "connection do not match."), stream->rtmp->scheme);
+            set_error_response(stream, HTTP_BAD_REQUEST);
+        }
+        stream->request = stream->rtmp;
+        stream->rtmp = NULL;
     }
     return status;
 }
index 3fbaa081afde2bafaeb7a2f30d99d959c759493e..09ea31167de8e9898fb9def0aba490720e5d75d8 100644 (file)
@@ -211,3 +211,11 @@ content-type: text/html
         assert 1024 == len(r.response["body"])
         assert "content-length" in h
         assert clen == h["content-length"]
+
+    # use an invalid scheme
+    def test_h2_003_51(self, env):
+        url = env.mkurl("https", "cgi", "/")
+        opt = ["-H:scheme: http"]
+        r = env.nghttp().get(url, options=opt)
+        assert r.exit_code == 0, r
+        assert r.response['status'] == 400