É "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?
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:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
$reject_request = true;
if(array_key_exists('HTTP_HOST', $_SERVER)){
$host_name = $_SERVER['HTTP_HOST'];
// [ need to cater for `host:port` since some "buggy" SAPI(s) have been known to return the port too, see http://goo.gl/bFrbCO
$strpos = strpos($host_name, ':');
if($strpos !== false){
$host_name = substr($host_name, $strpos);
}
// ]
// [ for dynamic verification, replace this chunk with db/file/curl queries
$reject_request = !array_key_exists($host_name, array(
'a.com' => null,
'a.a.com' => null,
'b.com' => null,
'b.b.com' => null
));
// ]
}
if($reject_request){
// log errors
// display errors (optional)
exit;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
echo 'Hello World!';
// ...
A vantagem $_SERVER['HTTP_HOST']
é que seu comportamento é mais bem definido do que $_SERVER['SERVER_NAME']
. Contraste ➫➫ :
Conteúdo do host: cabeçalho da solicitação atual, se houver.
com:
O nome do host do servidor sob o qual o script atual está sendo executado.
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 ➫➫ :
Não há garantia de que todo servidor web forneça qualquer uma dessas [ $_SERVER
entradas]; servidores podem omitir alguns ou fornecer outros não listados aqui.
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 / atacante
etc
Geralmente é feito através do arquivo de configuração local (SAPI). Observe que você o configurou corretamente, por exemplo, no Apache ➫➫ :
Algumas coisas precisam ser "falsificadas" para fazer com que o host virtual dinâmico pareça normal.
O mais importante é o nome do servidor usado pelo Apache para gerar URLs auto-referenciais etc. Ele é configurado com a ServerName
diretiva e está disponível para CGIs por meio doSERVER_NAME
meio da variável de ambiente.
O valor real usado no tempo de execução é controlado pela configuração UseCanonicalName.
Com UseCanonicalName Off
o nome do servidor, vem do conteúdo do Host:
cabeçalho na solicitação. Com UseCanonicalName DNS
isso, vem de uma pesquisa DNS reversa do endereço IP do host virtual. A configuração anterior é usada para hospedagem virtual dinâmica baseada em nome e a última é usada para ** hospedagem baseada em IP.
Se o Apache não puder descobrir o nome do servidor porque não há Host:
cabeçalho ou a pesquisa de DNS falhar , o valor configurado com ServerName
será usado.