From a7125ce37fae7ed2cb2a9c23062320d72667237f Mon Sep 17 00:00:00 2001 From: Aron Xu Date: Sat, 21 May 2022 20:14:28 +0100 Subject: [PATCH] CVE-2021-38161 commit feefc5e4abc5011dfad5dcfef3f22998faf6e2d4 Author: Alan M. Carroll Date: Wed Oct 27 13:41:47 2021 -0500 Add some checking to validate the scheme matches the wire protocol. (#8464) Gbp-Pq: Name 0020-CVE-2021-38161.patch --- proxy/http/HttpSM.cc | 14 ++++++++++++++ proxy/http/HttpSM.h | 1 + 2 files changed, 15 insertions(+) diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index e9b35de9..9435cb1a 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -443,6 +443,9 @@ HttpSM::attach_client_session(ProxyClientTransaction *client_vc, IOBufferReader // Collect log & stats information client_tcp_reused = !(ua_txn->is_first_transaction()); SSLNetVConnection *ssl_vc = dynamic_cast(netvc); + + is_internal = netvc->get_is_internal_request(); + if (ssl_vc != nullptr) { client_connection_is_ssl = true; client_ssl_reused = ssl_vc->getSSLSessionCacheHit(); @@ -724,6 +727,17 @@ HttpSM::state_read_client_request_header(int event, void *data) case PARSE_RESULT_DONE: SMDebug("http", "[%" PRId64 "] done parsing client request header", sm_id); + if (!is_internal) { + auto scheme = t_state.hdr_info.client_request.url_get()->scheme_get_wksidx(); + if ((client_connection_is_ssl && (scheme == URL_WKSIDX_HTTP || scheme == URL_WKSIDX_WS)) || + (!client_connection_is_ssl && (scheme == URL_WKSIDX_HTTPS || scheme == URL_WKSIDX_WSS))) { + SMDebug("http", "scheme [%s] vs. protocol [%s] mismatch", hdrtoken_index_to_wks(scheme), + client_connection_is_ssl ? "tls" : "plaintext"); + t_state.http_return_code = HTTP_STATUS_BAD_REQUEST; + call_transact_and_set_next_state(HttpTransact::BadRequest); + break; + } + } ua_txn->set_session_active(); if (t_state.hdr_info.client_request.version_get() == HTTPVersion(1, 1) && diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h index 1f3ac232..6026f4a6 100644 --- a/proxy/http/HttpSM.h +++ b/proxy/http/HttpSM.h @@ -541,6 +541,7 @@ public: int64_t pushed_response_body_bytes = 0; bool client_tcp_reused = false; // Info about client's SSL connection. + bool is_internal = false; bool client_ssl_reused = false; bool client_connection_is_ssl = false; const char *client_protocol = "-"; -- 2.30.2