nginx "server" directive with multiple "server_name" entries: always first one is passed to PHP's $_SERVER['SERVER_NAME']

32,802

Solution 1

Set SERVER_NAME to use $host in your fastcgi_params configuration.

fastcgi_param   SERVER_NAME         $host;

Source: http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param

Solution 2

This is intended and the proper solution is to use $_SERVER['HTTP_HOST'] in your code instead.

You should interpret SERVER_NAME as a verified server-name, and HTTP_HOST as user-input which can be modified quite easily, and thus shouldn't be trusted.

Share:
32,802
Paolo
Author by

Paolo

Updated on March 23, 2020

Comments

  • Paolo
    Paolo about 4 years

    My configuration file has a server directive block that begins with...

    server {
        server_name www.example1.com www.example2.com www.example3.com;
    

    ...in order to allow the site to be accessed with different domain names.

    However PHP's $_SERVER['SERVER_NAME'] always returns the first entry of server_name, in this case http://www.example1.com

    So I have no way from the PHP code to know which domain the user used to access the site.

    Is there any way to tell nginx/fastcgi to pass the real domain name used to access the site?


    The only solution I've found so far is to repeat the entire server block for each domain with a distinct server_name entry but obviously I'm looking for a better one.

  • Paolo
    Paolo almost 9 years
    thank you. This is the simplest solution and I'm probably will go with it. However I would have preferred to find a way to use 'SERVER_NAME' since it is the name of the virtual host as it's get defined as nginx handle the request applying the configuration directives. 'HTTP_HOST' comes straight from the request header (if the client sent it). Of course a properly configured nginx would reject requests with bad http host headers making 'HTTP_HOST' reliable...
  • Sjon
    Sjon almost 9 years
    I understand you're attempting some sort of partial validation in your nginx config; but like you mentioned, a properly configured nginx will only allow valid HTTP_HOST entries. Treating HTTP_* as untrusted like other user-input is still a good idea. The distinction between SERVER_NAME and HTTP_HOST is pretty useful if you understand the difference
  • David
    David about 8 years
    Up voted you, but why isn't this default behavior, seems logical to me. Why does it use the first item in the server_name block instead.
  • K M
    K M over 3 years
    Always declare fastcgi_param statements after the include fastcgi_params; statement to avoid any ambiguity in your configuration files.