Pesquisei bastante e também li os documentos do PHP $ _SERVER . Eu tenho esse direito sobre o que usar nos meus scripts PHP para definições simples de link usadas em todo o meu site?
$_SERVER['SERVER_NAME']
é baseado no arquivo de configuração do servidor da web (Apache2 no meu caso) e varia de acordo com algumas diretrizes: (1) VirtualHost, (2) ServerName, (3) UseCanonicalName, etc.
$_SERVER['HTTP_HOST']
é baseado na solicitação do cliente.
Portanto, parece-me que o correto a ser usado para tornar meus scripts o mais compatível possível seria $_SERVER['HTTP_HOST']
. Esta suposição está correta?
Comentários de acompanhamento:
Acho que fiquei um pouco paranóico depois de ler este artigo e notar que algumas pessoas disseram "não confiariam em nenhum dos $_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 (comentário: Vladimir Kornea 14-Mar-2009 01:06)
Aparentemente, a discussão é principalmente sobre $_SERVER['PHP_SELF']
e por que você não deve usá-la no atributo action action sem escape apropriado para evitar ataques XSS.
Minha conclusão sobre minha pergunta original acima é que é "seguro" usar $_SERVER['HTTP_HOST']
para todos os links em um site sem ter que se preocupar com ataques XSS, mesmo quando usado em formulários.
Por favor me corrija se eu estiver errado.
$_SERVER['SERVER_NAME']
e$_SERVER['HTTP_HOST']
(além de implementar outro handshake personalizado com base na solicitação do usuário). Os desenvolvedores profissionais não confiam no que não entendem completamente. Então, que quer ter sua SAPI configuração perfeitamente corretamente (caso em que a opção que eles usam vai dar o resultado correto), ou eles vão fazer whitelisting de tal forma que não importa o que valoriza o fornecimento SAPI.array_key_exists
é mais escalável em comparação comin_array
o desempenho O (n).Apenas uma observação adicional - se o servidor executar em uma porta diferente de 80 (como pode ser comum em uma máquina de desenvolvimento / intranet), ela
HTTP_HOST
conterá a porta, enquantoSERVER_NAME
não.(Pelo menos foi o que notei nos virtualhosts baseados em porta do Apache)
Como Mike observou a seguir,
HTTP_HOST
que não contêm:443
quando executado em HTTPS (a menos que você estiver executando em uma porta não-padrão, o que eu não testei).fonte
HTTP_HOST
não é exatamente oHost:
parâmetro fornecido pelo usuário. É apenas baseado nisso.Use qualquer um. Ambos são igualmente (in) seguros, pois em muitos casos o SERVER_NAME é apenas preenchido a partir de HTTP_HOST de qualquer maneira. Eu normalmente uso HTTP_HOST, para que o usuário permaneça no nome exato do host em que começou. Por exemplo, se eu tiver o mesmo site em um domínio .com e .org, não quero enviar alguém de .org para .com, principalmente se eles tiverem tokens de login em .org que perderiam se enviados para o outro domínio.
De qualquer forma, você só precisa ter certeza de que o seu aplicativo da Web só responderá sempre por domínios conhecidos. Isso pode ser feito (a) com uma verificação no lado do aplicativo, como a Gumbo, ou (b) usando um host virtual no (s) nome (s) de domínio que você deseja que não responda às solicitações que fornecem um cabeçalho de host desconhecido.
A razão para isso é que, se você permitir que seu site seja acessado com qualquer nome antigo, você estará aberto a ataques de religação de DNS (onde o nome do host de outro site aponta para o seu IP, um usuário acessa o site com o nome do host do atacante e, em seguida, o nome do host é movido para o IP do invasor, levando seus cookies / autenticação com ele) e o seqüestro de mecanismo de pesquisa (onde um invasor aponta seu próprio nome de host em seu site e tenta fazer com que os mecanismos de pesquisa o vejam como o 'melhor' nome de host principal).
Pfft. Bem, você não deve usar nada em nenhum atributo sem escapar
htmlspecialchars($string, ENT_QUOTES)
, portanto não há nada de especial nas variáveis do servidor.fonte
attacker.com
como a melhor fonte primária para o IP do seu servidor"? Isso não parece significar nada para os mecanismos de pesquisa. O que isso vai fazer?http://example.com/
,http://www.example.com/
ehttp://93.184.216.34/
seria combiná-los em um site, escolher o mais popular dos endereços, e retornar apenas links para que versão. Se você pudesse apontarevil-example.com
para o mesmo endereço e fazer com que o Google visse brevemente, como o endereço mais popular, você poderia roubar o suco do site. Não sei como isso é prático hoje, mas já vi invasores russos de fazendas de links tentarem fazer isso no passado.Esta é uma tradução detalhada do que o Symfony usa para obter o nome do host ( veja o segundo exemplo para uma tradução mais literal ):
Desatualizado:
Esta é minha tradução para simplificar o PHP de um método usado no framework Symfony que tenta obter o nome do host de todas as maneiras possíveis, na ordem das melhores práticas:
fonte
if ($host = $_SERVER['HTTP_X_FORWARDED_HOST'])
oux = a == 1 ? True : False
. A primeira vez que o vi, meu cérebro estava procurando por instanciação $ host e uma resposta para "por que é apenas um" = "sinal?". Estou começando a não gostar de linguagens de programação de digitação fracas. Tudo está escrito de forma diferente. Você não economiza tempo e não é especial. Não escrevo código dessa maneira, porque depois que o tempo passa, sou eu quem precisa depurá-lo. Parece realmente confuso para um cérebro cansado! Eu sei que meu inglês é interessante, mas pelo menos eu tento.Sim, é seguro usar
$_SERVER['HTTP_HOST']
(e até$_GET
e$_POST
) desde que você os verifique antes de aceitá-los. Isto é o que faço para servidores de produção seguros:A vantagem
$_SERVER['HTTP_HOST']
é que seu comportamento é mais bem definido do que$_SERVER['SERVER_NAME']
. Contraste ➫➫ :com:
Usar uma interface melhor definida como
$_SERVER['HTTP_HOST']
significa que mais SAPIs a implementarão usando um comportamento bem definido e confiável . (Diferente do outro .) No entanto, ainda é totalmente dependente do SAPI ➫➫ :Para entender como recuperar corretamente o nome do host, primeiro e acima de tudo, você precisa entender que um servidor que contém apenas código não tem como saber (pré-requisito para verificar) seu próprio nome na rede. Ele precisa interagir com um componente que fornece seu próprio nome. Isso pode ser feito via:
arquivo de configuração local
banco de dados local
código fonte codificado
solicitação externa ( ondulação )
Host:
solicitação do cliente / atacanteetc
Geralmente é feito através do arquivo de configuração local (SAPI). Observe que você o configurou corretamente, por exemplo, no Apache ➫➫ :
fonte
A principal diferença entre os dois é que
$_SERVER['SERVER_NAME']
é uma variável controlada pelo servidor, enquanto$_SERVER['HTTP_HOST']
é um valor controlado pelo usuário.A regra geral é nunca confiar nos valores do usuário, assim
$_SERVER['SERVER_NAME']
é a melhor escolha.Como Gumbo apontou, o Apache criará SERVER_NAME a partir dos valores fornecidos pelo usuário, se você não definir
UseCanonicalName On
.Edit: Dito tudo isso, se o site estiver usando um host virtual baseado em nome, o cabeçalho HTTP Host é a única maneira de acessar sites que não são o site padrão.
fonte
Host:
valor do HTTP, a menos que você já o tenha verificado , manualmente ou através da instalação do SAPI.Não tenho certeza e não confio realmente
$_SERVER['HTTP_HOST']
porque depende do cabeçalho do cliente. De outra maneira, se um domínio solicitado pelo cliente não for o meu, eles não entrarão no meu site porque os protocolos DNS e TCP / IP apontam para o destino correto. No entanto, não sei se é possível seqüestrar o DNS, a rede ou mesmo o servidor Apache. Para ser seguro, defino o nome do host no ambiente e o comparo com$_SERVER['HTTP_HOST']
.Adicione o
SetEnv MyHost domain.com
arquivo .htaccess na raiz e adicione o código ths no Common.phpEu incluo esse arquivo Common.php em todas as páginas php. Esta página faz o que for necessário para cada solicitação
session_start()
, como modificar o cookie da sessão e rejeitar se o método post vier de um domínio diferente.fonte
Host:
valor irrelevante diretamente para o IP do seu servidor.XSS
sempre estará lá, mesmo se você usar$_SERVER['HTTP_HOST']
,$_SERVER['SERVER_NAME']
OU$_SERVER['PHP_SELF']
fonte
Primeiro, quero agradecer por todas as boas respostas e explicações. Este é o método que eu criei com base em todas as suas respostas para obter o URL base. Só o uso em situações muito raras. Portanto, NÃO existe um grande foco em questões de segurança, como ataques XSS. Talvez alguém precise.
fonte