]> granicus.if.org Git - apache/commitdiff
mod_proxy_http: Don't unescape/escape forward proxied URLs. Just check them.
authorNick Kew <niq@apache.org>
Mon, 8 Oct 2007 23:47:35 +0000 (23:47 +0000)
committerNick Kew <niq@apache.org>
Mon, 8 Oct 2007 23:47:35 +0000 (23:47 +0000)
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
modules/proxy/mod_proxy_http.c

diff --git a/CHANGES b/CHANGES
index 0ec6f735561ac7dfce474bd4a907bfec5bb5b14a..28920e62c7cb6f1b6a44044168261e6c39d5b204 100644 (file)
--- 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]
 
index 0f74b7933e5eaa4d8de137748204789a2c240fd9..c7a1bfd4a4218db77557d74882bb38249a7d5d20 100644 (file)
@@ -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;