From 07b802c934b841d376733a3e2ecfa55f6b0ee994 Mon Sep 17 00:00:00 2001 From: Eric Covener Date: Sat, 11 Mar 2023 20:57:52 +0000 Subject: [PATCH] allow decoded chars when they will be escaped git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908296 13f79535-47bb-0310-9956-ffa450edef68 --- changes-entries/rewrite-escape.diff | 3 ++ modules/mappers/mod_rewrite.c | 45 +++++++++++++++++------------ 2 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 changes-entries/rewrite-escape.diff Index: apache2/changes-entries/rewrite-escape.diff =================================================================== --- /dev/null +++ apache2/changes-entries/rewrite-escape.diff @@ -0,0 +1,3 @@ + *) mod_rewrite: Re-allow some proxy and redirect substitutions flagged as + 403 errors in 2.4.56. [Eric Covener] + Index: apache2/modules/mappers/mod_rewrite.c =================================================================== --- apache2.orig/modules/mappers/mod_rewrite.c +++ apache2/modules/mappers/mod_rewrite.c @@ -4705,14 +4705,19 @@ static int hook_uri2file(request_rec *r) } if (rulestatus) { - unsigned skip; - apr_size_t flen; - int to_proxyreq; - - if (r->args && *(ap_scan_vchar_obstext(r->args))) { + unsigned skip_absolute = is_absolute_uri(r->filename, NULL); + apr_size_t flen = r->filename ? strlen(r->filename) : 0; + int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); + int will_escape = (to_proxyreq || skip_absolute) + && (rulestatus != ACTION_NOESCAPE); + + if (r->args + && !will_escape + && *(ap_scan_vchar_obstext(r->args))) { /* * We have a raw control character or a ' ' in r->args. - * Correct encoding was missed. + * Correct encoding was missed and we're not going to escape + * it before returning. */ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410) "Rewritten query string contains control " @@ -4727,9 +4732,6 @@ static int hook_uri2file(request_rec *r) return n; } - flen = r->filename ? strlen(r->filename) : 0; - to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); - /* If a pre_trans reverse "proxy:" filename gets rewritten to * a non-proxy one this is not a proxy request anymore. */ @@ -4782,15 +4784,15 @@ static int hook_uri2file(request_rec *r) r->filename)); return OK; } - else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) { + else if (skip_absolute > 0) { int n; /* it was finally rewritten to a remote URL */ if (rulestatus != ACTION_NOESCAPE) { rewritelog((r, 1, NULL, "escaping %s for redirect", - r->filename)); - r->filename = escape_absolute_uri(r->pool, r->filename, skip); + r->filename)); + r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute); } /* append the QUERY_STRING part */ @@ -5016,9 +5018,17 @@ static int hook_fixup(request_rec *r) */ rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory); if (rulestatus) { - unsigned skip; + unsigned skip_absolute = is_absolute_uri(r->filename, NULL); + int to_proxyreq = 0; + int will_escape = 0; - if (r->args && *(ap_scan_vchar_obstext(r->args))) { + l = strlen(r->filename); + to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0; + will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE); + + if (r->args + && !will_escape + && *(ap_scan_vchar_obstext(r->args))) { /* * We have a raw control character or a ' ' in r->args. * Correct encoding was missed. @@ -5036,8 +5046,7 @@ static int hook_fixup(request_rec *r) return n; } - l = strlen(r->filename); - if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) { + if (to_proxyreq) { /* it should go on as an internal proxy request */ /* make sure the QUERY_STRING and @@ -5061,7 +5070,7 @@ static int hook_fixup(request_rec *r) "%s [OK]", r->filename)); return OK; } - else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) { + else if (skip_absolute > 0) { /* it was finally rewritten to a remote URL */ /* because we are in a per-dir context @@ -5070,7 +5079,7 @@ static int hook_fixup(request_rec *r) */ if (dconf->baseurl != NULL) { /* skip 'scheme://' */ - cp = r->filename + skip; + cp = r->filename + skip_absolute; if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) { rewritelog((r, 2, dconf->directory, @@ -5114,8 +5123,8 @@ static int hook_fixup(request_rec *r) /* now prepare the redirect... */ if (rulestatus != ACTION_NOESCAPE) { rewritelog((r, 1, dconf->directory, "escaping %s for redirect", - r->filename)); - r->filename = escape_absolute_uri(r->pool, r->filename, skip); + r->filename)); + r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute); } /* append the QUERY_STRING part */