Reputation: 133
We just discovered in a reverse proxy setup that nginx is rewriting URL-encoded brackets as real brackets in proxy requests. For example, https://foo/a/b/test%20%5BTEST%5D.png gets rewritten to /a/b/test%20[TEST].png when it's proxied to the backend.
My config is very simple:
location /a/b/ {
proxy_pass http://localhost:8082/;
proxy_connect_timeout 15s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass_header Referer;
proxy_pass_header User-Agent;
add_header Strict-Transport-Security "max-age=31536000";
client_max_body_size 1024m;
}
The incoming request in access log is:
172.16.141.8 - - [13/May/2021:10:07:37 -0400] "GET /a/b/test%20%5BTEST%5D.png HTTP/1.1" 400 800 "https://[referrer]" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
Upstream log shows:
172.16.141.8 - - [13/May/2021:10:07:37 -0400] "GET /a/b/test%20%5BTEST%5D.png HTTP/1.1" 400 1386 127.0.0.1:8082
And the network trace of the request at port 8082 (the target of the proxy) is:
10:07:37.903863 IP 127.0.0.1.53518 > 127.0.0.1.8082: Flags [P.], seq 1:2308, ack 1, win 342, options [nop,nop,TS val 276559597 ecr 276559597], length 2307
E. 7.y@[email protected].,.....
.{...{..GET /a/b/test%20[TEST].png HTTP/1.0
X-Real-IP: 172.16.141.8
X-Forwarded-For: 172.16.141.8
X-Forwarded-Proto: https
Host: localhost:8082
Connection: close
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: https://[referrer]
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Why is nginx rewriting the encoded brackets as actual brackets? It's not touching the space in the URL, so it's definitely being selective as to what it rewrites for some reason. I'm running nginx version 1.16.1.
Thanks!
Upvotes: 2
Views: 428
Reputation: 1
The problem is that you specify an empty path in your proxy_pass directive. So writing
proxy_pass http://localhost:8082;
would prevent the rewriting/normalization behaviour. The subject is covered in detail here in the documentation of nginx https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
Upvotes: 0