Home > Blockchain >  Nginx returns 404 When I use valid_referers
Nginx returns 404 When I use valid_referers

Time:05-11

This is my environment:

  • Rails
  • Axios
  • Next.js
  • AWS EC2
  • Nginx
  • Vercel

I have two domains in production environment.
One is let's say fuga.com which is made with rails and containing some front pages.

Another one is hoge.com which is made with next.js.

hoge.com usually fetch data from fuga.com using http request.
But if I access to let's say fuga.com/users_data using browser I would see all users data.
Because api is global?
Anyway It's really bad in terms of security.

So I came up with blocking all domains aside from hoge.com. I configured in nginx:

server {
    listen 80;
    server_name fuga.com hoge.com;
    root /var/www/xxx/current/public;

    location / {
        proxy_pass http://xxx;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }
    # ↓here↓
    location /admin {
      valid_referers none blocked server_names hoge\.com;
      if ($invalid_referer) { return 403; }
    }

}

I want to block all domains /admin/~ aside from hoge.com.
So I used valid_referers none blocked.
From my search, it's white list which can only access.

But I got this parameter from access log in nginx:

172.31.xx.xxx - - [10/May/2022:13:31:58  0000] "POST /admin/auth/sign_in/ HTTP/1.1" 404 188 "https://hoge.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xxx.0.xxxx.54 Safari/xxx.36" "106.xx.xx.xxx" "-"

status code is 404.

So I tried allow instead of valid_referers like:

...
    location /admin {
      allow 172.xx.xx.xxx;
      deny all;
    }

But nginx returns:

172.xx.x.xxx - - [10/May/2022:13:34:12  0000] "POST /admin/auth/sign_in/ HTTP/1.1" 403 187 "https://hoge.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xxx.x.xxxx.54 Safari/xxx.xx" "xxx.xx.xx.xxx" "-"

I can't understand what's going on...
I'm sure It's completely problem of nginx setting.
Because if I remove allow and valid_referers it would work fine.

How can I fix the problem..?

CodePudding user response:

Every request ends up in a particular location and uses that location content handler. You can't do something like

location / {
    ... some settings ruleset
}
location /admin {
    ... additional settings ruleset
}

and expect that /admin/... request would use a combined settings ruleset. Your first locations uses an http_proxy_module content handler declared with the proxy_pass directive (other content handlers directive examples are fastcgi_pass, uwsgi_pass, etc.). Since there is no any content handler declared in your second location, nginx will use a local content handler for the requests handled with that location (in other words, will try to serve a request with some local file), and since such a local file does not exists, gives you an HTTP 404 Not Found response. You can either duplicate your main location content with your second location (not the best way) or use some other solution like map block:

map $uri $deny {
    ~^/admin  $invalid_referer;
    # default value will be an empty string, so we can omit "default '';" here
}
server {
    ...
    location / {
        if ($deny) { return 403; }
        ... rest of the configuration
    }
}
  • Related