Безопасно ли использовать $_SERVER['HTTP_HOST']
для всех ссылок на сайте, не беспокоясь о XSS-атаках, даже при использовании в формах?
Да, безопасно использовать $_SERVER['HTTP_HOST']
, (и даже $_GET
и $_POST
) , пока вы проверяете их до их принятия. Вот что я делаю для защищенных производственных серверов:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
$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!';
// ...
Преимущество $_SERVER['HTTP_HOST']
в том, что его поведение более четко определено, чем $_SERVER['SERVER_NAME']
. Контраст & # x27ab; & # x27ab; :
Содержимое заголовка Host: из текущего запроса, если он есть.
с:
Имя хоста сервера, под которым выполняется текущий скрипт.
Использование более определенного интерфейса, такого как $_SERVER['HTTP_HOST']
, означает, что больше SAPI будут реализовывать его, используя надежное четко определенное поведение. (В отличие от другого .) Однако он все еще полностью зависит от SAPI & # x27ab; & # x27ab; :
Нет никакой гарантии, что каждый веб-сервер предоставит любую из этих [$_SERVER
записей]; серверы могут пропустить некоторые или предоставить другие, не перечисленные здесь.
Чтобы понять, как правильно получить имя хоста, в первую очередь вам необходимо понять, что сервер, который содержит только код , не имеет возможности узнать (предварительное условие для проверки) свой собственный имя в сети. Он должен взаимодействовать с компонентом, который предоставляет ему собственное имя. Это можно сделать через:
локальный файл конфигурации
локальная база данных
исходный код в жестком коде
внешний запрос ( curl )
клиент / злоумышленник Host:
запрос
и т.д.
Обычно это делается через локальный (SAPI) файл конфигурации. Обратите внимание, что вы настроили его правильно, например, в Apache & # x027ab; & # x027ab; :
Несколько вещей необходимо «подделать», чтобы динамический виртуальный хост выглядел как обычный.
Наиболее важным является имя сервера, которое Apache использует для генерации URL-адресов с самореференциями и т. Д. Он настроен с помощью директивы ServerName
и доступен для CGI через переменную среды SERVER_NAME
.
Фактическое значение, используемое во время выполнения, составляет , управляемое настройкой UseCanonicalName.
При UseCanonicalName Off
имя сервера происходит из содержимого заголовка Host:
в запросе. С UseCanonicalName DNS
это происходит из-за обратного просмотра DNS IP-адреса виртуального хоста. Первый параметр используется для динамического виртуального хостинга на основе имен, а второй - для ** хостинга на основе IP.
Если Apache не может обработать имя сервера, так как отсутствует заголовок Host:
или поиск DNS не удается , тогда вместо него используется значение , настроенное с помощью ServerName
.