From: Daniel Earl Poirier Date: Thu, 17 Mar 2011 18:40:40 +0000 (+0000) Subject: Backport r1082196 from trunk: X-Git-Tag: 2.2.18~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3682577cddb11a83e7e270f857f5e4943fd85c14;p=thirdparty%2Fapache%2Fhttpd.git Backport r1082196 from trunk: core: AllowEncodedSlashes new option NoDecode to allow encoded slashes in request URL path info but not decode them. PR: 35256, 46830 Reviewed by: jim, covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1082630 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 7710ed66e9e..3109cdb3aec 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.18 + *) core: AllowEncodedSlashes new option NoDecode to allow encoded slashes + in request URL path info but not decode them. PR 35256, + PR 46830. [Dan Poirier] + *) mod_rewrite: Allow to unset environment variables. PR 50746. [Rainer Jung] diff --git a/STATUS b/STATUS index be76f20411b..f1c45c3402c 100644 --- a/STATUS +++ b/STATUS @@ -90,20 +90,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * core: Add NoDecode option to AllowEncodedSlashes to turn off decoding - of encoded slashes in path info. (This is already the behavior of - AllowEncodedSlashes On in trunk.) - Trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1082196 - Backport version for 2.2.x of patch: - http://people.apache.org/~poirier/AllowEncodedSlashes.22.patch - +1 poirier, jim, covener - +.1 wrowe; this essentially causes "%2F" -> "%2F" -> "%252F" to any backend, - as mentioned previously trunk is broken and decoding to 'something' - is necessary for routing such. %2F cannot be distinguished from - %252F on the front end, adding risks. All this said, not against - an optional broken feature if this warning is placed in the docs. - Non-optional broken features are worse :) - Trunk must be patched identically. PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index 8a4946168f8..e81caee2bbb 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -307,26 +307,35 @@ content-type is text/plain or text/html AllowEncodedSlashes Determines whether encoded path separators in URLs are allowed to be passed through -AllowEncodedSlashes On|Off +AllowEncodedSlashes On|Off|NoDecode AllowEncodedSlashes Off server configvirtual host -Available in Apache 2.0.46 and later +Available in Apache httpd 2.0.46 and later. +NoDecode option available in 2.2.18 and later.

The AllowEncodedSlashes directive allows URLs which contain encoded path separators (%2F for / and additionally %5C for \ on according systems) - to be used. Normally such URLs are refused with a 404 (Not found) error.

+ to be used in the path info.

+ +

With the default value, Off, such URLs are refused + with a 404 (Not found) error.

+ +

With the value On, such URLs are accepted, and encoded + slashes are decoded like all other encoded characters.

+ +

With the value NoDecode, such URLs are accepted, but + encoded slashes are not decoded but left in their encoded state.

Turning AllowEncodedSlashes On is mostly useful when used in conjunction with PATH_INFO.

Note -

Allowing encoded slashes does not imply decoding. - Occurrences of %2F or %5C (only on - according systems) will be left as such in the otherwise decoded URL - string.

+

If encoded slashes are needed in path info, use of NoDecode is + strongly recommended as a security measure. Allowing slashes + to be decoded could potentially allow unsafe paths.

AcceptPathInfo diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 3658fb73fa3..6d847c6b742 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -141,6 +141,7 @@ * 20051115.24 (2.2.15) Add forward member to proxy_conn_rec * 20051115.25 (2.2.17) Add errstatuses member to proxy_balancer * 20051115.26 (2.2.18) Add ap_cache_check_allowed() + * 20051115.27 (2.2.18) Add core_dir_config.decode_encoded_slashes. */ #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ @@ -148,7 +149,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20051115 #endif -#define MODULE_MAGIC_NUMBER_MINOR 26 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 27 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/http_core.h b/include/http_core.h index f124f21947f..0b96cca5aa9 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -568,6 +568,8 @@ typedef struct { #define USE_CANONICAL_PHYS_PORT_UNSET (2) unsigned use_canonical_phys_port : 2; + + unsigned int decode_encoded_slashes : 1; /* whether to decode encoded slashes in URLs */ } core_dir_config; /* Per-server core configuration */ diff --git a/include/httpd.h b/include/httpd.h index 500f38cb827..c872a454f0b 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -1454,7 +1454,7 @@ AP_DECLARE(int) ap_unescape_url(char *url); * @param url The url to unescape * @return 0 on success, non-zero otherwise */ -AP_DECLARE(int) ap_unescape_url_keep2f(char *url); +AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes); /** * Convert all double slashes to single slashes diff --git a/server/core.c b/server/core.c index 4d0056b74cb..ea01ca926d7 100644 --- a/server/core.c +++ b/server/core.c @@ -164,6 +164,7 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir) conf->enable_mmap = ENABLE_MMAP_UNSET; conf->enable_sendfile = ENABLE_SENDFILE_UNSET; conf->allow_encoded_slashes = 0; + conf->decode_encoded_slashes = 0; return (void *)conf; } @@ -450,6 +451,7 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) } conf->allow_encoded_slashes = new->allow_encoded_slashes; + conf->decode_encoded_slashes = new->decode_encoded_slashes; return (void*)conf; } @@ -2435,7 +2437,7 @@ static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg) return NULL; } -static const char *set_allow2f(cmd_parms *cmd, void *d_, int arg) +static const char *set_allow2f(cmd_parms *cmd, void *d_, const char *arg) { core_dir_config *d = d_; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); @@ -2444,7 +2446,20 @@ static const char *set_allow2f(cmd_parms *cmd, void *d_, int arg) return err; } - d->allow_encoded_slashes = arg != 0; + if (0 == strcasecmp(arg, "on")) { + d->allow_encoded_slashes = 1; + d->decode_encoded_slashes = 1; + } else if (0 == strcasecmp(arg, "off")) { + d->allow_encoded_slashes = 0; + d->decode_encoded_slashes = 0; + } else if (0 == strcasecmp(arg, "nodecode")) { + d->allow_encoded_slashes = 1; + d->decode_encoded_slashes = 0; + } else { + return apr_pstrcat(cmd->pool, + cmd->cmd->name, " must be On, Off, or NoDecode", + NULL); + } return NULL; } @@ -3437,7 +3452,7 @@ AP_INIT_TAKE1("SetInputFilter", ap_set_string_slot, AP_INIT_ITERATE2("AddOutputFilterByType", add_ct_output_filters, (void *)APR_OFFSETOF(core_dir_config, ct_output_filters), OR_FILEINFO, "output filter name followed by one or more content-types"), -AP_INIT_FLAG("AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF, +AP_INIT_TAKE1("AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF, "Allow URLs containing '/' encoded as '%2F'"), /* diff --git a/server/request.c b/server/request.c index 1801cf7b5ec..f70bb94d4a2 100644 --- a/server/request.c +++ b/server/request.c @@ -109,7 +109,7 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) core_dir_config *d; d = ap_get_module_config(r->per_dir_config, &core_module); if (d->allow_encoded_slashes) { - access_status = ap_unescape_url_keep2f(r->parsed_uri.path); + access_status = ap_unescape_url_keep2f(r->parsed_uri.path, d->decode_encoded_slashes); } else { access_status = ap_unescape_url(r->parsed_uri.path); diff --git a/server/util.c b/server/util.c index ac429c788ae..b5bd872fea2 100644 --- a/server/util.c +++ b/server/util.c @@ -1589,7 +1589,7 @@ AP_DECLARE(int) ap_unescape_url(char *url) return OK; } -AP_DECLARE(int) ap_unescape_url_keep2f(char *url) +AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_2f) { register int badesc, badpath; char *x, *y; @@ -1617,6 +1617,10 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url) if (decoded == '\0') { badpath = 1; } + else if (IS_SLASH(decoded) && !decode_2f) { + /* do not decode, just let it go by as-is */ + *x = *y; + } else { *x = decoded; y += 2;