Единственный безопасный способ сделать это
Все остальные ответы на этой странице имеют последствия для безопасности, о которых вам нужно знать. Единственный гарантированно безопасный метод получения текущего домена - это самому сохранить его в безопасном месте .
Большинство фреймворков заботятся о хранении домена за вас, поэтому вы захотите ознакомиться с документацией для вашего конкретного фреймворка. Если вы не используете фреймворк, рассмотрите возможность хранения домена в одном из следующих мест:
+ ------------------------------------------------- --- + ----------------------------------- +
| Безопасные методы хранения домена | Используется |
+ ------------------------------------------------- --- + ----------------------------------- +
| Файл конфигурации | Joomla, Drupal / Symfony |
| База данных | WordPress |
| Переменная окружающей среды | Laravel |
| Реестр услуг | Kubernetes DNS |
+ ------------------------------------------------- --- + ----------------------------------- +
Следующая работа ... но они небезопасны
Хакеры могут заставить следующие переменные выводить любой домен, который они хотят. Это может привести к заражению кеша и малозаметным фишинговым атакам.
$_SERVER['HTTP_HOST']
Он получает домен из заголовков запросов, которые открыты для манипуляций со стороны хакеров . То же самое с:
$_SERVER['SERVER_NAME']
Это можно улучшить, если отключить параметр Apache usecanonicalname ; в этом случае $_SERVER['SERVER_NAME']
больше не будет разрешено заполнять произвольные значения, и это будет безопасно. Однако это не по умолчанию и не так часто встречается в настройке.
В популярных системах
Ниже показано, как получить текущий домен в следующих фреймворках / системах:
WordPress
$urlparts = parse_url(home_url());
$domain = $urlparts['host'];
Если вы создаете URL-адрес в WordPress, просто используйте home_url или site_url или любую другую функцию URL .
Laravel
request()->getHost()
Эта request()->getHost
функция унаследована от Symfony и является безопасной с момента исправления CVE-2013-4752 2013 года .
Drupal
Программа установки еще не позаботилась об обеспечении безопасности ( проблема № 2404259 ). Но в Drupal 8 есть документация, за которой вы можете следить в настройках доверенного хоста, чтобы защитить вашу установку Drupal, после чего можно использовать следующее:
\Drupal::request()->getHost();
Другие фреймворки
Не стесняйтесь редактировать этот ответ, чтобы указать, как получить текущий домен в вашей любимой структуре. При этом включите ссылку на соответствующий исходный код или на что-нибудь еще, что поможет мне убедиться, что фреймворк работает безопасно.
Дополнение
Примеры эксплуатации:
Отравление кеша может произойти, если ботнет постоянно запрашивает страницу с использованием неправильного заголовка хоста. В результате полученный HTML-код будет включать ссылки на веб-сайт злоумышленников, где они могут фишинговать ваших пользователей. Сначала вредоносные ссылки будут отправлены обратно только хакеру, но если хакер сделает достаточно запросов, вредоносная версия страницы окажется в вашем кеше, где она будет распространена среди других пользователей.
Фишинговая атака может произойти, если вы храните ссылки в базе данных на основе заголовка hosts. Например, допустим, вы храните абсолютный URL-адрес профилей пользователя на форуме. Используя неправильный заголовок, хакер может заставить любого, кто нажимает на ссылку своего профиля, отправить на фишинговый сайт.
Отравление для сброса пароля может произойти, если хакер использует заголовок вредоносных хостов при заполнении формы сброса пароля для другого пользователя. Затем этот пользователь получит электронное письмо со ссылкой для сброса пароля, ведущей на фишинговый сайт.
Вот еще несколько вредоносных примеров
Дополнительные предостережения и примечания:
- Когда usecanonicalname отключен,
$_SERVER['SERVER_NAME']
он заполняется тем же заголовком, $_SERVER['HTTP_HOST']
который использовался бы в любом случае (плюс порт). Это настройка Apache по умолчанию. Если вы или DevOps включите это, то с вами все в порядке, но действительно ли вы хотите полагаться на отдельную команду или на себя через три года в будущем, чтобы сохранить то, что может показаться второстепенной конфигурацией. -значение по умолчанию? Несмотря на то, что это обеспечивает безопасность, я бы не стал полагаться на эту установку.
- Redhat, однако, по умолчанию включает usecanonical [ источник ].
- Если serverAlias используется в записи виртуальных хостов и запрашивается домен с псевдонимом,
$_SERVER['SERVER_NAME']
не будет возвращен текущий домен, но будет возвращено значение директивы serverName.
- Если serverName не может быть разрешен, вместо него используется команда hostname операционной системы [источник] .
- Если не указать заголовок хоста, сервер будет вести себя так, как если бы usecanonical был на [источник] .
- Наконец, я просто попытался использовать это на своем локальном сервере и не смог подделать заголовок хоста. Я не уверен, было ли обновление Apache для решения этой проблемы, или я просто делал что-то не так. Тем не менее, этот заголовок по-прежнему может использоваться в средах, где виртуальные хосты не используются.
Маленький Рент:
Этот вопрос получил сотни тысяч просмотров без единого упоминания о существующих проблемах безопасности! Так быть не должно, но то, что ответ на вопрос о переполнении стека популярен, не означает, что он безопасен.