From: Stefan Eissing Date: Tue, 8 Feb 2022 13:38:49 +0000 (+0000) Subject: *) mod_http2: when a h2 request carries a ':scheme' pseudoheader, X-Git-Tag: 2.5.0-alpha2-ci-test-only~506 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a6bf7f895e4cf0799f1cbbc68d13949d0d1a75c;p=thirdparty%2Fapache%2Fhttpd.git *) mod_http2: when a h2 request carries a ':scheme' pseudoheader, it gives a 400 response if the scheme does not match the connection. Fixes . git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1897872 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/changes-entries/http2_request_scheme.txt b/changes-entries/http2_request_scheme.txt new file mode 100644 index 00000000000..93a6d6348b3 --- /dev/null +++ b/changes-entries/http2_request_scheme.txt @@ -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 . diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c index b29a7d57afd..2a277b8ee09 100644 --- a/modules/http2/h2_stream.c +++ b/modules/http2/h2_stream.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -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; } diff --git a/test/modules/http2/test_003_get.py b/test/modules/http2/test_003_get.py index 3fbaa081afd..09ea31167de 100644 --- a/test/modules/http2/test_003_get.py +++ b/test/modules/http2/test_003_get.py @@ -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