From 2b9aea396474a81be80280aa2866b846f352b6ff Mon Sep 17 00:00:00 2001 From: Nick Kew Date: Mon, 8 Oct 2007 23:47:35 +0000 Subject: [PATCH] mod_proxy_http: Don't unescape/escape forward proxied URLs. Just check them. PR 42592 also add fix to PR42572 to CHANGES (from r563487/r563489) git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@583002 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 6 ++++++ modules/proxy/mod_proxy_http.c | 28 +++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 0ec6f73556..28920e62c7 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,12 @@ Changes with Apache 2.3.0 [ When backported to 2.2.x, remove entry from this file ] + *) mod_proxy_http: Check but don't escape/unescape forward-proxied URLs + PR 42592 [Nick Kew] + + *) mpm winnt: fix null pointer dereference + PR 42572 [Davi Arnaut] + *) http_core: OPTIONS * no longer maps to local storage or URI space. PR 43519 [Jim Jagielski] diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 0f74b7933e..c7a1bfd4a4 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -36,6 +36,9 @@ static int proxy_http_canon(request_rec *r, char *url) const char *err; const char *scheme; apr_port_t port, def_port; + const char *p; + const char *allowed = "~$-_.+!*'(),;:@&=/"; /* allowed+reserved from + ap_proxy_canonenc */ /* ap_port_of_scheme() */ if (strncasecmp(url, "http:", 5) == 0) { @@ -80,7 +83,30 @@ static int proxy_http_canon(request_rec *r, char *url) search = r->args; /* process path */ - path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); + /* In a reverse proxy, our URL has been processed, so canonicalise + * In a forward proxy, we have and MUST NOT MANGLE the original, + * so just check it for disallowed chars. + */ + switch (r->proxyreq) { + default: /* wtf are we doing here? */ + case PROXYREQ_REVERSE: + path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); + break; + case PROXYREQ_PROXY: + for (p = url; *p; ++p) { + if (!apr_isalnum(*p) && !strchr(allowed, *p)) { + if (*p == '%' && apr_isxdigit(p[1]) && apr_isxdigit(p[2])) { + p += 2; /* an encoded char */ + } + else { + return HTTP_BAD_REQUEST; /* reject bad char in URL */ + } + } + } + path = url; + break; + } + if (path == NULL) return HTTP_BAD_REQUEST; -- 2.40.0