]> granicus.if.org Git - apache/commitdiff
here we go. add a directive that will keep %2f from being
authorKen Coar <coar@apache.org>
Thu, 23 Jan 2003 21:34:13 +0000 (21:34 +0000)
committerKen Coar <coar@apache.org>
Thu, 23 Jan 2003 21:34:13 +0000 (21:34 +0000)
decoded into '/', allowing the *_walk to do their magic and
return 404 if it's in the path, and allowing it in the path-info.

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

include/ap_mmn.h
include/http_core.h
include/httpd.h
server/core.c
server/request.c
server/util.c

index 54ec08eed24fadaa0e4f7734fe472a9c50f8240b..24ba923c26e38e3da55fb92b02a0a2e30fe083c6 100644 (file)
  * 20020625 (2.0.40-dev) Changed conn_rec->keepalive to an enumeration
  * 20020628 (2.0.40-dev) Added filter_init to filter registration functions
  * 20020903 (2.0.41-dev) APR's error constants changed
+ * 20020903.1 (2.0.44-dev) allow_encoded_slashes added to core_dir_config
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20020903
 #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 86a8dd380a974a7fbd892f7a4a3235475f067ef6..44027cee2311c0ea69874eb482de4bdb205ce4f7 100644 (file)
@@ -537,7 +537,8 @@ typedef struct {
 #define ENABLE_SENDFILE_ON     (1)
 #define ENABLE_SENDFILE_UNSET  (2)
     unsigned int enable_sendfile : 2;  /* files in this dir can be mmap'ed */
-
+    unsigned int allow_encoded_slashes : 1; /* URLs may contain %2f w/o being
+                                             * pitched indiscriminately */
 } core_dir_config;
 
 /* Per-server core configuration */
index 3fae59e73f5abc65f02b2eb8798d764fa356c0e5..b1f7423ac918b59addcc53b662d7260406dcc177 100644 (file)
@@ -1309,10 +1309,16 @@ AP_DECLARE(int) ap_is_url(const char *u);
 
 /**
  * Unescape a URL
- * @param url The url to unescapte
+ * @param url The url to unescape
  * @return 0 on success, non-zero otherwise
  */
 AP_DECLARE(int) ap_unescape_url(char *url);
+/**
+ * Unescape a URL, but leaving %2f (slashes) escaped
+ * @param url The url to unescape
+ * @return 0 on success, non-zero otherwise
+ */
+AP_DECLARE(int) ap_unescape_url_keep2f(char *url);
 /**
  * Convert all double slashes to single slashes
  * @param name The string to convert
index 62b2fa509a266611d05d5383fa0a3124158e781b..b919c3229fe10d252a5b486f7ec2a654161b0f45 100644 (file)
@@ -180,6 +180,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;
 
     return (void *)conf;
 }
@@ -446,6 +447,8 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
         conf->enable_sendfile = new->enable_sendfile;
     }
 
+    conf->allow_encoded_slashes = new->allow_encoded_slashes;
+    
     return (void*)conf;
 }
 
@@ -2066,6 +2069,19 @@ 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)
+{
+    core_dir_config *d = d_;
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
+
+    if (err != NULL) {
+        return err;
+    }
+
+    d->allow_encoded_slashes = arg != 0;
+    return NULL;
+}
+
 static const char *set_hostname_lookups(cmd_parms *cmd, void *d_,
                                         const char *arg)
 {
@@ -3054,6 +3070,8 @@ 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,
+             "Allow URLs containing '/' encoded as '%2F'"),
 
 /*
  * These are default configuration directives that mpms can/should
index 051c224f26533875c34a2967be4545bd45b5c5b7..b255e8b828f4dd475945bd6ad0369ad4f46d99a1 100644 (file)
@@ -147,13 +147,22 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r)
 
     /* Ignore embedded %2F's in path for proxy requests */
     if (!r->proxyreq && r->parsed_uri.path) {
-        access_status = ap_unescape_url(r->parsed_uri.path);
+        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);
+        }
+        else {
+            access_status = ap_unescape_url(r->parsed_uri.path);
+        }
         if (access_status) {
             if (access_status == HTTP_NOT_FOUND) {
-                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
-                              "found %%2f (encoded '/') in URI "
-                              "(decoded='%s'), returning 404",
-                              r->parsed_uri.path);
+                if (! d->allow_encoded_slashes) {
+                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+                                  "found %%2f (encoded '/') in URI "
+                                  "(decoded='%s'), returning 404",
+                                  r->parsed_uri.path);
+                }
             }
             return access_status;
         }
index c028bf51c6bc44a8775c83211cf1eec3f4721fea..65da169f311a4b5c3e28b8d386f481689bdd9498 100644 (file)
@@ -1595,6 +1595,57 @@ AP_DECLARE(int) ap_unescape_url(char *url)
         return OK;
 }
 
+AP_DECLARE(int) ap_unescape_url_keep2f(char *url)
+{
+    register int badesc, badpath;
+    char *x, *y;
+
+    badesc = 0;
+    badpath = 0;
+    /* Initial scan for first '%'. Don't bother writing values before
+     * seeing a '%' */
+    y = strchr(url, '%');
+    if (y == NULL) {
+        return OK;
+    }
+    for (x = y; *y; ++x, ++y) {
+        if (*y != '%') {
+            *x = *y;
+        }
+        else {
+            if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) {
+                badesc = 1;
+                *x = '%';
+            }
+            else {
+                char decoded;
+                decoded = x2c(y + 1);
+                if (IS_SLASH(decoded)) {
+                    *x++ = *y++;
+                    *x = *y;
+                }
+                else {
+                    *x = decoded;
+                    y += 2;
+                    if (decoded == '\0') {
+                        badpath = 1;
+                    }
+                }
+            }
+        }
+    }
+    *x = '\0';
+    if (badesc) {
+        return HTTP_BAD_REQUEST;
+    }
+    else if (badpath) {
+        return HTTP_NOT_FOUND;
+    }
+    else {
+        return OK;
+    }
+}
+
 AP_DECLARE(char *) ap_construct_server(apr_pool_t *p, const char *hostname,
                                        apr_port_t port, const request_rec *r)
 {