diff options
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | docs/manual/mod/core.xml | 23 | ||||
-rw-r--r-- | include/ap_mmn.h | 3 | ||||
-rw-r--r-- | include/http_core.h | 2 | ||||
-rw-r--r-- | include/httpd.h | 2 | ||||
-rw-r--r-- | server/core.c | 21 | ||||
-rw-r--r-- | server/request.c | 2 | ||||
-rw-r--r-- | server/util.c | 18 |
8 files changed, 56 insertions, 20 deletions
@@ -2,6 +2,11 @@ Changes with Apache 2.3.12 + *) core: AllowEncodedSlashes new option NoDecode to allow encoded slashes + in request URL path info but not decode them. Change behavior of option + "On" to decode the encoded slashes as 2.0 and 2.2 do. PR 35256, + PR 46830. [Dan Poirier] + *) mod_ssl: Check SNI hostname against Host header case-insensitively. PR 49491. [Mayank Agrawal <magrawal.08 gmail.com>] diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index a3c7d2dec0..a219feccd6 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -269,26 +269,35 @@ content-type is <code>text/plain</code> or <code>text/html</code></description> <name>AllowEncodedSlashes</name> <description>Determines whether encoded path separators in URLs are allowed to be passed through</description> -<syntax>AllowEncodedSlashes On|Off</syntax> +<syntax>AllowEncodedSlashes On|Off|NoDecode</syntax> <default>AllowEncodedSlashes Off</default> <contextlist><context>server config</context><context>virtual host</context> </contextlist> -<compatibility>Available in Apache httpd 2.0.46 and later</compatibility> +<compatibility>Available in Apache httpd 2.0.46 and later. +NoDecode option available in 2.3.12 and later.</compatibility> <usage> <p>The <directive>AllowEncodedSlashes</directive> directive allows URLs which contain encoded path separators (<code>%2F</code> for <code>/</code> and additionally <code>%5C</code> for <code>\</code> on according systems) - to be used. Normally such URLs are refused with a 404 (Not found) error.</p> + to be used in the path info.</p> + + <p>With the default value, <code>Off</code>, such URLs are refused + with a 404 (Not found) error.</p> + + <p>With the value <code>On</code>, such URLs are accepted, and encoded + slashes are decoded like all other encoded characters.</p> + + <p>With the value <code>NoDecode</code>, such URLs are accepted, but + encoded slashes are not decoded but left in their encoded state.</p> <p>Turning <directive>AllowEncodedSlashes</directive> <code>On</code> is mostly useful when used in conjunction with <code>PATH_INFO</code>.</p> <note><title>Note</title> - <p>Allowing encoded slashes does <em>not</em> imply <em>decoding</em>. - Occurrences of <code>%2F</code> or <code>%5C</code> (<em>only</em> on - according systems) will be left as such in the otherwise decoded URL - string.</p> + <p>If encoded slashes are needed in path info, use of <code>NoDecode</code> is + strongly recommended as a security measure. Allowing slashes + to be decoded could potentially allow unsafe paths.</p> </note> </usage> <seealso><directive module="core">AcceptPathInfo</directive></seealso> diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 70f25ce42d..fbc9dfd5fc 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -306,6 +306,7 @@ util_ldap_state_t.connectionPoolTTL, util_ldap_connection_t.freed, and util_ldap_connection_t.rebind_pool. + * 20110312.1 (2.3.12-dev) Add core_dir_config.decode_encoded_slashes. */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -313,7 +314,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20110312 #endif -#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 1 /* 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 277b271061..e674915b8a 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -540,6 +540,8 @@ typedef struct { /** per-dir log config */ struct ap_logconf *log; + + unsigned int decode_encoded_slashes : 1; /* whether to decode encoded slashes in URLs */ } core_dir_config; /* macro to implement off by default behaviour */ diff --git a/include/httpd.h b/include/httpd.h index a7650a7df7..8086ff8e1c 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -1496,7 +1496,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 f764df667a..6600df332e 100644 --- a/server/core.c +++ b/server/core.c @@ -169,6 +169,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; } @@ -372,6 +373,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; if (new->log) { if (!conf->log) { @@ -2634,11 +2636,24 @@ 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_; - d->allow_encoded_slashes = arg != 0; + if (0 == strcasecmp(arg, "on")) { + d->allow_encoded_slashes = 1; + d->decode_encoded_slashes = 1; /* for compatibility with 2.0 & 2.2 */ + } 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; } @@ -3780,7 +3795,7 @@ AP_INIT_TAKE1("SetOutputFilter", ap_set_string_slot, AP_INIT_TAKE1("SetInputFilter", ap_set_string_slot, (void *)APR_OFFSETOF(core_dir_config, input_filters), OR_FILEINFO, "filter (or ; delimited list of filters) to be run on the request body"), -AP_INIT_FLAG("AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF, +AP_INIT_TAKE1("AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF, "Allow URLs containing '/' encoded as '%2F'"), /* scoreboard.c directives */ diff --git a/server/request.c b/server/request.c index fa6d9b7d82..b0ec847361 100644 --- a/server/request.c +++ b/server/request.c @@ -124,7 +124,7 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) if (!r->proxyreq && r->parsed_uri.path) { 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 c443c942a3..a6bdfd0c41 100644 --- a/server/util.c +++ b/server/util.c @@ -79,8 +79,10 @@ */ #ifdef CASE_BLIND_FILESYSTEM #define IS_SLASH(s) ((s == '/') || (s == '\\')) +#define SLASHES "/\\" #else #define IS_SLASH(s) (s == '/') +#define SLASHES "/" #endif APLOG_USE_MODULE(core); @@ -1514,16 +1516,18 @@ static int unescape_url(char *url, const char *forbid, const char *reserved) AP_DECLARE(int) ap_unescape_url(char *url) { /* Traditional */ -#ifdef CASE_BLIND_FILESYSTEM - return unescape_url(url, "/\\", NULL); -#else - return unescape_url(url, "/", NULL); -#endif + return unescape_url(url, SLASHES, NULL); } -AP_DECLARE(int) ap_unescape_url_keep2f(char *url) +AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes) { /* AllowEncodedSlashes (corrected) */ - return unescape_url(url, NULL, "/"); + if (decode_slashes) { + /* no chars reserved */ + return unescape_url(url, NULL, NULL); + } else { + /* reserve (do not decode) encoded slashes */ + return unescape_url(url, NULL, SLASHES); + } } #ifdef NEW_APIS /* IFDEF these out until they've been thought through. |