diff options
author | Yann Ylavic <ylavic@apache.org> | 2020-06-22 12:36:55 +0200 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2020-06-22 12:36:55 +0200 |
commit | 6b3b91a616b4848ee134ef902c785a7b2c0dd453 (patch) | |
tree | 25dfa0408c8cf68f8fcb8dc6467a28a406e53b32 /server/request.c | |
parent | Validate request-target per RFC 7230 section 5.3. (diff) | |
download | apache2-6b3b91a616b4848ee134ef902c785a7b2c0dd453.tar.xz apache2-6b3b91a616b4848ee134ef902c785a7b2c0dd453.zip |
Allow for URI-path pre_translate_name before (and/or instead of) decoding.
Apply minimal normalization (AP_NORMALIZE_DECODE_UNRESERVED) first in
ap_process_request_internal() before running pre_translate_name hooks,
such that the hooks can work with undecoded r->uri.
Only if no hook takes "ownership" of the URI (returning OK), apply
percent decoding for the rest of request handling. Otherwise r->uri remains
encoded meaning that further location/directory/file/if/.. sections (walks)
should that into account.
Since normalization now happens before decoding, we might have to
re-normalize after decoding if "AllowEncodedSlahes on" transformed any
"%2F" sequence to "/", potentially creating new "/./" or "/../" sequences.
Note that for (lookup) subrequests, the path may be relative so we have
to allow for that.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879079 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | server/request.c | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/server/request.c b/server/request.c index e00ed69d3e..aa05d524e0 100644 --- a/server/request.c +++ b/server/request.c @@ -172,12 +172,41 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) core_dir_config *d; core_server_config *sconf = ap_get_core_module_config(r->server->module_config); + unsigned int normalize_flags = 0; - /* Ignore embedded %2F's in path for proxy requests */ - if (!r->proxyreq && r->parsed_uri.path) { + if (r->main) { + /* Lookup subrequests can have a relative path. */ + normalize_flags = AP_NORMALIZE_ALLOW_RELATIVE; + } + + if (r->parsed_uri.path) { + /* Normalize: remove /./ and shrink /../ segments, plus + * decode unreserved chars (first time only to avoid + * double decoding after ap_unescape_url() below). + */ + if (!ap_normalize_path(r->parsed_uri.path, + normalize_flags | + AP_NORMALIZE_DECODE_UNRESERVED)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() + "invalid URI path (%s)", r->uri); + return HTTP_BAD_REQUEST; + } + } + + /* Let pre_translate_name hooks work with non-decoded URIs, + * and eventually apply their own transformations (return OK). + */ + access_status = ap_run_pre_translate_name(r); + if (access_status != OK && access_status != DECLINED) { + return access_status; + } + + /* Ignore URL unescaping for translated URIs already */ + if (access_status == DECLINED && r->parsed_uri.path) { d = ap_get_core_module_config(r->per_dir_config); if (d->allow_encoded_slashes) { - access_status = ap_unescape_url_keep2f(r->parsed_uri.path, d->decode_encoded_slashes); + access_status = ap_unescape_url_keep2f(r->parsed_uri.path, + d->decode_encoded_slashes); } else { access_status = ap_unescape_url(r->parsed_uri.path); @@ -188,20 +217,27 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00026) "found %%2f (encoded '/') in URI " "(decoded='%s'), returning 404", - r->parsed_uri.path); + r->uri); } } return access_status; } - } - ap_getparents(r->uri); /* OK --- shrinking transformations... */ - if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { - ap_no2slash(r->uri); - if (r->parsed_uri.path) { + if (d->allow_encoded_slashes && d->decode_encoded_slashes) { + /* Decoding slashes might have created new /./ and /../ + * segments (e.g. "/.%2F/"), so re-normalize. If asked to, + * merge slashes while at it. + */ + if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { + normalize_flags |= AP_NORMALIZE_MERGE_SLASHES; + } + ap_normalize_path(r->parsed_uri.path, normalize_flags); + } + else if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { + /* We still didn't merged slashes yet, do it now. */ ap_no2slash(r->parsed_uri.path); } - } + } /* All file subrequests are a huge pain... they cannot bubble through the * next several steps. Only file subrequests are allowed an empty uri, |