On Thu, Jun 25, 2020 at 9:24 AM Ruediger Pluem <[email protected]> wrote:
>
> The other thing that still worries me and that I think is not covered is the 
> following scenario:
>
> <Location /admin>
>
> ..... some authn and authz ....
>
> </Location>
>
> ProxyPass / http://
>
> Here the Apache is used to do authn and authz for the backend.
>
> /app/..;pp=somevalue/admin/nastything
>
> IMHO could circumvent this no matter what the mapping option is set to in 
> ProxyPass

Yes, very true.

But if we want mapping=servlet to take "ownership" of r->uri, we can
do something like the attached patch.
The result is that if mod_proxy matches a servlet URI-path, r->uri
gets servlet normalized (without the path parameters) for the rest of
the request handling.
So your above example gets rewritten to "/admin/nastything" and
"<Location /admin>" now applies.

Would that be better?

Regards;
Yann
Index: modules/proxy/mod_proxy.c
===================================================================
--- modules/proxy/mod_proxy.c	(revision 1879145)
+++ modules/proxy/mod_proxy.c	(working copy)
@@ -574,10 +574,11 @@ static int alias_match(const char *uri, const char
  * Inspired by mod_jk's jk_servlet_normalize().
  */
 static int alias_match_servlet(apr_pool_t *p,
-                               const char *uri,
+                               const char **urip,
                                const char *alias)
 {
     char *map;
+    const char *uri = *urip;
     apr_array_header_t *stack;
     int map_pos, uri_pos, alias_pos, first_pos;
     int alias_depth = 0, depth;
@@ -759,6 +760,8 @@ static int alias_match_servlet(apr_pool_t *p,
     if (alias[alias_pos - 1] != '/' && uri[uri_pos - 1] == '/') {
         uri_pos--;
     }
+
+    *urip = map;
     return uri_pos;
 }
 
@@ -869,7 +872,7 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_re
     ap_regmatch_t regm[AP_MAX_REG_MATCH];
     ap_regmatch_t reg1[AP_MAX_REG_MATCH];
     char *found = NULL;
-    int mismatch = 0;
+    int mismatch = 0, servlet = 0;
     unsigned int nocanon = ent->flags & PROXYPASS_NOCANON;
     const char *use_uri = nocanon ? r->unparsed_uri : r->uri;
 
@@ -933,8 +936,9 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_re
     }
     else {
         if ((ent->flags & PROXYPASS_MAP_SERVLET) == PROXYPASS_MAP_SERVLET) {
+            len = alias_match_servlet(r->pool, (const char **)&r->uri, fake);
             nocanon = 0; /* ignored since servlet's normalization applies */
-            len = alias_match_servlet(r->pool, r->uri, fake);
+            servlet = 1;
         }
         else {
             len = alias_match(r->uri, fake);
@@ -969,7 +973,7 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_re
          */
         int rc = proxy_run_check_trans(r, found + 6);
         if (rc != OK && rc != DECLINED) {
-            return DONE;
+            return HTTP_CONTINUE;
         }
 
         r->filename = found;
@@ -987,10 +991,10 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_re
                       "URI path '%s' matches proxy handler '%s'", r->uri,
                       found);
 
-        return OK;
+        return servlet ? DONE : OK;
     }
 
-    return DONE;
+    return HTTP_CONTINUE;
 }
 
 static int proxy_trans(request_rec *r, int pre_trans)
@@ -1042,7 +1046,7 @@ static int proxy_trans(request_rec *r, int pre_tra
         enc = (dconf->alias->flags & PROXYPASS_MAP_ENCODED) != 0;
         if (!(pre_trans ^ enc)) {
             int rv = ap_proxy_trans_match(r, dconf->alias, dconf);
-            if (DONE != rv) {
+            if (rv != HTTP_CONTINUE) {
                 return rv;
             }
         }
@@ -1054,7 +1058,7 @@ static int proxy_trans(request_rec *r, int pre_tra
         enc = (ent->flags & PROXYPASS_MAP_ENCODED) != 0;
         if (!(pre_trans ^ enc)) {
             int rv = ap_proxy_trans_match(r, ent, dconf);
-            if (DONE != rv) {
+            if (rv != HTTP_CONTINUE) {
                 return rv;
             }
         }

Reply via email to