Opened 5 years ago
Closed 5 years ago
#1930 closed defect (invalid)
Space in URL %20 is decoded space causing an invalid URL
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | documentation | Version: | 1.17.x |
Keywords: | Cc: | ||
uname -a: | Windows 10 64-bit | ||
nginx -V: |
nginx version: nginx/1.17.8
built by cl 16.00.40219.01 for 80x86 built with OpenSSL 1.1.1d 10 Sep 2019 TLS SNI support enabled configure arguments: --with-cc=cl --builddir=objs.msvc8 --with-debug --prefix= --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/fastcgi_temp --http-scgi-temp-path=temp/scgi_temp --http-uwsgi-temp-path=temp/uwsgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs.msvc8/lib/pcre-8.43 --with-zlib=objs.msvc8/lib/zlib-1.2.11 --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_stub_status_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_slice_module --with-mail --with-stream --with-openssl=objs.msvc8/lib/openssl-1.1.1d --with-openssl-opt='no-asm no-tests -D_WIN32_WINNT=0x0501' --with-http_ssl_module --with-mail_ssl_module --with-stream_ssl_module |
Description
We are seeing nginx 1.15 and the latest 1.17.8 wrongly decoding %20 to " " (space) in URLs before forwarding them upstream. Some upstreams do not accept this and cause a 400. Nginx should not IMHO be unencoding URLs!
Consider the following Nginx running on 8080 with fiddler running as the upstream server on port 8888 to view traffic:
location ~ "^/yo/(.*)" { proxy_pass http://127.0.0.1:8888/$1$is_args$args; }
Next we hit NginX with:
GET http://localhost:8080/yo/foo%20bar
Fiddler (upstream) shows the incoming request as:
GET /foo bar
Correct would be
GET /foo%20bar
The following workaround is available:
location ~ "^/yo/(.*)" { set $allowspace1 $1; proxy_pass http://127.0.0.1:8888/$allowspace1$is_args$args;
Note:
See TracTickets
for help on using tickets.
In your configuration snippet:
you are using
$1$is_args$args
, where$1
comes from unescaped URI as matched by the location. Given thatproxy_pass
expects properly escaped URI and uses it as is, this results in arbitrary invalid requests being generated.If you are not prepared to deal with it and do not want to correctly escape all the variables used, consider using
proxy_pass
without variables instead. The same configuration can be correctly rewritten as:Note the trailing
/
inproxy_pass
. Alternatively, you can useproxy_pass
without a URI andrewrite
, though in this particular case usingproxy_pass
with a URI is much cleaner solution. See proxy_pass docs for additional examples.(Note well that the "workaround" you've mentioned is rather a bug, see #348.)