How reliable is HTTP_HOST?
Asked Answered
O

5

9

I have written a PHP script that I would like to use on several domains on the same server (pointing to same script). I want to add functionality to the script so I can find out which domain the script is working with at any time. HTTP_HOST can be used to find the domain ,however, I have read that its not reliable especially with older browsers. My understanding is most Apache servers use virtual hosts which uses the same method anyway so if its not a problem with hosting providers it shouldn't be an issue with my code.

Can any one please verify this and clear the confusion ?

Orian answered 4/11, 2010 at 11:26 Comment(0)
P
10

HTTP_HOST is for the Host: header sent by HTTP 1.1 user-agents during the request. This is not used by HTTP 1.0 clients, so it won't appear then. However, nowadays, I don't think there are still many HTTP 1.0 clients.

Photodynamics answered 4/11, 2010 at 11:38 Comment(3)
And even most HTTP 1.0 clients have extended into using this field now - only the old, not-updated HTTP 1.0 don't supply it.Cloudy
@Pekka not a big deal. Such imaginary client won't get to the most of sites (named virtual host based ones), so, it's just impracticable.Snavely
@Col yeah, that was what I was wondering: How can such a client request a resource from a multi-vhost server at all? That must be really old. Anyway, it answers the questionSmudge
S
10

Edit: I stand corrected: The HOST header is not present in HTTP 1.0 requests. See @Bruno's answer. Leaving mine in place because of the security considerations

The only issues with HTTP_HOST that I'm aware of are security issues, not compatibility ones.

The security issues stem from the fact that HTTP_HOST is sent by the user. If the web server is incorrectly set up and/or buggy, arbitrary HTTP_HOST values could make it to your site/script (see e.g. here for detailed discussion). Your application needs to be prepared for that.

It's good never to trust HTTP_HOST (e.g. it can be a good idea to set up an array of allowed values for it before processing it in your PHP script):

<?php
  $allowed_hosts = array("domain1.com", "domain2.com", "domain3.com");

  if (!in_array(strtolower($_SERVER["HTTP_HOST"]), $allowed_hosts))
   die ("Unknown host name ". $_SERVER["HTTP_HOST"]);
Smudge answered 4/11, 2010 at 11:31 Comment(6)
+1 for your answer too, although it's not about older browser compatibility, it's definitely on topic for "How reliable is HTTP_HOST?"Photodynamics
@Smudge Thats what i intend to do. This also brings in another question thats on my mind would it be better to allow Apache to resolve this and use HTTP_SERVER the server alias instead. The only issue I have with this is making the host.conf dynamic.Orian
@andicrook that would work, but you'd have to set up a vhost for every conceivable domain name. But seeing as you'll need to introduce all domain names into httpd.conf anyway....Smudge
I should be able to set virtual hosting to be dynamic or use CNAMESOrian
@andi I must correct myself, I'm pretty sure that is possible using wildcards. Serverfault.com may have better answers on that specific issueSmudge
@Smudge yes, you can use them with ServerAliasOrian
P
10

HTTP_HOST is for the Host: header sent by HTTP 1.1 user-agents during the request. This is not used by HTTP 1.0 clients, so it won't appear then. However, nowadays, I don't think there are still many HTTP 1.0 clients.

Photodynamics answered 4/11, 2010 at 11:38 Comment(3)
And even most HTTP 1.0 clients have extended into using this field now - only the old, not-updated HTTP 1.0 don't supply it.Cloudy
@Pekka not a big deal. Such imaginary client won't get to the most of sites (named virtual host based ones), so, it's just impracticable.Snavely
@Col yeah, that was what I was wondering: How can such a client request a resource from a multi-vhost server at all? That must be really old. Anyway, it answers the questionSmudge
S
1

Pekka's answer seems more interesting, but it seems that you want to know which browsers support http 1.1 and which dont. Found this on google: http://www.1-script.com/forums/Browser-Support-for-HTTP-1-1-article34982--8.htm

A note, from that thread: "a HTTP 1.0 browser cannot get to the non-default virtual host." That means that a browser that dont support http 1.1 cannot reach any website on a shared server as far as i know. Thare are LOTS of websites on shared hosts. Also subdomains might(no sure though) be "detected' in the same way, by using the HTTP_HOST var.

After reading these, i dont really think anyone uses a browser that old nowdays, it would be impossible for them to actually navigate the web:)

Sporty answered 4/11, 2010 at 12:13 Comment(3)
mind you, there are still a lot of mobile phones out there that use HTTP/1.0Tonitonia
do you have one? I'm curios if they cannot actually access subdomains.Sporty
Yes Apache uses HTTP_HOST for most virtual hosts, if its IP based hosting then it can use DNS reverse lookup which would create overhead anywayOrian
B
0

This is what I answered in a similar question :


Looking into this myself for other purposes:

"HTTP/1.0 is in use by proxies, some mobile clients, and IE when configured to use a proxy. So 1.0 appears to still account for a non- trivial % of traffic on the web overall. ... Yes, there are many 1.0 clients still out there."

Source (July 2009): http://groups.google.com/group/erlang-programming/msg/08f6b72d5156ef74

:-(


I am personally getting quite a few HTTP/1.0 requests on my sites with a missing HTTP_HOST :-(

Brasilein answered 12/11, 2010 at 18:30 Comment(0)
N
0

This is an old post I stumble onto and the solution I gave is this:

I created a JSON file (my code makes extensive use of these which I call tokens) to become the single source of truth and to be open at the same time for modifications from who knows what new things will emerge in a application/framework:

// accounttoken.json
{
    "site": {
        "email": "[email protected]",
        "password": "Bty1!",
        "firstname": "John",
        "secondname": "Doe",
        "country": "USA",
        "username": "Admin",
        "role": "admin",
        "protocol": "http://",
        "domain": "a9623c7ca853.eu.ngrok.io",
        "site_key": "fgRt4%$x!0($DqJi",
        "language": "en"
    },
    "google": {
        "client_id": "51965.apps.googleusercontent.com",
        "client_secret": "8Kz"
    },
    "db_mysql": {
        "db_port": 3306,
        "db_user": "<user>"
    },
// more entries here...
}

Now, all you have to do is to consult your entries in one file:

// find php executable
cent$ whereis php
php: /usr/bin/php7.0 /usr/bin/php /usr/lib/php /etc/php /usr/include/php ...

// start interactive shell
cent$ /usr/bin/php7.0 -a

php > $json = file_get_contents('accounttoken.json');
php > $json = json_decode($json, true);
php > echo('Your domain is: ' . $json['site']['domain']);
php > echo('The site url is: ' . $json['site']['protocol'] . $json['site']['domain']);
php > quit
Nervous answered 30/6, 2020 at 8:5 Comment(1)
already proved correct: cookie.domain in another json file should be set to localhost while site.domain at this file should be set like in my example when redirecting localhost to ngrok server and test authentication!Nervous

© 2022 - 2024 — McMap. All rights reserved.