From 80caf0b9ce61a4654f1a9f6043b238ef6a85e2f5 Mon Sep 17 00:00:00 2001 From: chengyechun Date: Thu, 9 Mar 2023 21:18:25 +0800 Subject: [PATCH] fix CVE-2023-27522 CVE-25690 --- 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..ebeb1aa --- /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 03c77ed..b9be869 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 65abfa2..80fdbde 100644 +--- a/modules/mappers/mod_rewrite.c ++++ b/modules/mappers/mod_rewrite.c +@@ -4702,6 +4702,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; + +@@ -4986,6 +4997,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 8c2259e..317ee63 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 e26e95d..f235f4a 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 679ecdd..ae5e3d5 100644 +--- a/modules/proxy/mod_proxy_http.c ++++ b/modules/proxy/mod_proxy_http.c +@@ -86,10 +86,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 fb53fe6..28d6363 100644 +--- a/modules/proxy/mod_proxy_wstunnel.c ++++ b/modules/proxy/mod_proxy_wstunnel.c +@@ -69,10 +69,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..2f2e0fa --- /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 9efc5b6..cc5cda7 100644 +--- a/modules/proxy/mod_proxy_uwsgi.c ++++ b/modules/proxy/mod_proxy_uwsgi.c +@@ -304,18 +304,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; +@@ -324,8 +322,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; + +@@ -345,21 +343,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 b2cade5..c55706e 100644 --- a/httpd.spec +++ b/httpd.spec @@ -8,7 +8,7 @@ Name: httpd Summary: Apache HTTP Server Version: 2.4.43 -Release: 20 +Release: 21 License: ASL 2.0 URL: https://httpd.apache.org/ Source0: https://archive.apache.org/dist/httpd/httpd-%{version}.tar.bz2 @@ -103,6 +103,8 @@ Patch49: backport-CVE-2022-28330.patch Patch50: backport-CVE-2006-20001.patch Patch51: backport-CVE-2022-36760.patch Patch52: backport-CVE-2022-37436.patch +Patch53: backport-CVE-2023-27522.patch +Patch54: 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 @@ -539,6 +541,12 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Thu Mar 9 2023 chengyechun - 2.4.43-21 +- Type:CVE +- ID:CVE-2023-27522, CVE-2023-25690 +- SUG:restart +- DESC:fix CVE-2023-27522, CVE-2023-25690 + * Fri Feb 3 2023 chengyechun - 2.4.43-20 - Type:bugfix - ID:NA -- Gitee