¿Es "seguro" usarlo $_SERVER['HTTP_HOST']
para todos los enlaces en un sitio sin tener que preocuparse por los ataques XSS, incluso cuando se usan en formularios?
Sí, es seguro de usar $_SERVER['HTTP_HOST']
, (e incluso $_GET
y $_POST
) siempre que los verifique antes de aceptarlos. Esto es lo que hago para servidores de producción 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!';
// ...
La ventaja de $_SERVER['HTTP_HOST']
es que su comportamiento está más bien definido que $_SERVER['SERVER_NAME']
. Contraste ➫➫ :
Contenido del host: encabezado de la solicitud actual, si hay una.
con:
El nombre del host del servidor en el que se ejecuta el script actual.
El uso de una interfaz mejor definida $_SERVER['HTTP_HOST']
significa que más SAPI lo implementarán utilizando un comportamiento confiable y bien definido. (A diferencia del otro .) Sin embargo, todavía depende totalmente de SAPI ➫➫ :
No hay garantía de que cada servidor web proporcione ninguna de estas [ $_SERVER
entradas]; los servidores pueden omitir algunos o proporcionar otros que no figuran aquí.
Para comprender cómo recuperar correctamente el nombre de host, primero debe comprender que un servidor que contiene solo código no tiene medios para conocer (requisito previo para verificar) su propio nombre en la red. Necesita interactuar con un componente que le proporcione su propio nombre. Esto se puede hacer a través de:
archivo de configuración local
base de datos local
código fuente codificado
solicitud externa ( curl )
Host:
solicitud del cliente / atacante
etc.
Por lo general, se realiza a través del archivo de configuración local (SAPI). Tenga en cuenta que lo ha configurado correctamente, por ejemplo, en Apache ➫➫ :
Hay que 'falsificar' un par de cosas para que el host virtual dinámico se vea normal.
El más importante es el nombre del servidor que utiliza Apache para generar URL autorreferenciales, etc. Está configurado con la ServerName
directiva y está disponible para CGI a través deSERVER_NAME
variable de entorno.
El valor real utilizado en tiempo de ejecución está controlado por la configuración UseCanonicalName.
Con UseCanonicalName Off
el nombre del servidor proviene del contenido del Host:
encabezado en la solicitud. Con UseCanonicalName DNS
esto proviene de una búsqueda inversa de DNS de la dirección IP del host virtual. La configuración anterior se usa para el alojamiento virtual dinámico basado en nombres, y la segunda se usa para el alojamiento ** basado en IP.
Si Apache no puede calcular el nombre del servidor porque no hay Host:
encabezado o la búsqueda de DNS falla, entoncesServerName
se utiliza el valor configurado con .