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;