]> granicus.if.org Git - apache/commitdiff
* modules/proxy/mod_proxy_balancer.c (balancer_handler): Check Referer
authorJoe Orton <jorton@apache.org>
Thu, 8 Aug 2019 12:11:36 +0000 (12:11 +0000)
committerJoe Orton <jorton@apache.org>
Thu, 8 Aug 2019 12:11:36 +0000 (12:11 +0000)
  to improve on protection against balancer-manager XSRF attacks
  provided by the nonce.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1864695 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/mod_proxy_balancer.c

index 0ca13fd343cda1662da4b35b699b0cb10e7294ba..ca00f562389733871c986906202ae3caeebdc399 100644 (file)
@@ -1843,6 +1843,18 @@ static void balancer_display_page(request_rec *r, proxy_server_conf *conf,
     }
 }
 
+/* Returns non-zero if the Referer: header value passed matches the
+ * host of the request. */
+static int safe_referer(request_rec *r, const char *ref)
+{
+    apr_uri_t uri;
+
+    if (apr_uri_parse(r->pool, ref, &uri) || !uri.hostname)
+        return 0;
+
+    return strcmp(uri.hostname, ap_get_server_name(r)) == 0;
+}
+
 /* Manages the loadfactors and member status
  *   The balancer, worker and nonce are obtained from
  *   the request args (?b=...&w=...&nonce=....).
@@ -1860,7 +1872,7 @@ static int balancer_handler(request_rec *r)
     apr_table_t *params;
     int i;
     int ok2change = 1;
-    const char *name;
+    const char *name, *ref;
     apr_status_t rv;
 
     /* is this for us? */
@@ -1920,6 +1932,15 @@ static int balancer_handler(request_rec *r)
         push2table(buf, params, NULL, r->pool);
     }
 
+    /* Ignore parameters if this looks like XSRF */
+    ref = apr_table_get(r->headers_in, "Referer");
+    if (apr_table_elts(params)
+        && (!ref || !safe_referer(r, ref))) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10187)
+                      "ignoring params in balancer-manager cross-site access");
+        apr_table_clear(params);
+    }
+    
     /* Process the parameters */
     if ((name = apr_table_get(params, "b")))
         bsel = ap_proxy_get_balancer(r->pool, conf,