From: Brian Neradt Date: Tue, 9 Aug 2022 03:18:49 +0000 (-0500) Subject: [PATCH] Add back validatation that the scheme matches the wire protocol (#9007) X-Git-Tag: archive/raspbian/8.0.2+ds-1+rpi1+deb10u7^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=60c3073690302919922f93a6a798e6169644f947;p=trafficserver.git [PATCH] Add back validatation that the scheme matches the wire protocol (#9007) This adds back in the scheme and wire protocol check (see #8465) along with a configuration to be able to disable the check if the verification is not desired. Gbp-Pq: Name CVE-2021-37150.patch --- diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst index b799c24f..6398f546 100644 --- a/doc/admin-guide/files/records.config.en.rst +++ b/doc/admin-guide/files/records.config.en.rst @@ -3413,6 +3413,29 @@ Client-Related Configuration Enables (``1``) or disables (``0``) TLSv1_1 in the ATS client context. If not specified, enabled by default +.. ts:cv:: CONFIG proxy.config.ssl.client.scheme_proto_mismatch_policy INT 2 + :overridable: + + This option controls how |TS| behaves when the client side connection + protocol and the client request's scheme do not match. For example, if + enforcement is enabled by setting this value to ``2`` and the client + connection is a cleartext HTTP connection but the scheme of the URL is + ``https://``, then |TS| will emit a warning and return an immediate 400 HTTP + response without proxying the request to the origin. + + The default value is ``2``, meaning that |TS| will enforce that the protocol + matches the scheme. + + ===== ====================================================================== + Value Description + ===== ====================================================================== + ``0`` Disable verification that the protocol and scheme match. + ``1`` Check that the protocol and scheme match, but only emit a warning if + they do not. + ``2`` Check that the protocol and scheme match and, if they do not, emit a + warning and return an immediate HTTP 400 response. + ===== ====================================================================== + .. ts:cv:: CONFIG proxy.config.ssl.client.TLSv1_2 INT 1 Enables (``1``) or disables (``0``) TLSv1_2 in the ATS client context. If not specified, enabled by default diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc index d9602967..084649de 100644 --- a/mgmt/RecordsConfig.cc +++ b/mgmt/RecordsConfig.cc @@ -1137,6 +1137,8 @@ static const RecordElement RecordsConfig[] = , {RECT_CONFIG, "proxy.config.ssl.client.CA.cert.path", RECD_STRING, TS_BUILD_SYSCONFDIR, RECU_RESTART_TS, RR_NULL, RECC_NULL, nullptr, RECA_NULL} , + {RECT_CONFIG, "proxy.config.ssl.client.scheme_proto_mismatch_policy", RECD_INT, "2", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL} + , {RECT_CONFIG, "proxy.config.ssl.session_cache", RECD_INT, "2", RECU_RESTART_TS, RR_NULL, RECC_NULL, nullptr, RECA_NULL} , {RECT_CONFIG, "proxy.config.ssl.session_cache.size", RECD_INT, "102400", RECU_RESTART_TS, RR_NULL, RECC_NULL, nullptr, RECA_NULL} diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc index 9b98bba5..03de8af0 100644 --- a/proxy/http/HttpConfig.cc +++ b/proxy/http/HttpConfig.cc @@ -1225,7 +1225,7 @@ HttpConfig::startup() HttpEstablishStaticConfigByte(c.redirection_host_no_port, "proxy.config.http.redirect_host_no_port"); HttpEstablishStaticConfigLongLong(c.oride.number_of_redirections, "proxy.config.http.number_of_redirections"); HttpEstablishStaticConfigLongLong(c.post_copy_size, "proxy.config.http.post_copy_size"); - + HttpEstablishStaticConfigByte(c.scheme_proto_mismatch_policy, "proxy.config.ssl.client.scheme_proto_mismatch_policy"); http_config_cont->handleEvent(EVENT_NONE, nullptr); return; @@ -1492,6 +1492,8 @@ HttpConfig::reconfigure() params->oride.client_cert_filename = ats_strdup(m_master.oride.client_cert_filename); params->oride.client_cert_filepath = ats_strdup(m_master.oride.client_cert_filepath); + params->scheme_proto_mismatch_policy = m_master.scheme_proto_mismatch_policy; + params->negative_caching_list = m_master.negative_caching_list; m_id = configProcessor.set(m_id, params); diff --git a/proxy/http/HttpConfig.h b/proxy/http/HttpConfig.h index 5b395a36..2c7c648a 100644 --- a/proxy/http/HttpConfig.h +++ b/proxy/http/HttpConfig.h @@ -873,6 +873,7 @@ public: MgmtInt body_factory_response_max_size = 8192; + MgmtByte scheme_proto_mismatch_policy = 2; // noncopyable ///////////////////////////////////// // operator = and copy constructor // diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 9435cb1a..a4492fea 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -727,17 +727,20 @@ 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) { + if (!is_internal && t_state.http_config_param->scheme_proto_mismatch_policy != 0) { 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), + Warning("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; + if (t_state.http_config_param->scheme_proto_mismatch_policy == 2) { + 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) &&