SERVER_NAME:

  • The name of the server host under which the current script is executing.
  • If the script is running on a virtual host, this will be the value defined for that virtual host.
  • SERVER_NAME comes from the server’s VirtualHost definition and is therefore considered more reliable.
  • It can, however, also be manipulated from outside under certain conditions related to how your web server is set up.

HTTP_HOST:

  • Contents of the Host: header from the current request, if there is one.
  • HTTP_HOST is the target host sent by the client. It can be manipulated freely by the user.
  • It’s no problem to send a request to your site asking for a HTTP_HOST
  • HTTP_HOST vs SERVER_NAME:
  • Imagine your web server has a default host set up as follows:
  • UseCanonicalName Off
    ServerName example.org
  • The ServerName directive might seem like the only thing that affects $_SERVER[‘SERVER_NAME’], but is this a safe assumption?
  • To determine what affect the Host header has, if any, create an index.php in the document root of the default host with the following code
[pastacode lang=”php” manual=”%3C%3Fphp%20%20%0Aecho%20%22HTTP_HOST%20%5B%7B%24_SERVER%5B’HTTP_HOST’%5D%7D%5D%5Cn%22%3B%20%0Aecho%20%22SERVER_NAME%20%5B%7B%24_SERVER%5B’SERVER_NAME’%5D%7D%5D%22%3B%20%0A%20%3F%3E%0A” message=”Php Code” highlight=”” provider=”manual”/]

You can test several different values for Host easily enough with telnet:

[pastacode lang=”php” manual=”telnet%20example.org%2080%0A” message=”Php Code” highlight=”” provider=”manual”/] [ad type=”banner”]

Here are a few tests and corresponding results. For each test, we show the exact request and the content of the response.

1. No Host, HTTP/1.0

Request:

[pastacode lang=”php” manual=”GET%20%2F%20HTTP%2F1.0%0A” message=”Php Code” highlight=”” provider=”manual”/]

Result:

[pastacode lang=”php” manual=”HTTP_HOST%20%5B%5D%0ASERVER_NAME%20%5Bexample.org%5D” message=”Php Code” highlight=”” provider=”manual”/]

Empty Host, HTTP/1.0

Request:

[pastacode lang=”php” manual=”GET%20%2F%20HTTP%2F1.0%0AHost%3A%0A” message=”Php Code” highlight=”” provider=”manual”/]

Result:

[pastacode lang=”php” manual=”HTTP_HOST%20%5B%5D%0ASERVER_NAME%20%5B%5D%0A” message=”Php Code” highlight=”” provider=”manual”/]

With an empty Host, SERVER_NAME is empty.

Empty Host, HTTP/1.1

Request:

[pastacode lang=”php” manual=”%20GET%20%2F%20HTTP%2F1.1%0A%20Host%3A%0A” message=”Php Code” highlight=”” provider=”manual”/]

Result:

[pastacode lang=”php” manual=”HTTP_HOST%20%5B%5D%0ASERVER_NAME%20%5B%5D%0A” message=”Php Code” highlight=”” provider=”manual”/]

Request:

[pastacode lang=”php” manual=”GET%20%2F%20HTTP%2F1.1%0AHost%3A%20%3Cscript%3Ealert(‘XSS’)%3C%2Fscript%3E%0A” message=”Php code” highlight=”” provider=”manual”/]

Result:

[pastacode lang=”php” manual=”HTTP_HOST%20%5B%3Cscript%3Ealert(‘XSS’)%3C%2Fscript%3E%5D%0ASERVER_NAME%20%5B%26lt%3Bscript%26gt%3Balert(‘XSS’)%26lt%3B%2Fscript%26gt%3B%5D%0A” message=”Php Code” highlight=”” provider=”manual”/] [ad type=”banner”]

With a non-empty Host, SERVER_NAME is the HTML-escaped host value.

SQL Injection Host, HTTP/1.1

Request:

[pastacode lang=”php” manual=”GET%20%2F%20HTTP%2F1.1%0AHost%3A%20chris’%20–%0A” message=”Php Code” highlight=”” provider=”manual”/]

Result:

[pastacode lang=”php” manual=”HTTP_HOST%20%5Bchris’%20–%5D%20%0ASERVER_NAME%20%5Bchris’%20–%5D” message=”Php Code” highlight=”” provider=”manual”/]
  • As you can see by the results Under certain circumstances, the Host header can affect $_SERVER[‘SERVER_NAME’].
  • The ServerName directive is used when the Host header is absent, and apparently $_SERVER[‘SERVER_NAME’] is escaped with something like htmlentities().
  • Sometimes, it’s hard to tell whether a particular element in $_SERVER can be affected by the HTTP request (ask Sean about PHP_SELF)
  • so I find it easier to treat everything from $_SERVER just as if it were something like $_GET or $_POST.
  • SERVER_NAME instead of HTTP_HOST
  • We found a problem with our configuration (nginx and php-fpm).
  • When you define domain in your plugin you are using SERVER_NAME as its value.
  • SERVER_NAME with this configuration is not the same as HTTP_HOST, so the plugin is not working.
  • We have changed it to get the SERVER_NAME from HTTP_HOST that it’s what the user is really loading in its browser.
  • With this line in wp-config.php it’s working well
[pastacode lang=”php” manual=”%24_SERVER%5B’SERVER_NAME’%5D%20%3D%20%24_SERVER%5B’HTTP_HOST’%5D%3B%0A” message=”Php Code” highlight=”” provider=”manual”/]

Get host name or server name in PHP:

  • $_SERVER[‘HTTP_HOST’] give you host infomration obtained from the HTTP request header and this is what the client actually used as “target host” of the request.
  • $_SERVER[‘SERVER_NAME’] normally returns the same result as $_SERVER[‘HTTP_HOST’], but is defined in server config.
  • However, if you server is running behind the proxy, then should use $_SERVER[‘HTTP_X_FORWARDED_HOST’] and
[pastacode lang=”php” manual=”%24_SERVER%5B’HTTP_X_FORWARDED_SERVER’%5D%C2%A0in%20place%20of%C2%A0%24_SERVER%5B’HTTP_HOST’%5D%C2%A0and%C2%A0%24_SERVER%5B’SERVER_NAME’%5D.%20%0A” message=”Php Code” highlight=”” provider=”manual”/] [pastacode lang=”php” manual=”%24host_name%20%3D%20isset(%24_SERVER%5B’HTTP_X_FORWARDED_HOST’%5D)%20%3F%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24_SERVER%5B’HTTP_X_FORWARDED_HOST’%5D%20%3A%20%24_SERVER(%22HTTP_HOST%22)%3B%20%20%0A%24server_name%20%3D%20isset(%24_SERVER%5B’HTTP_X_FORWARDED_SERVER’%5D)%20%3F%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24_SERVER%5B’HTTP_X_FORWARDED_SERVER’%5D%20%3A%20%24_SERVER(%22SERVER_NAME%22)%3B%20%0A” message=”Php Code” highlight=”” provider=”manual”/] [ad type=”banner”]

Categorized in: