564 votes

HTTP_HOST vs. SERVER_NAME

Quand envisageriez-vous d'utiliser l'un plutôt que l'autre et pourquoi ?

15 votes

"J'opte normalement pour HTTP_HOST, afin que l'utilisateur reste sur le nom d'hôte exact sur lequel il a commencé. Par exemple, si j'ai le même site sur un domaine .com et .org, je ne veux pas envoyer quelqu'un de .org à .com, surtout s'il a des jetons de connexion sur .org qu'il perdrait s'il était envoyé sur l'autre domaine." - Ce point, ainsi que d'autres points intéressants, sont tirés de stackoverflow.com/questions/1459739/

6 votes

@Yarin, N'oubliez pas de vérifier sur une liste blanche les résultats de HTTP_HOST . Sinon, un attaquant peut mettre en tout dans l'interface HTTP Host: et faire en sorte que le serveur l'accepte.

7 votes

Débutants : Cette question fait référence aux valeurs généralement obtenues par $_SERVER['HTTP_HOST'] o $_SERVER['SERVER_NAME']

807voto

BalusC Points 498232

Le site HTTP_HOST est obtenu à partir de la En-tête de requête HTTP et c'est ce que le client a effectivement utilisé comme "hôte cible" de la demande. Le site SERVER_NAME est défini dans la configuration du serveur. Le choix de l'une ou l'autre dépend de ce dont vous avez besoin. Vous devriez maintenant réaliser que l'une est une valeur contrôlée par le client qui peut donc ne pas être fiable pour une utilisation dans la logique métier et que l'autre est une valeur contrôlée par le serveur qui est plus fiable. Vous devez cependant vous assurer que le serveur web en question possède le code de sécurité SERVER_NAME correctement configuré. Prenons l'exemple d'Apache HTTPD, dont voici un extrait sa documentation :

Si aucun nom de serveur n'est spécifié, le serveur tente de déduire le nom d'hôte en effectuant une recherche inverse sur l'adresse IP. Si aucun port n'est spécifié dans le ServerName, le serveur utilise le port de la requête entrante. Pour une fiabilité et une prévisibilité optimales, vous devez spécifier un nom d'hôte et un port explicites à l'aide de la directive ServerName.

Mise à jour : après avoir vérifié la réponse de Pekka à votre question qui contient un lien vers La réponse de Bobince que PHP retournerait toujours HTTP_HOST de la valeur de SERVER_NAME J'ai fait sauter la poussière de mon environnement XAMPP actuel sur Windows XP (Apache HTTPD 2.2.1 avec PHP 5.2.8), je l'ai démarré, j'ai créé une page PHP qui imprime les deux valeurs, j'ai créé une application de test Java en utilisant la fonction URLConnection pour modifier le Host L'en-tête et les tests m'ont appris que c'est effectivement (incorrectement) le cas.

Après avoir d'abord soupçonné PHP et creusé dans quelques Rapports de bogue PHP concernant le sujet, j'ai appris que la racine du problème se trouve dans le serveur web utilisé, qu'il renvoyait incorrectement HTTP Host l'en-tête lorsque SERVER_NAME a été demandé. Alors j'ai creusé dans Rapports de bogues sur Apache HTTPD en utilisant différents mots-clés sur le sujet, mais je n'arrive pas à en trouver une.

Ne sommes-nous pas censés remplir un rapport de bogue pour HTTPD à ce sujet ? Il semble que personne ne l'ait fait auparavant, bien que cela ait été suggéré plusieurs fois dans les rapports de bogue PHP correspondants.

Mise à jour 2 : Je pense de plus en plus que le problème se trouve en fait dans le phpX_module spécifique pour Apache HTTPD sous Windows, car il semble fonctionner comme documenté lorsqu'il est utilisé sous Linux. Je ne sais seulement pas où trouver le site de développement, de documentation et de bogues pour les modules PHP libres ?

Mise à jour 3 : J'ai finalement trouvé un bug lié à la base de données des bugs d'Apache HTTPD. Ce comportement a été introduit aux alentours de la version 1.3 d'Apache HTTPD. Vous devez définir UseCanonicalName à la directive on dans le <VirtualHost> entrée dans httpd.conf (vérifiez également l'avertissement au bas de la page le document !).

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
</VirtualHost> 

Cela a marché pour moi.

Résumée, SERVER_NAME est plus fiable, mais vous dépendant sur la configuration du serveur !

5 votes

Ok, ceci résout mon problème, qui n'a rien à voir avec l'OP mais qui est pertinent. J'étais très préoccupé par les problèmes de sécurité en utilisant tout ce qu'un navigateur pouvait fournir. Cette réponse m'a été d'une GRANDE aide. Merci d'avoir pris le temps de la mettre au point.

2 votes

Pourquoi dites-vous que HTTP_HOST n'est pas fiable ? Oui, il est fourni par l'utilisateur, mais si l'utilisateur donne une valeur bidon, votre configuration serveur retournerait automatiquement 503 et votre script PHP ne serait même pas exécuté !

1 votes

@Pacerier : au moment de la rédaction de cette réponse, ce n'est pas le cas. Les versions sont mentionnées dans la réponse. Je ne me tiens plus au courant de PHP, donc je ne peux pas dire si cela a effectivement changé dans une version plus récente.

72voto

Pekka 웃 Points 249607

HTTP_HOST est l'hôte cible envoyé par le client. Il peut être manipulé librement par l'utilisateur. Il n'y a aucun problème à envoyer une requête à votre site demandant un HTTP_HOST valeur de www.stackoverflow.com .

SERVER_NAME provient de l'interface du serveur VirtualHost et est donc considéré comme plus fiable. Il peut toutefois aussi être manipulé de l'extérieur sous certaines conditions liées à la configuration de votre serveur web : Voir ceci Cette question de l'OS qui traite des aspects de sécurité des deux variantes.

Vous ne devriez pas compter sur l'un ou l'autre pour être en sécurité. Cela dit, ce qu'il faut utiliser dépend vraiment de ce que vous voulez faire. Si vous voulez déterminer sur quel domaine votre script s'exécute, vous pouvez utiliser en toute sécurité HTTP_HOST tant que les valeurs invalides provenant d'un utilisateur malveillant ne peuvent rien casser.

9 votes

Oui, mais une requête demandant une valeur HTTP_HOST de www.stackoverflow.com serait rejetée d'emblée par la plupart des serveurs HTTP, de sorte que le script PHP ne verrait même pas la requête !

2 votes

@Pacerier vrai, mais pas toujours si le serveur n'est pas correctement configuré.

1 votes

Comme mentionné dans le post de BalusC, lorsque vous accédez à un virtualhost Apache par IP, ambos de ces variables contiennent l'IP (par défaut), et non le nom réel du serveur. Vous devez utiliser UseCanonicalName on dans httpd.conf pour forcer SERVER_NAME pour être le nom réel du serveur.

60voto

Simon Points 4467

Comme je l'ai mentionné dans cette réponse Si le serveur fonctionne sur un port autre que 80 (comme cela peut être le cas sur une machine de développement/intranet), alors HTTP_HOST contient le port, tandis que SERVER_NAME ne le fait pas.

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'

(Du moins, c'est ce que j'ai remarqué dans les virtualhosts basés sur le port Apache).

A noté que HTTP_HOST fait pas contiennent :443 lors d'une exécution sur HTTPS (sauf si vous exécutez sur un port non standard, ce que je n'ai pas testé).

2 votes

Quand vont-ils corriger ce comportement insidieux ?

29voto

Daniel Marschall Points 177

Veuillez noter que si vous voulez utiliser IPv6, vous voudrez probablement utiliser HTTP_HOST plutôt que SERVER_NAME . Si vous entrez http://\[::1]/ les variables d'environnement seront les suivantes :

HTTP_HOST = [::1]
SERVER_NAME = ::1

Cela signifie que si vous effectuez un mod_rewrite par exemple, vous risquez d'obtenir un résultat désagréable. Exemple pour une redirection SSL :

# SERVER_NAME will NOT work - Redirection to https://::1/
RewriteRule .* https://%{SERVER_NAME}/

# HTTP_HOST will work - Redirection to https://[::1]/
RewriteRule .* https://%{HTTP_HOST}/

Cela s'applique UNIQUEMENT si vous accédez au serveur sans nom d'hôte.

1 votes

SiteGround, dans son code de redirection interne de http à https, utilise https://%{SERVER_NAME}%{REQUEST_URI}

5voto

Rowland Shaw Points 22860

Ça dépend de ce que je veux découvrir. SERVER_NAME est le nom d'hôte du serveur, tandis que HTTP_HOST est l'hôte virtuel auquel le client s'est connecté.

4 votes

Pas tout à fait vrai Rowland, SERVER_NAME est généralement le nom du VirtualHost, et non du serveur lui-même. Et dans Apache, SERVER_NAME est souvent remplie de la même valeur que HTTP_HOST (voir la réponse de BalusC).

1 votes

@Simon, Puisque les hôtes sont maintenant des VirtualHost, qu'entendez-vous par le nom du "serveur lui-même" ?

0 votes

Si vous utilisez un serveur privé virtuel (VPS) avec un seul site web, vous ne devez pas supposer que SERVER_NAME s'applique à un hôte virtuel. Cependant, on peut toujours utiliser une configuration d'hôte virtuel pour un seul site. De nombreuses personnes utilisent l'hébergement partagé, je comprends donc votre point de vue.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X