J'ai fait beaucoup de recherches et j'ai également lu la documentation PHP $ _SERVER . Ai-je ce droit sur lequel utiliser pour mes scripts PHP pour les définitions de liens simples utilisées sur mon site?
$_SERVER['SERVER_NAME']
est basé sur le fichier de configuration de votre serveur Web (Apache2 dans mon cas), et varie en fonction de quelques directives: (1) VirtualHost, (2) ServerName, (3) UseCanonicalName, etc.
$_SERVER['HTTP_HOST']
est basé sur la demande du client.
Par conséquent, il me semble que le bon à utiliser pour rendre mes scripts aussi compatibles que possible serait $_SERVER['HTTP_HOST']
. Cette hypothèse est-elle correcte?
Commentaires de suivi:
Je suppose que je suis devenu un peu paranoïaque après avoir lu cet article et noté que certains ont dit "qu'ils ne feraient confiance à aucun des $_SERVER
vars":
http://markjaquith.wordpress.com/2009/09/21/php-server-vars-not-safe-in-forms-or-links/
http://php.net/manual/en/reserved.variables.server.php#89567 (commentaire: Vladimir Kornea 14-mars-2009 01:06)
Apparemment, la discussion porte principalement sur les $_SERVER['PHP_SELF']
raisons pour lesquelles vous ne devriez pas l'utiliser dans l'attribut form action sans échapper correctement pour empêcher les attaques XSS.
Ma conclusion à propos de ma question initiale ci-dessus est qu'il est "sûr" de l'utiliser $_SERVER['HTTP_HOST']
pour tous les liens d'un site sans avoir à se soucier des attaques XSS, même lorsqu'il est utilisé dans des formulaires.
Corrigez-moi si j'ai tort, s'il-vous plait.
$_SERVER['SERVER_NAME']
et$_SERVER['HTTP_HOST']
(mis à part l'implémentation d'une autre poignée de main personnalisée en fonction de la demande de l'utilisateur). Les développeurs professionnels ne font pas confiance aux choses qu'ils ne comprennent pas complètement. Ils ont donc soit leur SAPI configuration parfaitement correctement (dans ce cas , l'option qu'ils utilisent va donner le résultat correct), ou ils vont faire une liste blanche telle qu'elle n'a pas d' importance ce que les valeurs de l'offre SAPI.array_key_exists
est plus évolutive par rapport àin_array
ce que a O (n) performance.Juste une remarque supplémentaire - si le serveur fonctionne sur un port autre que 80 (comme cela pourrait être courant sur une machine de développement / intranet), il
HTTP_HOST
contient alors le port, alors que ceSERVER_NAME
n'est pas le cas.(Du moins, c'est ce que j'ai remarqué dans les hôtes virtuels basés sur le port Apache)
Comme Mike l'a noté ci-dessous,
HTTP_HOST
ne contient pas:443
lors de l'exécution sur HTTPS (sauf si vous utilisez un port non standard, que je n'ai pas testé).la source
HTTP_HOST
n'est pas exactement leHost:
paramètre fourni par l'utilisateur. Il est simplement basé sur cela.Utilisez l'un ou l'autre. Ils sont tous les deux également (in) sécurisés, car dans de nombreux cas, SERVER_NAME est de toute façon alimenté à partir de HTTP_HOST. Je choisis normalement 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 vers .com, en particulier s'il peut avoir des jetons de connexion sur .org qu'ils perdraient s'ils étaient envoyés à l'autre domaine.
Dans tous les cas, vous devez simplement vous assurer que votre application Web ne répondra que pour les domaines connus. Cela peut être fait soit (a) avec une vérification côté application comme celle de Gumbo, ou (b) en utilisant un hôte virtuel sur le (s) nom (s) de domaine que vous voulez et qui ne répond pas aux demandes qui donnent un en-tête Host inconnu.
La raison en est que si vous autorisez l'accès à votre site sous n'importe quel ancien nom, vous vous exposez aux attaques de rebinding DNS (où le nom d'hôte d'un autre site pointe vers votre IP, un utilisateur accède à votre site avec le nom d'hôte de l'attaquant, puis le nom d'hôte. est déplacé vers l'adresse IP de l'attaquant, emportant vos cookies / authentification avec lui) et le piratage des moteurs de recherche (où un attaquant pointe son propre nom d'hôte sur votre site et essaie de faire en sorte que les moteurs de recherche le voient comme le `` meilleur '' nom d'hôte principal).
Pfft. Eh bien , vous ne devriez pas utiliser quoi que ce soit dans tout attribut sans échapper avec
htmlspecialchars($string, ENT_QUOTES)
, donc il y a des variables du serveur spécial à propos de rien.la source
attacker.com
comme la meilleure source principale pour l'adresse IP de votre serveur"? Cela ne semble rien signifier pour les moteurs de recherche, qu'est-ce que cela va faire?http://example.com/
,http://www.example.com/
ethttp://93.184.216.34/
qu'il les combinerait en un seul site, choisissez la plus populaire des adresses et ne renvoyez que les liens vers cela. version. Si vous pouviez pointerevil-example.com
vers la même adresse et faire en sorte que Google voie brièvement cela comme l'adresse la plus populaire, vous pourriez voler le jus du site. Je ne sais pas à quel point c'est pratique aujourd'hui, mais j'ai vu des attaquants de fermes de liens russes essayer de le faire dans le passé.Ceci est une traduction détaillée de ce que Symfony utilise pour obtenir le nom d'hôte ( voir le deuxième exemple pour une traduction plus littérale ):
Dépassé:
Ceci est ma traduction en PHP nu d'une méthode utilisée dans le framework Symfony qui tente d'obtenir le nom d'hôte de toutes les manières possibles dans l'ordre des meilleures pratiques:
la source
if ($host = $_SERVER['HTTP_X_FORWARDED_HOST'])
oux = a == 1 ? True : False
. La première fois que je l'ai vu, mon cerveau cherchait une instanciation de $ host et une réponse pour "pourquoi un seul" = "signe?" Je commence à détester les langages de programmation de frappe faibles. Tout est écrit différemment. Vous ne gagnez pas de temps et vous n'êtes pas spécial. Je n'écris pas de code de cette façon, car après le temps, c'est moi qui ai besoin de le déboguer. Ça a l'air vraiment en désordre pour un cerveau fatigué! Je sais que mon anglais est engrish, mais au moins j'essaye.Oui, c'est sûr à utiliser
$_SERVER['HTTP_HOST']
, (et même$_GET
et$_POST
) tant que vous les vérifiez avant de les accepter. Voici ce que je fais pour les serveurs de production sécurisés:L'avantage de
$_SERVER['HTTP_HOST']
est que son comportement est plus bien défini que$_SERVER['SERVER_NAME']
. Contraste ➫➫ :avec:
L'utilisation d'une interface mieux définie comme cela
$_SERVER['HTTP_HOST']
signifie que plus de SAPI l'implémenteront en utilisant un comportement fiable et bien défini. (Contrairement à l'autre .) Cependant, il est encore totalement dépendant de SAPI ➫➫ :Pour comprendre comment récupérer correctement le nom d'hôte, vous devez d'abord et avant tout comprendre qu'un serveur qui ne contient que du code n'a aucun moyen de connaître (condition préalable à la vérification) son propre nom sur le réseau. Il doit s'interfacer avec un composant qui lui fournit son propre nom. Cela peut être fait via:
fichier de configuration local
base de données locale
code source codé en dur
requête externe ( curl )
Host:
demande du client / attaquantetc
Habituellement, cela se fait via le fichier de configuration local (SAPI). Notez que vous l'avez configuré correctement, par exemple dans Apache ➫➫ :
la source
La principale différence entre les deux est qu'il
$_SERVER['SERVER_NAME']
s'agit d'une variable contrôlée par le serveur, tandis que$_SERVER['HTTP_HOST']
c'est une valeur contrôlée par l'utilisateur.La règle d'or est de ne jamais faire confiance aux valeurs de l'utilisateur, donc
$_SERVER['SERVER_NAME']
le meilleur choix.Comme Gumbo l'a souligné, Apache construira SERVER_NAME à partir des valeurs fournies par l'utilisateur si vous ne définissez pas
UseCanonicalName On
.Edit: Cela dit, si le site utilise un hôte virtuel basé sur le nom, l'en-tête HTTP Host est le seul moyen d'atteindre des sites qui ne sont pas le site par défaut.
la source
Host:
valeur HTTP sauf si vous l'avez déjà vérifiée , soit manuellement, soit via la configuration de votre SAPI.Je ne suis pas sûr et pas vraiment confiance
$_SERVER['HTTP_HOST']
car cela dépend de l'en-tête du client. D'une autre manière, si un domaine demandé par le client n'est pas le mien, ils n'entreront pas dans mon site car les protocoles DNS et TCP / IP le pointent vers la bonne destination. Cependant, je ne sais pas s'il est possible de détourner le DNS, le réseau ou même le serveur Apache. Pour être sûr, je définis le nom d'hôte dans l'environnement et je le compare avec$_SERVER['HTTP_HOST']
.Ajoutez le
SetEnv MyHost domain.com
fichier .htaccess à la racine et ajoutez le code dans Common.phpJ'inclus ce fichier Common.php dans chaque page php. Cette page fait tout ce qui est nécessaire pour chaque demande, comme
session_start()
modifier le cookie de session et rejeter si la méthode de publication provient d'un domaine différent.la source
Host:
valeur fradulente directement sur l'IP de votre serveur.XSS
sera toujours là même si vous utilisez$_SERVER['HTTP_HOST']
,$_SERVER['SERVER_NAME']
OU$_SERVER['PHP_SELF']
la source
Je tiens d'abord à vous remercier pour toutes les bonnes réponses et explications. C'est la méthode que j'ai créée en fonction de toutes vos réponses pour obtenir l'URL de base. Je ne l'utilise que dans de très rares situations. Il n'y a donc PAS une grande concentration sur les problèmes de sécurité, comme les attaques XSS. Peut-être que quelqu'un en a besoin.
la source