summaryrefslogtreecommitdiffstats
path: root/server/request.c
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2020-06-22 12:36:55 +0200
committerYann Ylavic <ylavic@apache.org>2020-06-22 12:36:55 +0200
commit6b3b91a616b4848ee134ef902c785a7b2c0dd453 (patch)
tree25dfa0408c8cf68f8fcb8dc6467a28a406e53b32 /server/request.c
parentValidate request-target per RFC 7230 section 5.3. (diff)
downloadapache2-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.c56
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,