]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Follow up to r1919620: Restore r->filename re-encoding for ProxyPass URLs.
authorYann Ylavic <ylavic@apache.org>
Fri, 2 Aug 2024 00:53:53 +0000 (00:53 +0000)
committerYann Ylavic <ylavic@apache.org>
Fri, 2 Aug 2024 00:53:53 +0000 (00:53 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1919628 13f79535-47bb-0310-9956-ffa450edef68

changes-entries/bz69203.txt
modules/proxy/mod_proxy.c
modules/proxy/mod_proxy_fcgi.c

index 4d9080ba37c6c7897277a8f3580be754771453e6..2408352a3bd5953ef1e673aa09d71be790a23eed 100644 (file)
@@ -1 +1,2 @@
-  *) mod_proxy_fcgi: Don't re-encode SCRIPT_FILENAME. PR 69203. [Yann Ylavic]
\ No newline at end of file
+  *) mod_proxy_fcgi: Don't re-encode SCRIPT_FILENAME when set via SetHandler.
+     PR 69203. [Yann Ylavic]
\ No newline at end of file
index 0b6be1a1b02e2322c5705c7359ea3aec01580b4c..a4e7a1aed1744c5c563f23be3d131a3056274dc8 100644 (file)
@@ -1246,6 +1246,7 @@ static int proxy_handler(request_rec *r)
 
         r->proxyreq = PROXYREQ_REVERSE;
         r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL);
+        apr_table_setn(r->notes, "proxy-sethandler", "1");
 
         /* Still need to canonicalize r->filename */
         rc = ap_proxy_canon_url(r);
@@ -1255,6 +1256,7 @@ static int proxy_handler(request_rec *r)
         }
     }
     else if (r->proxyreq && strncmp(r->filename, "proxy:", 6) == 0) {
+        apr_table_unset(r->notes, "proxy-sethandler");
         rc = OK;
     }
     if (rc != OK) {
index 9f2fbf34e9c238b6effb5c5afa29cd18def48576..94aeae7ac4dbde7e1c5d2fbb969e91f5e288e301 100644 (file)
@@ -59,10 +59,13 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
 {
     char *host, sport[7];
     const char *err;
-    char *path, *pc;
+    char *path;
     apr_port_t port, def_port;
     fcgi_req_config_t *rconf = NULL;
     const char *pathinfo_type = NULL;
+    fcgi_dirconf_t *dconf = ap_get_module_config(r->per_dir_config,
+                                                 &proxy_fcgi_module);
+    int from_handler;
 
     if (ap_cstr_casecmpn(url, "fcgi:", 5) == 0) {
         url += 5;
@@ -71,12 +74,11 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
         return DECLINED;
     }
 
-    path = url;
     port = def_port = ap_proxy_port_of_scheme("fcgi");
 
     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                  "canonicalising URL %s", url);
-    err = ap_proxy_canon_netloc(r->pool, &path, NULL, NULL, &host, &port);
+    err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
     if (err) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01059)
                       "error parsing URL %s: %s", url, err);
@@ -93,20 +95,40 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
         host = apr_pstrcat(r->pool, "[", host, "]", NULL);
     }
 
-    /* We do not call ap_proxy_canonenc_ex() on the path here because the CGI
-     * environment variable SCRIPT_FILENAME based on it want the decoded/local
-     * path, don't let control characters pass still.
-     *
-     * XXX: should we encode based on dconf->backend_type though?
-     */
-    for (pc = path; *pc; pc++) {
-        if (apr_iscntrl(*pc)) {
+    from_handler = apr_table_get(r->notes, "proxy-sethandler") != NULL;
+    if (from_handler
+        || apr_table_get(r->notes, "proxy-nocanon")
+        || apr_table_get(r->notes, "proxy-noencode")) {
+        char *c = path = url;   /* this is the raw path */
+
+        /* We do not call ap_proxy_canonenc_ex() on the path here, don't
+         * let control characters pass still, and for php-fpm no '?' either.
+         */
+        if (FCGI_MAY_BE_FPM(dconf)) {
+            while (!apr_iscntrl(*c) && *c != '?')
+                c++;
+        }
+        else {
+            while (!apr_iscntrl(*c))
+                c++;
+        }
+        if (*c) {
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10414)
-                          "To be forwarded path contains control "
-                          "characters");
+                          "To be forwarded path contains control characters%s",
+                          FCGI_MAY_BE_FPM(dconf) ? " or '?'" : "");
             return HTTP_FORBIDDEN;
         }
     }
+    else {
+        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+        int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
+
+        path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
+                                    r->proxyreq);
+        if (!path) {
+            return HTTP_BAD_REQUEST;
+        }
+    }
 
     r->filename = apr_pstrcat(r->pool, "proxy:fcgi://", host, sport, "/",
                               path, NULL);