From a356fdbfb93c59a4e359f0a81b38aef31ddd856e Mon Sep 17 00:00:00 2001 From: Eric covener Date: Mon, 20 Mar 2023 05:29:03 AM GMT+0800 Subject: [PATCH] mod_proxy: Fix double encoding of the uri-path of the request forwarded to the origin server, when using mapping=encoded|servlet Conflict:NA Reference:https://github.com/apache/httpd/commit/a356fdbfb93c59a4e359f0a81b38aef31ddd856e --- modules/http2/mod_proxy_http2.c | 20 ++++++++++---------- modules/proxy/mod_proxy.c | 17 +++++++++++------ modules/proxy/mod_proxy_ajp.c | 20 ++++++++++---------- modules/proxy/mod_proxy_balancer.c | 20 ++++++++++---------- modules/proxy/mod_proxy_fcgi.c | 5 +++-- modules/proxy/mod_proxy_http.c | 20 ++++++++++---------- modules/proxy/mod_proxy_uwsgi.c | 10 ++++++++-- modules/proxy/mod_proxy_wstunnel.c | 20 ++++++++++---------- 8 files changed, 72 insertions(+), 60 deletions(-) diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c index 753f7f4..9b741e1 100644 --- a/modules/http2/mod_proxy_http2.c +++ b/modules/http2/mod_proxy_http2.c @@ -162,16 +162,16 @@ static int proxy_http2_canon(request_rec *r, char *url) 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(10412) - "To be forwarded query string contains control " - "characters or spaces"); - return HTTP_FORBIDDEN; - } + } + 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(10412) + "To be forwarded query string contains control " + "characters or spaces"); + return HTTP_FORBIDDEN; } break; case PROXYREQ_PROXY: diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index f8a4db6..6717782 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -960,6 +960,8 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent, } if (found) { + unsigned int encoded = ent->flags & PROXYPASS_MAP_ENCODED; + /* A proxy module is assigned this URL, check whether it's interested * in the request itself (e.g. proxy_wstunnel cares about Upgrade * requests only, and could hand over to proxy_http otherwise). @@ -979,6 +981,9 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent, if (ent->flags & PROXYPASS_NOQUERY) { apr_table_setn(r->notes, "proxy-noquery", "1"); } + if (encoded) { + apr_table_setn(r->notes, "proxy-noencode", "1"); + } if (servlet_uri) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10248) @@ -992,13 +997,13 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent, */ AP_DEBUG_ASSERT(strlen(r->uri) >= strlen(servlet_uri)); strcpy(r->uri, servlet_uri); - return DONE; } - - ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03464) - "URI path '%s' matches proxy handler '%s'", r->uri, - found); - return OK; + else { + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03464) + "URI path '%s' matches proxy handler '%s'", r->uri, + found); + } + return (encoded) ? DONE : OK; } return HTTP_CONTINUE; diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index ba41fbd..731e4ed 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -73,16 +73,16 @@ static int proxy_ajp_canon(request_rec *r, char *url) 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 (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 c8bba0f..719a99e 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -110,16 +110,16 @@ static int proxy_balancer_canon(request_rec *r, char *url) 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 (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_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index 3382b9b..a89b9a9 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -92,8 +92,9 @@ static int proxy_fcgi_canon(request_rec *r, char *url) host = apr_pstrcat(r->pool, "[", host, "]", NULL); } - if (apr_table_get(r->notes, "proxy-nocanon")) { - path = url; /* this is the raw path */ + if (apr_table_get(r->notes, "proxy-nocanon") + || apr_table_get(r->notes, "proxy-noencode")) { + path = url; /* this is the raw/encoded path */ } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 09269b2..4d0f8de 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -129,16 +129,16 @@ static int proxy_http_canon(request_rec *r, char *url) 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; - } + } + 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_uwsgi.c b/modules/proxy/mod_proxy_uwsgi.c index cc21e38..71c6ebb 100644 --- a/modules/proxy/mod_proxy_uwsgi.c +++ b/modules/proxy/mod_proxy_uwsgi.c @@ -84,8 +84,14 @@ static int uwsgi_canon(request_rec *r, char *url) host = apr_pstrcat(r->pool, "[", host, "]", NULL); } - path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, - r->proxyreq); + if (apr_table_get(r->notes, "proxy-nocanon") + || apr_table_get(r->notes, "proxy-noencode")) { + path = url; /* this is the raw/encoded path */ + } + else { + path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, + r->proxyreq); + } if (!path) { return HTTP_BAD_REQUEST; } diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c index e2fcba2..3f8de25 100644 --- a/modules/proxy/mod_proxy_wstunnel.c +++ b/modules/proxy/mod_proxy_wstunnel.c @@ -118,16 +118,16 @@ static int proxy_wstunnel_canon(request_rec *r, char *url) 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 (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