I have a nginx.conf as follows:
server {
listen 443 ssl;
# some other ssl config
server_name home.aaa.com;
# some access_log and error_log config
location /actuator/ {
allow 10.1.1.0/24;
deny all;
proxy_pass http://10.1.1.1:8989;
}
location / {
proxy_pass http://10.1.1.1:8989;
}
}
When I access https://home.aaa.com/actuator/prometheus, nginx deny this request and return 403, this is what I expect.
When I access https://home.aaa.com/actuator/prometheus;%2f..%2f..//, nginx output a new line in access.log:
1.203.146.132 - - [15/Jan/2024:11:00:55 +0800] "GET /actuator/prometheus;%2f..%2f..// HTTP/1.1" 200 7889841 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0" "-" https "home.aaa.com" "1.025" "0.270" "10.1.1.1:8989"
and there is not a log in nginx error_log. But I expect nginx deny this request too.
I do not know why the second request was proxied to the backend server, and how can I debug this issue?
Thanks!
The url https://home.aaa.com/actuator/prometheus;%2f..%2f..//
after url decode is https://home.aaa.com/actuator/prometheus;/../..//
. Which will in the nginx $uri
valable will be /
. Then it not match the location /actuator/
.
Here is the illustration,
#nginx config
location /actuator/ {
return 403 $uri;
}
location / {
return 200 $uri;
}
And the curl result
$ curl -sS 'xxxx/actuator/prometheus;%2f..%2f..//'
/
$ curl -sS 'xxxx/actuator/prometheus'
/actuator/prometheus