Я много искал, а также читал документацию по PHP $ _SERVER . Имею ли я это право в отношении того, какие скрипты PHP использовать для простых определений ссылок, используемых на моем сайте?
$_SERVER['SERVER_NAME']
основан на файле конфигурации вашего веб-сервера (в моем случае Apache2) и варьируется в зависимости от нескольких директив: (1) VirtualHost, (2) ServerName, (3) UseCanonicalName и т. д.
$_SERVER['HTTP_HOST']
основано на запросе от клиента.
Поэтому мне кажется, что будет правильным использовать его, чтобы сделать мои сценарии максимально совместимыми $_SERVER['HTTP_HOST']
. Это предположение верно?
Последующие комментарии:
Полагаю, я немного заразился после прочтения этой статьи и заметил, что некоторые люди говорят: «Они не будут доверять ни одной из $_SERVER
перемен»:
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 (комментарий: Владимир Корнеа, 14 марта 2009 г., 01:06)
Очевидно, речь идет в основном о том, $_SERVER['PHP_SELF']
почему вы не должны использовать его в атрибуте действия формы без надлежащего экранирования для предотвращения атак XSS.
Мой вывод о моем первоначальном вопросе выше состоит в том, что «безопасно» использовать $_SERVER['HTTP_HOST']
все ссылки на сайте, не беспокоясь о XSS-атаках, даже если они используются в формах.
Пожалуйста, поправьте меня, если я ошибаюсь.
$_SERVER['SERVER_NAME']
и$_SERVER['HTTP_HOST']
(кроме реализации некоторого другого пользовательского рукопожатия, основанного на запросе пользователя). Профессиональные разработчики не доверяют вещам, которые они не понимают полностью. Таким образом, они либо имеют свои настройки SAPI совершенно правильно (в этом случае выбранный ими вариант даст правильный результат), либо они составят белый список так, что не имеет значения, какие значения поставляются SAPI.array_key_exists
является более масштабируемым по сравнению с тем,in_array
что имеет производительность O (n).Просто дополнительное примечание - если сервер работает на порте, отличном от 80 (как это может быть распространено на машине разработки / интрасети), то
HTTP_HOST
содержит порт, аSERVER_NAME
не -.(По крайней мере, это то, что я заметил в виртуальных хостах на основе портов Apache)
Как заметил Майк ниже,
HTTP_HOST
он не содержится:443
при работе по HTTPS (если только вы не используете нестандартный порт, который я не тестировал).источник
HTTP_HOST
не совсемHost:
параметр, предоставленный пользователем. Это просто основано на этом.Используйте либо. Они оба одинаково (небезопасны), так как во многих случаях SERVER_NAME в любом случае просто заполняется из HTTP_HOST. Обычно я использую HTTP_HOST, чтобы пользователь оставался на том же имени хоста, на котором он начал. Например, если у меня есть один и тот же сайт в домене .com и .org, я не хочу отправлять кого-то из .org в .com, особенно если у них могут быть токены входа в систему .org, которые они потеряли бы, если бы их отправили в другой домен.
В любом случае, вам просто нужно быть уверенным, что ваше веб-приложение будет отвечать только за известные домены. Это можно сделать либо (а) с помощью проверки на стороне приложения, такой как Gumbo, либо (б) с использованием виртуального хоста на доменных именах, которые вы хотите, которые не отвечают на запросы, которые дают неизвестный заголовок хоста.
Причина этого заключается в том, что если вы разрешаете доступ к вашему сайту под любым старым именем, вы открываете себя для атак повторного связывания DNS (когда имя хоста другого сайта указывает на ваш IP, пользователь получает доступ к вашему сайту с именем хоста злоумышленника, а затем именем хоста). перемещается по IP-адресу злоумышленника, забирая ваши куки / авторизацию с ним) и захватывая поисковую систему (когда злоумышленник указывает свое собственное имя хоста на ваш сайт и пытается заставить поисковые системы видеть его как «лучшее» основное имя хоста).
Пфф. Что ж, вы не должны использовать что-либо в любом атрибуте без экранирования
htmlspecialchars($string, ENT_QUOTES)
, так что там нет ничего особенного в серверных переменных.источник
attacker.com
лучший первичный источник IP вашего сервера»? Похоже, это ничего не значит для поисковых систем. Что это вообще собирается делать?http://example.com/
,http://www.example.com/
иhttp://93.184.216.34/
он будет объединять их в один сайт, выберите самый популярный из адресов и верните только ссылки на него. версия. Если бы вы могли указатьevil-example.com
на тот же адрес и сделать так, чтобы Google кратко заметил, что в качестве более популярного адреса вы могли бы украсть сок сайта. Я не знаю, насколько это практично сегодня, но я видел, как российские злоумышленники пытались сделать это в прошлом.Это подробный перевод того, что Symfony использует для получения имени хоста ( см. Второй пример для более буквального перевода ):
Устаревшие:
Это мой перевод на голый PHP метода, используемого в платформе Symfony, который пытается получить имя хоста любым возможным способом в порядке лучшей практики:
источник
if ($host = $_SERVER['HTTP_X_FORWARDED_HOST'])
илиx = a == 1 ? True : False
. В первый раз, когда я увидел это, мой мозг искал инстанцирования $ host и ответа на вопрос «почему только один» = «знак?». Я начинаю не любить слабые языки программирования. Все написано по-другому. Вы не экономите время, и вы не особенный. Я не пишу код таким образом, потому что по прошествии времени я должен отлаживать его. Выглядит очень грязно для усталого мозга! Я знаю, что мой английский - английский, но, по крайней мере, я стараюсь.Да, это безопасно использовать
$_SERVER['HTTP_HOST']
(и даже$_GET
и$_POST
), пока вы проверяете их, прежде чем принять их. Вот что я делаю для защищенных производственных серверов:Преимущество в
$_SERVER['HTTP_HOST']
том, что его поведение более четко определено, чем$_SERVER['SERVER_NAME']
. Контраст ➫➫ :с участием:
Использование более определенного интерфейса, такого как,
$_SERVER['HTTP_HOST']
означает, что большее количество SAPI будет реализовывать его, используя надежное, четко определенное поведение. (В отличие от других .) Однако он все еще полностью зависит от SAPI ➫➫ :Чтобы понять, как правильно получить имя хоста, прежде всего вам необходимо понять, что сервер, который содержит только код, не имеет возможности узнать (предварительное условие для проверки) свое собственное имя в сети. Он должен взаимодействовать с компонентом, который предоставляет ему свое имя. Это можно сделать через:
локальный конфигурационный файл
локальная база данных
жестко закодированный исходный код
внешний запрос ( curl )
Host:
запрос клиента / злоумышленникаи т.д
Обычно это делается через локальный (SAPI) файл конфигурации. Обратите внимание, что вы настроили его правильно, например, в Apache ➫➫ :
источник
Основное различие между ними заключается в том, что
$_SERVER['SERVER_NAME']
это переменная, управляемая сервером, а$_SERVER['HTTP_HOST']
значение, контролируемое пользователем.Основное правило - никогда не доверять значениям пользователя, поэтому
$_SERVER['SERVER_NAME']
это лучший выбор.Как указал Гамбо, Apache создаст SERVER_NAME из предоставленных пользователем значений, если вы не установите их
UseCanonicalName On
.Изменить: Сказав все это, если сайт использует виртуальный хост на основе имени, заголовок HTTP Host является единственным способом добраться до сайтов, которые не являются сайтом по умолчанию.
источник
Host:
значению HTTP, если вы уже не проверили его, ни вручную, ни через настройку SAPI.Я не уверен и не очень доверяю,
$_SERVER['HTTP_HOST']
потому что это зависит от заголовка от клиента. Иными словами, если запрашиваемый клиентом домен не принадлежит мне, он не попадет на мой сайт, поскольку протокол DNS и TCP / IP указывают его на правильный пункт назначения. Однако я не знаю, если это возможно, чтобы захватить DNS, сеть или даже сервер Apache. Чтобы быть в безопасности, я определяю имя хоста в среде и сравниваю его с$_SERVER['HTTP_HOST']
.Добавьте
SetEnv MyHost domain.com
в корневой файл .htaccess и добавьте этот код в Common.phpЯ включаю этот файл Common.php в каждую страницу php. Эта страница делает все, что требуется для каждого запроса, например
session_start()
, изменяет сеансовый cookie и отклоняет, если метод post пришел из другого домена.источник
Host:
значение непосредственно в IP-адрес вашего сервера.XSS
всегда будет там, даже если вы используете$_SERVER['HTTP_HOST']
,$_SERVER['SERVER_NAME']
или$_SERVER['PHP_SELF']
источник
Сначала я хочу поблагодарить вас за все хорошие ответы и объяснения. Это метод, который я создал на основе всего вашего ответа, чтобы получить базовый URL. Я использую его только в очень редких ситуациях. Таким образом, не уделяется большое внимание вопросам безопасности, таким как атаки XSS. Может, кому-то это нужно.
источник