From 406636996fcd9ef6b92d9257a388dffe7cef69a1 Mon Sep 17 00:00:00 2001 From: chengyechun Date: Thu, 9 Mar 2023 15:05:04 +0800 Subject: [PATCH] fix CVE-2023-27522 --- backport-CVE-2023-25690.patch | 205 ++++++++++++++++++++++++++++++++++ backport-CVE-2023-27522.patch | 104 +++++++++++++++++ httpd.spec | 10 +- 3 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2023-25690.patch create mode 100644 backport-CVE-2023-27522.patch diff --git a/backport-CVE-2023-25690.patch b/backport-CVE-2023-25690.patch new file mode 100644 index 0000000..03552c7 --- /dev/null +++ b/backport-CVE-2023-25690.patch @@ -0,0 +1,205 @@ +From d78a166fedd9d02c23e4b71d5f53bd9b2c4b9a51 Mon Sep 17 00:00:00 2001 +From: covener +Date: Mon, 6 Mar 2023 4:27:31 AM GMT+0800 +Subject: [PATCH] don't forward invalid query strings + +Conflict:NA +Reference:https://github.com/apache/httpd/commit/d78a166fedd9d02c23e4b71d5f53bd9b2c4b9a51 + +--- + modules/http2/mod_proxy_http2.c | 14 ++++++++++++++ + modules/mappers/mod_rewrite.c | 22 ++++++++++++++++++++++ + modules/proxy/mod_proxy_ajp.c | 14 ++++++++++++++ + modules/proxy/mod_proxy_balancer.c | 14 ++++++++++++++ + modules/proxy/mod_proxy_http.c | 14 ++++++++++++++ + modules/proxy/mod_proxy_wstunnel.c | 14 ++++++++++++++ + 6 files changed, 92 insertions(+) + +diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c +index 3faf034..b316aa8 100644 +--- a/modules/http2/mod_proxy_http2.c ++++ b/modules/http2/mod_proxy_http2.c +@@ -154,10 +154,24 @@ static int proxy_http2_canon(request_rec *r, char *url) + if (apr_table_get(r->notes, "proxy-nocanon")) { + path = url; /* this is the raw path */ + } ++ else if (apr_table_get(r->notes, "proxy-noencode")) { ++ path = url; /* this is the encoded path already */ ++ search = r->args; ++ } + else { + path = ap_proxy_canonenc(r->pool, url, (int)strlen(url), + enc_path, 0, r->proxyreq); + search = r->args; ++ if (search && *(ap_scan_vchar_obstext(search))) { ++ /* ++ * We have a raw control character or a ' ' in r->args. ++ * Correct encoding was missed. ++ */ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() ++ "To be forwarded query string contains control " ++ "characters or spaces"); ++ return HTTP_FORBIDDEN; ++ } + } + break; + case PROXYREQ_PROXY: +diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c +index 9439965..f6398f1 100644 +--- a/modules/mappers/mod_rewrite.c ++++ b/modules/mappers/mod_rewrite.c +@@ -4729,6 +4729,17 @@ static int hook_uri2file(request_rec *r) + unsigned skip; + apr_size_t flen; + ++ if (r->args && *(ap_scan_vchar_obstext(r->args))) { ++ /* ++ * We have a raw control character or a ' ' in r->args. ++ * Correct encoding was missed. ++ */ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410) ++ "Rewritten query string contains control " ++ "characters or spaces"); ++ return HTTP_FORBIDDEN; ++ } ++ + if (ACTION_STATUS == rulestatus) { + int n = r->status; + +@@ -5013,6 +5024,17 @@ static int hook_fixup(request_rec *r) + if (rulestatus) { + unsigned skip; + ++ if (r->args && *(ap_scan_vchar_obstext(r->args))) { ++ /* ++ * We have a raw control character or a ' ' in r->args. ++ * Correct encoding was missed. ++ */ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10411) ++ "Rewritten query string contains control " ++ "characters or spaces"); ++ return HTTP_FORBIDDEN; ++ } ++ + if (ACTION_STATUS == rulestatus) { + int n = r->status; + +diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c +index 1449aca..aa3441a 100644 +--- a/modules/proxy/mod_proxy_ajp.c ++++ b/modules/proxy/mod_proxy_ajp.c +@@ -65,10 +65,24 @@ static int proxy_ajp_canon(request_rec *r, char *url) + if (apr_table_get(r->notes, "proxy-nocanon")) { + path = url; /* this is the raw path */ + } ++ else if (apr_table_get(r->notes, "proxy-noencode")) { ++ path = url; /* this is the encoded path already */ ++ search = r->args; ++ } + else { + path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, + r->proxyreq); + search = r->args; ++ if (search && *(ap_scan_vchar_obstext(search))) { ++ /* ++ * We have a raw control character or a ' ' in r->args. ++ * Correct encoding was missed. ++ */ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10406) ++ "To be forwarded query string contains control " ++ "characters or spaces"); ++ return HTTP_FORBIDDEN; ++ } + } + if (path == NULL) + return HTTP_BAD_REQUEST; +diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c +index f6fb634..de5ac8a 100644 +--- a/modules/proxy/mod_proxy_balancer.c ++++ b/modules/proxy/mod_proxy_balancer.c +@@ -102,10 +102,24 @@ static int proxy_balancer_canon(request_rec *r, char *url) + if (apr_table_get(r->notes, "proxy-nocanon")) { + path = url; /* this is the raw path */ + } ++ else if (apr_table_get(r->notes, "proxy-noencode")) { ++ path = url; /* this is the encoded path already */ ++ search = r->args; ++ } + else { + path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, + r->proxyreq); + search = r->args; ++ if (search && *(ap_scan_vchar_obstext(search))) { ++ /* ++ * We have a raw control character or a ' ' in r->args. ++ * Correct encoding was missed. ++ */ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10407) ++ "To be forwarded query string contains control " ++ "characters or spaces"); ++ return HTTP_FORBIDDEN; ++ } + } + if (path == NULL) + return HTTP_BAD_REQUEST; +diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c +index ec4e7fb..85f16f2 100644 +--- a/modules/proxy/mod_proxy_http.c ++++ b/modules/proxy/mod_proxy_http.c +@@ -121,10 +121,24 @@ static int proxy_http_canon(request_rec *r, char *url) + if (apr_table_get(r->notes, "proxy-nocanon")) { + path = url; /* this is the raw path */ + } ++ else if (apr_table_get(r->notes, "proxy-noencode")) { ++ path = url; /* this is the encoded path already */ ++ search = r->args; ++ } + else { + path = ap_proxy_canonenc(r->pool, url, strlen(url), + enc_path, 0, r->proxyreq); + search = r->args; ++ if (search && *(ap_scan_vchar_obstext(search))) { ++ /* ++ * We have a raw control character or a ' ' in r->args. ++ * Correct encoding was missed. ++ */ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10408) ++ "To be forwarded query string contains control " ++ "characters or spaces"); ++ return HTTP_FORBIDDEN; ++ } + } + break; + case PROXYREQ_PROXY: +diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c +index bcbba42..16502e2 100644 +--- a/modules/proxy/mod_proxy_wstunnel.c ++++ b/modules/proxy/mod_proxy_wstunnel.c +@@ -110,10 +110,24 @@ static int proxy_wstunnel_canon(request_rec *r, char *url) + if (apr_table_get(r->notes, "proxy-nocanon")) { + path = url; /* this is the raw path */ + } ++ else if (apr_table_get(r->notes, "proxy-noencode")) { ++ path = url; /* this is the encoded path already */ ++ search = r->args; ++ } + else { + path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, + r->proxyreq); + search = r->args; ++ if (search && *(ap_scan_vchar_obstext(search))) { ++ /* ++ * We have a raw control character or a ' ' in r->args. ++ * Correct encoding was missed. ++ */ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10409) ++ "To be forwarded query string contains control " ++ "characters or spaces"); ++ return HTTP_FORBIDDEN; ++ } + } + if (path == NULL) + return HTTP_BAD_REQUEST; +-- +2.27.0 + diff --git a/backport-CVE-2023-27522.patch b/backport-CVE-2023-27522.patch new file mode 100644 index 0000000..8a7f4f4 --- /dev/null +++ b/backport-CVE-2023-27522.patch @@ -0,0 +1,104 @@ +From 0df5879df8f16b4101ea2365672178b4ae899e9e Mon Sep 17 00:00:00 2001 +From: ylavic +Date: Thu, 2 Mar 2023 11:10:54 PM GMT+0800 +Subject: [PATCH] mod_proxy_uwsgi:Stricter backend HTTP response parsing/validation + +Conflict:NA +Reference:https://github.com/apache/httpd/commit/0df5879df8f16b4101ea2365672178b4ae899e9e + +--- + modules/proxy/mod_proxy_uwsgi.c | 49 +++++++++++++++++++++++---------- + 1 file changed, 35 insertions(+), 14 deletions(-) + +diff --git a/modules/proxy/mod_proxy_uwsgi.c b/modules/proxy/mod_proxy_uwsgi.c +index e02450e..92e153c 100644 +--- a/modules/proxy/mod_proxy_uwsgi.c ++++ b/modules/proxy/mod_proxy_uwsgi.c +@@ -307,18 +307,16 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend, + pass_bb = apr_brigade_create(r->pool, c->bucket_alloc); + + len = ap_getline(buffer, sizeof(buffer), rp, 1); +- + if (len <= 0) { +- /* oops */ ++ /* invalid or empty */ + return HTTP_INTERNAL_SERVER_ERROR; + } +- + backend->worker->s->read += len; +- +- if (len >= sizeof(buffer) - 1) { +- /* oops */ ++ if ((apr_size_t)len >= sizeof(buffer)) { ++ /* too long */ + return HTTP_INTERNAL_SERVER_ERROR; + } ++ + /* Position of http status code */ + if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) { + status_start = 9; +@@ -327,8 +325,8 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend, + status_start = 7; + } + else { +- /* oops */ +- return HTTP_INTERNAL_SERVER_ERROR; ++ /* not HTTP */ ++ return HTTP_BAD_GATEWAY; + } + status_end = status_start + 3; + +@@ -348,21 +346,44 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend, + } + r->status_line = apr_pstrdup(r->pool, &buffer[status_start]); + +- /* start parsing headers */ ++ /* parse headers */ + while ((len = ap_getline(buffer, sizeof(buffer), rp, 1)) > 0) { ++ if ((apr_size_t)len >= sizeof(buffer)) { ++ /* too long */ ++ len = -1; ++ break; ++ } + value = strchr(buffer, ':'); +- /* invalid header skip */ +- if (!value) +- continue; +- *value = '\0'; +- ++value; ++ if (!value) { ++ /* invalid header */ ++ len = -1; ++ break; ++ } ++ *value++ = '\0'; ++ if (*ap_scan_http_token(buffer)) { ++ /* invalid name */ ++ len = -1; ++ break; ++ } + while (apr_isspace(*value)) + ++value; + for (end = &value[strlen(value) - 1]; + end > value && apr_isspace(*end); --end) + *end = '\0'; ++ if (*ap_scan_http_field_content(value)) { ++ /* invalid value */ ++ len = -1; ++ break; ++ } + apr_table_add(r->headers_out, buffer, value); + } ++ if (len < 0) { ++ /* Reset headers, but not to NULL because things below the chain expect ++ * this to be non NULL e.g. the ap_content_length_filter. ++ */ ++ r->headers_out = apr_table_make(r->pool, 1); ++ return HTTP_BAD_GATEWAY; ++ } + + if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { + ap_set_content_type(r, apr_pstrdup(r->pool, buf)); +-- +2.27.0 + diff --git a/httpd.spec b/httpd.spec index 9bda056..7268e78 100644 --- a/httpd.spec +++ b/httpd.spec @@ -8,7 +8,7 @@ Name: httpd Summary: Apache HTTP Server Version: 2.4.55 -Release: 2 +Release: 3 License: ASL 2.0 URL: https://httpd.apache.org/ Source0: https://archive.apache.org/dist/httpd/httpd-%{version}.tar.bz2 @@ -69,6 +69,8 @@ Patch15: backport-httpd-2.4.43-gettid.patch Patch16: backport-httpd-2.4.43-r1861793+.patch Patch17: backport-httpd-2.4.48-r1828172+.patch Patch18: backport-httpd-2.4.46-htcacheclean-dont-break.patch +Patch19: backport-CVE-2023-27522.patch +Patch20: backport-CVE-2023-25690.patch BuildRequires: gcc autoconf pkgconfig findutils xmlto perl-interpreter perl-generators systemd-devel BuildRequires: zlib-devel libselinux-devel lua-devel brotli-devel @@ -505,6 +507,12 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Thu Mar 9 2023 chengyechun - 2.4.55-3 +- Type:CVE +- ID:CVE-2023-27522, CVE-2023-25690 +- SUG:restart +- DESC:fix CVE-2023-27522, CVE-2023-25690 + * Sat Mar 4 2023 Wenlong Zhang - 2.4.55-2 - Type:bugfix - ID:NA -- Gitee