]> granicus.if.org Git - apache/commitdiff
core: AllowEncodedSlashes new option NoDecode to allow encoded slashes
authorDaniel Earl Poirier <poirier@apache.org>
Wed, 16 Mar 2011 16:45:25 +0000 (16:45 +0000)
committerDaniel Earl Poirier <poirier@apache.org>
Wed, 16 Mar 2011 16:45:25 +0000 (16:45 +0000)
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.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1082196 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/core.xml
include/ap_mmn.h
include/http_core.h
include/httpd.h
server/core.c
server/request.c
server/util.c

diff --git a/CHANGES b/CHANGES
index fdc20dcf09fe150093ee28cd8fe553406974dbe5..20807cd370ded34560ddec12e36fa2f112f76006 100644 (file)
--- 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>]
 
index a3c7d2dec0b6baf211fc0147c07ff29263655517..a219feccd6fafffb11483df64cd2e0938f95d772 100644 (file)
@@ -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>
index 70f25ce42d0ac2c219f25e8121bd3c5f5973ae07..fbc9dfd5fcd946f50ea06361aebcecd384aecd9a 100644 (file)
                            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" */
 #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
index 277b2710610e1ba0294cda651a900c22ba598aba..e674915b8a41a573bf35574bbd1a5c9b52482933 100644 (file)
@@ -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 */
index a7650a7df7b9f96d03595507fb1941ad110c1a7f..8086ff8e1c7de3001ef237ff81501e0f6d9980c7 100644 (file)
@@ -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
index f764df667a09b96e862825da010aaea6fc3587d9..6600df332ea025c29dddca8939a55421bdd4d171 100644 (file)
@@ -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 */
index fa6d9b7d82ed08120b824eee4d709b78eb2f0a55..b0ec847361e1394ca4beff6d4d7cd759f08f9d88 100644 (file)
@@ -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);
index c443c942a3d37fb37ab09e83b3262c6d1a31a3d5..a6bdfd0c4144e044fa25a024f9f74fe1781226dd 100644 (file)
  */
 #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.