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

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

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

Email links are not yet pinned to a trusted host.

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

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

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

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

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

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

Исправление⚓︎

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

Вариант 1: пользовательский базовый URL (рекомендуется)⚓︎

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

В админке перейдите в Настройка → Система → Дополнительно → Пользовательский базовый URL и введите полный адрес вашего сайта, например:

https://www.example.com

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

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

Вариант 2: хост сайта в плагине Login⚓︎

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

В админке перейдите в Плагины → Login → Site Host и введите полный адрес вашего сайта, например:

https://www.example.com

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

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

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

Отказ от отправки при отсутствии хоста⚓︎

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

Включите Плагины → 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, затем добавьте catch-all по умолчанию, который отклоняет всё остальное:

server {
    listen 80 default_server;
    server_name _;
    return 444;            # close the connection on an unknown host
}

server {
    listen 80;
    server_name www.example.com example.com;
    # ... your normal Grav configuration ...
}

Caddy⚓︎

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

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 для соответствующих настроек.

Проверка исправления⚓︎

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