httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Aaron Bannert <aa...@clove.org>
Subject Re: Backport of AllowEncodedSlashes to Apache 1.3
Date Tue, 29 Mar 2005 16:43:42 GMT
If there's no objection, shall I just go ahead and commit this?
-aaron

On Mar 24, 2005, at 4:38 PM, Aaron Bannert wrote:

> I've attached a patch against the trunk of Apache 1.3 that backports
> support for the AllowEncodedSlashes directive. It should behave
> identically to the way it works in 2.0. By default Apache will disallow
> any request that includes a %-encoded slash ('/') character (which
> is '%2F'), but by enabling this directive an administrator can override
> this prevention and allow %2Fs in request URLs. If this is an 
> acceptable
> backport, and I can get some +1s for it, I'll be happy to commit it and
> update the documentation (at least the English :).
>
> -aaron
>
> Index: src/include/httpd.h
> ===================================================================
> --- src/include/httpd.h	(revision 158971)
> +++ src/include/httpd.h	(working copy)
> @@ -976,6 +976,7 @@
>
>  API_EXPORT(int) ap_is_url(const char *u);
>  API_EXPORT(int) ap_unescape_url(char *url);
> +API_EXPORT(int) ap_unescape_url_keep2f(char *url);
>  API_EXPORT(void) ap_no2slash(char *name);
>  API_EXPORT(void) ap_getparents(char *name);
>  API_EXPORT(char *) ap_escape_path_segment(pool *p, const char *s);
> Index: src/include/http_core.h
> ===================================================================
> --- src/include/http_core.h	(revision 158971)
> +++ src/include/http_core.h	(working copy)
> @@ -318,6 +318,8 @@
>      /* Digest auth. */
>      char *ap_auth_nonce;
>
> +    unsigned int allow_encoded_slashes : 1; /* URLs may contain %2f 
> w/o being
> +					     * pitched indiscriminately */
>  } core_dir_config;
>
>  /* Per-server core configuration */
> Index: src/main/util.c
> ===================================================================
> --- src/main/util.c	(revision 158971)
> +++ src/main/util.c	(working copy)
> @@ -1635,6 +1635,53 @@
>  	return OK;
>  }
>
> +API_EXPORT(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 (!ap_isxdigit(*(y + 1)) || !ap_isxdigit(*(y + 2))) {
> +                badesc = 1;
> +                *x = '%';
> +            }
> +            else {
> +                char decoded;
> +                decoded = x2c(y + 1);
> +                if (decoded == '\0') {
> +                    badpath = 1;
> +                }
> +                else {
> +                    *x = decoded;
> +                    y += 2;
> +                }
> +            }
> +        }
> +    }
> +    *x = '\0';
> +    if (badesc) {
> +        return BAD_REQUEST;
> +    }
> +    else if (badpath) {
> +        return NOT_FOUND;
> +    }
> +    else {
> +        return OK;
> +    }
> +}
> +
>  API_EXPORT(char *) ap_construct_server(pool *p, const char *hostname,
>  				    unsigned port, const request_rec *r)
>  {
> Index: src/main/http_request.c
> ===================================================================
> --- src/main/http_request.c	(revision 158971)
> +++ src/main/http_request.c	(working copy)
> @@ -1175,8 +1175,21 @@
>
>      /* Ignore embedded %2F's in path for proxy requests */
>      if (r->proxyreq == NOT_PROXY && 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 (! d->allow_encoded_slashes) {
> +		ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r,
> +			      "found %%2f (encoded '/') in URI "
> +			      "(decoded='%s'), returning 404",
> +			      r->parsed_uri.path);
> +	    }
>  	    ap_die(access_status, r);
>  	    return;
>  	}
> Index: src/main/http_core.c
> ===================================================================
> --- src/main/http_core.c	(revision 158971)
> +++ src/main/http_core.c	(working copy)
> @@ -143,6 +143,9 @@
>      conf->etag_add = ETAG_UNSET;
>      conf->etag_remove = ETAG_UNSET;
>
> +    /* disallow %2f (encoded '/') by default */
> +    conf->allow_encoded_slashes = 0;
> +
>      return (void *)conf;
>  }
>
> @@ -319,6 +322,8 @@
>          conf->cgi_command_args = new->cgi_command_args;
>      }
>
> +    conf->allow_encoded_slashes = new->allow_encoded_slashes;
> +
>      return (void*)conf;
>  }
>
> @@ -2309,6 +2314,18 @@
>  }
>  #endif /* AP_ENABLE_EXCEPTION_HOOK */
>
> +static const char *set_allow2f(cmd_parms *cmd, core_dir_config *d, 
> int arg)
> +{
> +    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_pidfile(cmd_parms *cmd, void *dummy, char *arg)
>  {
>      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
> @@ -3551,6 +3568,8 @@
>  { "ErrorLog", set_server_string_slot,
>    (void *)XtOffsetOf (server_rec, error_fname), RSRC_CONF, TAKE1,
>    "The filename of the error log" },
> +{ "AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF, FLAG,
> +  "Allow URLs containing '/' encoded as '%2F'"},
>  { "PidFile", set_pidfile, NULL, RSRC_CONF, TAKE1,
>      "A file for logging the server process ID"},
>  { "ScoreBoardFile", set_scoreboard, NULL, RSRC_CONF, TAKE1,
>


Mime
View raw message