Opened 21 months ago
Closed 21 months ago
#2472 closed defect (invalid)
Invalid request caused by '.' in the first URI component
Reported by: | Weitian LI | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-core | Version: | 1.22.x |
Keywords: | Cc: | Weitian LI | |
uname -a: | Linux xxx 6.1.6-arch1-3 #1 SMP PREEMPT_DYNAMIC Mon, 16 Jan 2023 12:51:23 +0000 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.22.1
built with OpenSSL 3.0.7 1 Nov 2022 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/bin/nginx --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --user=http --group=http --http-log-path=/var/log/nginx/access.log --error-log-path=stderr --http-client-body-temp-path=/var/lib/nginx/client-body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-cc-opt='-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -flto=auto' --with-ld-opt='-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -flto=auto' --with-compat --with-debug --with-file-aio --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-pcre-jit --with-stream --with-stream_geoip_module --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads |
Description (last modified by )
Hi,
I found a request to /% 2e% 2e/x
caused Nginx to response 400 with error:
2023/03/21 17:06:55 [info] 1552400#1552400: *6 client sent invalid request while reading client request line, client: 127.0.0.1, server: _, request: "GET /% 2e% 2e/x HTTP/1.1"
Similarly, requests of /% 2e% 2e
, /.% 2e
, and /% 2e.
all give the same 400 result.
However, requests of /x/% 2e% 2e
, /x/.% 2e
, and /x/% 2e.
all work as expected. Meanwhile, request of /..
is also OK (so ..
and % 2e% 2e
behave differently).
I traced the issue and found it was raised by https://github.com/nginx/nginx/blame/master/src/http/ngx_http_parse.c#L1466, but I couldn't yet find the root cause.
N.B. please ignore the space between %
and 2e
; otherwise, trac auto replace it with .
.
Thank you.
Change History (5)
comment:1 by , 21 months ago
Description: | modified (diff) |
---|
follow-up: 3 comment:2 by , 21 months ago
comment:3 by , 21 months ago
Replying to Maxim Dounin:
Could you please clarify how do you test so you see different handling for
/..
?
I was testing with curl, but failed to notice curl auto normalized the /..
part. So I was actually requesting /
instead of /..
. So %2e%2e
and ..
are essentially the same. My bad. Sorry.
Just in case it's not clear, all these are rejected since these are different forms to escape from root. In particular, RFC 2396 used to consider such references to be in error:
g) If the resulting buffer string still begins with one or more complete path segments of "..", then the reference is considered to be in error. Implementations may handle this error by retaining these components in the resolved path (i.e., treating them as part of the final URI), by removing them from the resolved path (i.e., discarding relative levels above the root), or by avoiding traversal of the reference.While the the suggested pseudocode in RFC 3986 replaces such invalid dot segments with just
/
(that is, discards relative levels above the root), nginx prefers conservative approach here, and rejects such URIs.
Note well that URIs in HTTP requests are not expected to be relative, and therefore should not contain any dot segments. Such URIs used to work though, and therefore nginx tries to normalize them unless there are obvious errors.
This makes it crystal clear. Thank you for the prompt and detailed response.
I'm sorry for the noise.
comment:5 by , 21 months ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Thanks for the details, closing this.
Requests to
/..
are also rejected by nginx:With the corresponding log message:
This matches handling of various escaped variants, including
/%2e%2e
,/.%2e
, and/%2e.
, as well as/../x
and/%2e%2e/x
.Could you please clarify how do you test so you see different handling for
/..
?Just in case it's not clear, all these are rejected since these are different forms to escape from root. In particular, RFC 2396 used to consider such references to be in error:
While the the suggested pseudocode in RFC 3986 replaces such invalid dot segments with just
/
(that is, discards relative levels above the root), nginx prefers conservative approach here, and rejects such URIs.Note well that URIs in HTTP requests are not expected to be relative, and therefore should not contain any dot segments. Such URIs used to work though, and therefore nginx tries to normalize them unless there are obvious errors.