summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--docs/manual/mod/core.xml23
-rw-r--r--include/ap_mmn.h3
-rw-r--r--include/http_core.h2
-rw-r--r--include/httpd.h2
-rw-r--r--server/core.c21
-rw-r--r--server/request.c2
-rw-r--r--server/util.c18
8 files changed, 56 insertions, 20 deletions
diff --git a/CHANGES b/CHANGES
index fdc20dcf09..20807cd370 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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.