summaryrefslogtreecommitdiff
path: root/modules/mappers
diff options
context:
space:
mode:
authorRuediger Pluem <rpluem@apache.org>2021-10-08 10:49:06 +0000
committerRuediger Pluem <rpluem@apache.org>2021-10-08 10:49:06 +0000
commitd8b3d1f0f6ed16ff6f83a30513aac573a8a44c34 (patch)
tree2ebd8a09d1880fdc63c3295729b8ede7f9f92b96 /modules/mappers
parent861c15e03c41851de1157c15b9a4f737967cd5fc (diff)
downloadhttpd-d8b3d1f0f6ed16ff6f83a30513aac573a8a44c34.tar.gz
* 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
Diffstat (limited to 'modules/mappers')
-rw-r--r--modules/mappers/mod_alias.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c
index 569d331e7f..f14d6cb6f3 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] != '/') {