tags:

views:

356

answers:

6
+5  A: 

If you want a server name that can't be set by the client, use $_SERVER['SERVER_NAME']. It is set by the server itself but can also be forged under certain circumstances using a bug, as Gumbo points out and links to in the comments.

Pekka
In fact it can be manipulated by the client (see http://shiflett.org/blog/2006/mar/server-name-versus-http-host).
Gumbo
@Gumbo: That was a bug. Whether it's still present or not, I don't know (that blog entry is nearly 4 years old)
R. Bemrose
@R. Bemrose: It *is* still present (PHP 5.3.0).
Gumbo
@Gumbo: Good to know! I'll add it to my answer.
Pekka
Some things will never change … ;-) But I don’t know if it’s really a bug. Maybe that behavior is on purpose.
Gumbo
I think this is a flaw in apache's vhost design and how "UseCanonicalName off" works - which shouldn't be used anyway except your REALLY know the consequences (eg SERVER_NAME being set by Http-Request-Host instead of from the vhost config, which actually can be set to any string as it is client-provided). Apparently it is a (dangerous) default setting in many of the managed deployments out there.
hurikhan77
+3  A: 

I think the one you are referring to is

$_SERVER['HTTP_HOST'];

which, given the HTTP prefix means it comes from the HTTP Headers.

You might want to use:

$_SERVER['SERVER_NAME']

which is defined by the server and can't be changed via a request?

Chacha102
+3  A: 

this will get the hostname server-side, but if you're running on a commercial host (not hosting yourself), I don't imagine this will be all that useful.

$host = php_uname( 'n' );

If you're using Apache, what you should do is make your server / site only answer to certain names (else there should be a default that doesn't do much). You can do with with the ServerName and ServerAlias directives.

Dan Beam
if you only ever use a whitelist of hostnames, you'll never get injected
Dan Beam
+1  A: 

You don't. That's the purpose of the $_SERVER variables. If you want to get the HOST_NAME from the path, you must first get the PATH from $_SERVER['HTTP_HOST']

Joel Etherton
Thanks, everyone. That's all what i wanted to know.
minnur
+1  A: 

Of course $_SERVER['HTTP_HOST'] can be modified by the client - because in fact IT IS sent by the client. This is part of the http protocol. If you want to get the primary server name defined in the vhost configuration of apache or whatever you can access $_SERVER['SERVER_NAME'] as proposed by the others.

I suggest it is not wise to extract the domain name from the file path of the server (which is stored in __FILE__) as it may render your application non-relocatable (it will no longer be storage location agnostic).

You may see the contents of the array by dumping it within the script using var_dump($_SERVER) but keep in mind the not all web servers and all web server settings expose the same environment. This is documented in the web server documentation and I think it is partly documented in the php online docs.

Update / Important notice: As others pointed out, the content of $_SERVER['SERVER_NAME'] could be spoofed if apache is configured for UseCanonicalName off (which may be a default setting if you are using eg Plesk-based hosting). So actually going with the __FILE__ can solve this (if your doc root contains the host name). The bigger problem of the first approach is that it can be used to inject any sort of stuff into your application (SQL, JavaScript) because php programmers usually take it granted that SERVER_NAME is no user input and thus apply no sanitizing to it.

hurikhan77
Thanks for the answer! I will use $path = realpath(__FILE__);
minnur
+1  A: 

*Edit: as pointed by Gumbo, the original poster probably means HTTP_HOST rather than HOST_NAME. Otherwise, my answer is plain wrong.*

The HTTP_HOST variable reflects the domain name that the visitor used to access the site. If doesn't have anything to do with file paths! Its value is conveniently stored in $_SERVER['HTTP_HOST']. Is there any other way to get it? Of course, there're normally several ways to do things. For instance, this works when PHP runs as Apache module.

<?php

$request_headers = apache_request_headers();
echo $request_headers['Host'];

?>

The question is: why would anyone want to do such a thing? Why replace a reliable standard method with a quirky workaround that eventually fetches the same piece of data from the same place?

You have the concern that $_SERVER['HTTP_HOST'] is altered by the HTTP request. Of course it is: that's where it comes from. The browser has to specify what site it wants to visit (that's the base of name based virtual hosts) and if it sends a rogue value, well, it just won't reach the site.

Álvaro G. Vicario
There is no `$_SERVER['HOST_NAME']`; it’s `$_SERVER['HTTP_HOST']`.
Gumbo
Certainly. I'm fixing the typo right now.
Álvaro G. Vicario
The main problem the OP probably had with his hosting is that it's a managed standard apache/plesk/whatever installation which always responds with the first vhost no matter which host name is sent if that doesn't match any of the vhosts. Proper way to fix that would be to return 404 if the http host from the request headers doesn't match what is expected. Otherwise you won't make anything better (in the sense what you are trying to fix/prevent).
hurikhan77