Перейти к содержанию

Доверенный хост для ссылок в письмах

Если в админке вы видели предупреждение вроде:

Email links are not yet pinned to a trusted host.

то эта страница объясняет, что оно значит, почему это важно и какую одну небольшую настройку нужно изменить, чтобы его убрать. Это рекомендация по усилению защиты, а не признак того, что ваш сайт взломали.

Что означает предупреждение

Когда Grav отправляет письмо для сброса пароля, активации учётной записи или входа по ссылке, ему нужно вставить в ссылку полный веб-адрес, например https://www.example.com/reset/.... Чтобы построить этот адрес, Grav должен знать имя хоста вашего сайта (www.example.com).

Если вы не сообщили Grav, какое у него имя хоста, он читает заголовок Host из входящего веб-запроса. Этот заголовок отправляет браузер посетителя, и злоумышленник может подставить в него что угодно.

Поэтому если атакующий запросит сброс пароля для одного из ваших пользователей и отправит поддельный заголовок Host, ссылка сброса в письме может указывать на похожий фишинговый сайт вместо вашего. Если пользователь перейдёт по ней и атакующий перехватит одноразовый токен, он сможет захватить учётную запись. Это отслеживается как GHSA-46jp-rc59-w2gc.

Предупреждение просто означает: вы ещё не привязали эти ссылки в письмах к доверенному хосту, поэтому Grav использует хост запроса как резервное значение.

Как исправить

Скажите Grav, какой хост использовать. Достаточно одного из двух вариантов ниже. Любой из них привязывает все ссылки в письмах безопасности к этому хосту и убирает предупреждение.

Вариант 1: Custom Base URL (рекомендуется)

Это самый широкий способ. Он задаёт доверенный базовый адрес для всего сайта, а не только для писем, поэтому заодно делает согласованными и другие абсолютные ссылки.

В админке перейдите в Configuration → System → Advanced → Custom Base URL и укажите полный адрес сайта, например:

https://www.example.com

Или задайте его напрямую в user/config/system.yaml:

custom_base_url: 'https://www.example.com'

Вариант 2: Site Host в плагине Login

Если вы хотите привязать только ссылки в письмах и не трогать всё остальное, используйте собственную настройку плагина Login.

В админке перейдите в Plugins → Login → Site Host и укажите полный адрес сайта, например:

https://www.example.com

Или задайте его напрямую в user/config/plugins/login.yaml:

site_host: 'https://www.example.com'

Примечание

Если один и тот же сайт доступен по нескольким адресам (например, домен для тестирования и домен рабочей версии или несколько языков на разных доменах), выберите канонический публичный адрес, который пользователи всегда должны видеть в своих письмах.

Отказ от отправки, когда хост не задан

Для сайтов, где безопасность учётных записей критична, плагин Login может пойти дальше и отказаться отправлять письма сброса пароля, если доверенный хост не настроен, вместо того чтобы использовать хост запроса.

Включите Plugins → Login → Require Trusted Host или задайте в user/config/plugins/login.yaml:

require_trusted_host: true

С этой настройкой неправильно настроенный сайт безопасно откажет (письмо не будет отправлено), а не отправит потенциально подделываемую ссылку.

Эшелонированная защита: проверка хоста на веб-сервере

Custom Base URL исправляет ссылки в письмах, но полезно также отклонять поддельные заголовки Host на веб-сервере, прежде чем они дойдут до Grav. Тогда все части вашего стека будут согласны в том, какие имена хостов допустимы.

Примеры ниже отклоняют любой запрос, заголовок Host которого не входит в ожидаемые.

Apache

В виртуальном хосте или .htaccess разрешите только известные хосты:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www\.example\.com|example\.com)$ [NC]
RewriteRule ^ - [F]

Ещё лучше задать явные ServerName и ServerAlias в виртуальном хосте и позволить Apache обслуживать неизвестные хосты из отдельного виртуального хоста по умолчанию, который возвращает ошибку.

Nginx

Задайте реальному блоку server точный server_name, затем добавьте общий блок по умолчанию, отклоняющий всё остальное:

server {
    listen 80 default_server;
    server_name _;
    return 444;            # закрыть соединение для неизвестного хоста
}

server {
    listen 80;
    server_name www.example.com example.com;
    # ... ваша обычная конфигурация Grav ...
}

Caddy

Caddy отвечает только на имена хостов, перечисленные в блоке сайта, поэтому точный адрес уже отклоняет поддельные хосты:

www.example.com, example.com {
    root * /var/www/grav
    php_fastcgi unix//run/php/php-fpm.sock
    file_server
}

За прокси или CDN

Если Grav работает за балансировщиком нагрузки, обратным прокси или CDN (например, Cloudflare), убедитесь, что прокси передаёт настоящий проверенный хост, а Grav настроен ему доверять. См. параметры reverse_proxy_setup и http_x_forwarded в разделе Конфигурация Grav.

Как убедиться, что проблема решена

После сохранения Custom Base URL или Site Host предупреждение в админке исчезает при следующей загрузке страницы. Можно также отправить себе письмо сброса пароля и убедиться, что ссылка в нём указывает на ваш настоящий домен.