From: Ruediger Pluem Date: Fri, 8 Oct 2021 10:49:06 +0000 (+0000) Subject: * Make aliases more robust against potential traversal attacks, by using X-Git-Tag: 2.5.0-alpha2-ci-test-only~759 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8b3d1f0f6ed16ff6f83a30513aac573a8a44c34;p=thirdparty%2Fapache%2Fhttpd.git * Make aliases more robust against potential traversal attacks, by using apr_filepath_merge to merge the real path and the remainder of the fake path like we do in the same situation for resources mapped by DocumentRoot. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1894024 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index 6f3af99369f..c62bdf7d0a6 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -10297 +10298 diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c index 569d331e7f4..f14d6cb6f3e 100644 --- a/modules/mappers/mod_alias.c +++ b/modules/mappers/mod_alias.c @@ -67,8 +67,10 @@ typedef struct { module AP_MODULE_DECLARE_DATA alias_module; -static char magic_error_value; -#define PREGSUB_ERROR (&magic_error_value) +static char magic_pregsub_error_value; +#define PREGSUB_ERROR (&magic_pregsub_error_value) +static char magic_merge_error_value; +#define MERGE_ERROR (&magic_merge_error_value) static void *create_alias_config(apr_pool_t *p, server_rec *s) { @@ -500,6 +502,7 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases, alias_entry *entries = (alias_entry *) aliases->elts; ap_regmatch_t regm[AP_MAX_REG_MATCH]; char *found = NULL; + int canon = 1; int i; for (i = 0; i < aliases->nelts; ++i) { @@ -553,8 +556,41 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases, found = apr_pstrcat(r->pool, alias->real, escurl, NULL); } - else + else if (is_redir) { found = apr_pstrcat(r->pool, alias->real, r->uri + l, NULL); + } + else { + apr_status_t rv; + char *fake = r->uri + l; + + /* + * For the apr_filepath_merge below we need a relative path + * Hence skip all leading '/' + */ + while (*fake == '/') { + fake++; + } + + /* Merge if there is something left to merge */ + if (*fake) { + if ((rv = apr_filepath_merge(&found, alias->real, fake, + APR_FILEPATH_TRUENAME + | APR_FILEPATH_SECUREROOT, r->pool)) + != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10297) + "Cannot map %s to file", r->the_request); + return MERGE_ERROR; + } + canon = 0; + } + else { + /* + * r->uri + l might be either pointing to \0 or to a + * string full of '/'s. Hence we need to cat. + */ + found = apr_pstrcat(r->pool, alias->real, r->uri + l, NULL); + } + } } } @@ -568,7 +604,7 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases, * canonicalized. After I finish eliminating os canonical. * Better fail test for ap_server_root_relative needed here. */ - if (!is_redir) { + if (!is_redir && canon) { found = ap_server_root_relative(r->pool, found); } if (found) { @@ -596,7 +632,7 @@ static int translate_alias_redir(request_rec *r) if ((ret = try_redirect(r, &status)) != NULL || (ret = try_alias_list(r, serverconf->redirects, 1, &status)) != NULL) { - if (ret == PREGSUB_ERROR) + if ((ret == PREGSUB_ERROR) || (ret == MERGE_ERROR)) return HTTP_INTERNAL_SERVER_ERROR; if (ap_is_HTTP_REDIRECT(status)) { alias_dir_conf *dirconf = (alias_dir_conf *) @@ -653,7 +689,7 @@ static int fixup_redir(request_rec *r) if ((ret = try_redirect(r, &status)) != NULL || (ret = try_alias_list(r, dirconf->redirects, 1, &status)) != NULL) { - if (ret == PREGSUB_ERROR) + if ((ret == PREGSUB_ERROR) || (ret == MERGE_ERROR)) return HTTP_INTERNAL_SERVER_ERROR; if (ap_is_HTTP_REDIRECT(status)) { if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') {