File apache2-CVE-2019-10092.patch of Package apache2.14724
commit 0522155a5a0fb5ba3b5716a63a3c2253aa74085e
Author: Stefan Eissing <icing@apache.org>
Date: Fri Aug 9 11:59:15 2019 +0000
Merge of r1864693,1864695,1864703 from trunk;
*) mod_proxy: Improve XSRF/XSS protection. [Joe Orton]
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1864787 13f79535-47bb-0310-9956-ffa450edef68
Index: httpd-2.4.16/modules/proxy/mod_proxy_balancer.c
===================================================================
--- httpd-2.4.16.orig/modules/proxy/mod_proxy_balancer.c 2015-05-29 22:07:15.000000000 +0200
+++ httpd-2.4.16/modules/proxy/mod_proxy_balancer.c 2019-08-22 13:19:45.877352651 +0200
@@ -969,6 +969,18 @@ static void push2table(const char *input
}
}
+/* 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=....).
@@ -987,7 +999,7 @@ static int balancer_handler(request_rec
apr_table_t *params;
int i, n;
int ok2change = 1;
- const char *name;
+ const char *name, *ref;
const char *action;
apr_status_t rv;
@@ -1043,6 +1055,16 @@ static int balancer_handler(request_rec
buf[len] = '\0';
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);
+ }
+
if ((name = apr_table_get(params, "b")))
bsel = ap_proxy_get_balancer(r->pool, conf,
apr_pstrcat(r->pool, BALANCER_PREFIX, name, NULL), 0);
@@ -1256,7 +1278,7 @@ static int balancer_handler(request_rec
/* Start proxy_balancer */
ap_rvputs(r, " <httpd:name>", balancer->s->name, "</httpd:name>\n", NULL);
if (balancer->s->sticky) {
- ap_rvputs(r, " <httpd:stickysession>", balancer->s->sticky,
+ ap_rvputs(r, " <httpd:stickysession>", ap_escape_html(r->pool, balancer->s->sticky),
"</httpd:stickysession>\n", NULL);
ap_rprintf(r,
" <httpd:nofailover>%s</httpd:nofailover>\n",
@@ -1491,11 +1513,11 @@ static int balancer_handler(request_rec
balancer->max_workers - (int)storage->num_free_slots(balancer->wslot));
if (*balancer->s->sticky) {
if (strcmp(balancer->s->sticky, balancer->s->sticky_path)) {
- ap_rvputs(r, "<td>", balancer->s->sticky, " | ",
- balancer->s->sticky_path, NULL);
+ ap_rvputs(r, "<td>", ap_escape_html(r->pool, balancer->s->sticky), " | ",
+ ap_escape_html(r->pool, balancer->s->sticky_path), NULL);
}
else {
- ap_rvputs(r, "<td>", balancer->s->sticky, NULL);
+ ap_rvputs(r, "<td>", ap_escape_html(r->pool, balancer->s->sticky), NULL);
}
}
else {
@@ -1587,10 +1609,10 @@ static int balancer_handler(request_rec
ap_rputs("</tr></table>\n", r);
ap_rputs("<tr><td colspan=2><input type=submit value='Submit'></td></tr>\n", r);
ap_rvputs(r, "</table>\n<input type=hidden name='w' id='w' ", NULL);
- ap_rvputs(r, "value='", ap_escape_uri(r->pool, wsel->s->name), "'>\n", NULL);
+ ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->s->name), "\">\n", NULL);
ap_rvputs(r, "<input type=hidden name='b' id='b' ", NULL);
- ap_rvputs(r, "value='", bsel->s->name + sizeof(BALANCER_PREFIX) - 1,
- "'>\n", NULL);
+ ap_rvputs(r, "value=\"", ap_escape_html(r->pool, bsel->s->name + sizeof(BALANCER_PREFIX) - 1),
+ "\">\n", NULL);
ap_rvputs(r, "<input type=hidden name='nonce' id='nonce' value='",
bsel->s->nonce, "'>\n", NULL);
ap_rputs("</form>\n", r);
@@ -1600,9 +1622,9 @@ static int balancer_handler(request_rec
const ap_list_provider_names_t *pname;
int i;
ap_rputs("<h3>Edit balancer settings for ", r);
- ap_rvputs(r, bsel->s->name, "</h3>\n", NULL);
- ap_rputs("<form method='POST' enctype='application/x-www-form-urlencoded' action='", r);
- ap_rvputs(r, ap_escape_uri(r->pool, action), "'>\n", NULL);
+ ap_rvputs(r, ap_escape_html(r->pool, bsel->s->name), "</h3>\n", NULL);
+ ap_rputs("<form method='POST' enctype='application/x-www-form-urlencoded' action=\"", r);
+ ap_rvputs(r, ap_escape_uri(r->pool, action), "\">\n", NULL);
ap_rputs("<dl>\n<table>\n", r);
provs = ap_list_provider_names(r->pool, PROXY_LBMETHOD, "0");
if (provs) {
@@ -1625,13 +1647,13 @@ static int balancer_handler(request_rec
create_radio("b_sforce", bsel->s->sticky_force, r);
ap_rputs("<tr><td>Sticky Session:</td><td><input name='b_ss' id='b_ss' size=64 type=text ", r);
if (strcmp(bsel->s->sticky, bsel->s->sticky_path)) {
- ap_rvputs(r, "value ='", bsel->s->sticky, " | ",
- bsel->s->sticky_path, NULL);
+ ap_rvputs(r, "value =\"", ap_escape_html(r->pool, bsel->s->sticky), " | ",
+ ap_escape_html(r->pool, bsel->s->sticky_path), NULL);
}
else {
- ap_rvputs(r, "value ='", bsel->s->sticky, NULL);
+ ap_rvputs(r, "value =\"", ap_escape_html(r->pool, bsel->s->sticky), NULL);
}
- ap_rputs("'> (Use '-' to delete)</td></tr>\n", r);
+ ap_rputs("\"> (Use '-' to delete)</td></tr>\n", r);
if (storage->num_free_slots(bsel->wslot) != 0) {
ap_rputs("<tr><td>Add New Worker:</td><td><input name='b_nwrkr' id='b_nwrkr' size=32 type=text>"
" Are you sure? <input name='b_wyes' id='b_wyes' type=checkbox value='1'>"
@@ -1639,8 +1661,8 @@ static int balancer_handler(request_rec
}
ap_rputs("<tr><td colspan=2><input type=submit value='Submit'></td></tr>\n", r);
ap_rvputs(r, "</table>\n<input type=hidden name='b' id='b' ", NULL);
- ap_rvputs(r, "value='", bsel->s->name + sizeof(BALANCER_PREFIX) - 1,
- "'>\n", NULL);
+ ap_rvputs(r, "value=\"", ap_escape_html(r->pool, bsel->s->name + sizeof(BALANCER_PREFIX) - 1),
+ "\">\n", NULL);
ap_rvputs(r, "<input type=hidden name='nonce' id='nonce' value='",
bsel->s->nonce, "'>\n", NULL);
ap_rputs("</form>\n", r);
Index: httpd-2.4.16/modules/proxy/proxy_util.c
===================================================================
--- httpd-2.4.16.orig/modules/proxy/proxy_util.c 2015-06-02 15:40:41.000000000 +0200
+++ httpd-2.4.16/modules/proxy/proxy_util.c 2019-08-22 13:00:22.982367293 +0200
@@ -1253,10 +1253,11 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sha
if (*balancer->s->nonce == PROXY_UNSET_NONCE) {
char nonce[APR_UUID_FORMATTED_LENGTH + 1];
apr_uuid_t uuid;
- /* Retrieve a UUID and store the nonce for the lifetime of
- * the process.
- */
- apr_uuid_get(&uuid);
+
+ /* Generate a pseudo-UUID from the PRNG to use as a nonce for
+ * the lifetime of the process. uuid.data is a char array so
+ * this is an adequate substitute for apr_uuid_get(). */
+ ap_random_insecure_bytes(uuid.data, sizeof uuid.data);
apr_uuid_format(nonce, &uuid);
rv = PROXY_STRNCPY(balancer->s->nonce, nonce);
}