Hero Image

Лучшие практики по настройке заголовков Referer и Referrer-Policy

Лучшие практики по настройке заголовков Referer и Referrer-Policy

Лучшие практики по настройке заголовка ответа Referrer-Policy и использования реферера во входящих запросах.

Updated
Appears in: Safe and secure

Резюме #

  • Неожиданная утечка информации при запросах на другой источник препятствует конфиденциальности пользователей в Интернете. Здесь может помочь защитная политика реферера.
  • Рассмотрите возможность установки политики реферера strict-origin-when-cross-origin. Она сохраняет большую часть полезности реферера, одновременно снижая риск утечки данных при запросах на другой источник.
  • Не используйте рефереры для защиты от подделки межсайтовых запросов (CSRF). Вместо этого используйте токены CSRF и другие заголовки в качестве дополнительного уровня безопасности.

Прежде чем мы начнем:

  • Если вы не уверены в разнице между «сайтом» и «источником», ознакомьтесь со статьей «Понимание "same-site" и "same-origin"».
  • В Referer отсутствует буква R из-за неправильного написания в спецификации. Заголовок Referrer-Policy и referrer в JavaScript и DOM написаны правильно.

Кратко о заголовках Referer и Referrer-Policy #

HTTP-запросы могут включать необязательный заголовок Referer, указывающий источник или URL-адрес веб-страницы, с которой был сделан запрос. Заголовок Referrer-Policy определяет, какие данные будут доступны в заголовке Referer

В приведенном ниже примере заголовок Referer включает полный URL-адрес страницы на сайте site-one, с которого был сделан запрос.

HTTP-запрос, включая заголовок Referer

Заголовок Referer может присутствовать в разных типах запросов:

  • запросы навигации, когда пользователь нажимает ссылку;
  • запросы подресурсов, когда браузер запрашивает изображения, плавающие фреймы, скрипты и другие ресурсы, которые необходимы странице.

Что касается навигации и плавающих фреймов, к этим данным также можно получить доступ через JavaScript с помощью document.referrer.

Значение Referer может быть полезным. Например, служба аналитики может использовать это значение, чтобы определить, что 50% посетителей на site-two.example пришли из social-network.example.

Но когда полный URL-адрес, включая путь и строку запроса, отправляется в Referer при запросах на другие источники, это может нарушать конфиденциальность и создавать риски для безопасности. Взгляните на эти URL-адреса:

URL-адреса с путями, сопоставленными с различными угрозами конфиденциальности и безопасности.

URL-адреса с №1 по №5 содержат личную информацию, иногда даже идентифицирующую или конфиденциальную. Незаметная утечка данных при запросах на другие источники может поставить под угрозу конфиденциальность пользователей в Интернете.

URL № 6это возможность URL. Вы не хотите, чтобы пароль попал в руки кого-либо, кроме предполагаемого пользователя. Если это произойдет, злоумышленник может завладеть учетной записью этого пользователя.

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

Какие политики доступны и чем они отличаются? #

Вы можете выбрать одну из восьми политик. В зависимости от политики данные, из заголовка Refererdocument.referrer) могут быть доступны следующие данные:

  • нет данных (Referer отсутствует);
  • только источник;
  • полный URL-адрес: источник, путь и строка запроса.
Данные, которые могут содержаться в заголовке Referer и document.referrer.

Некоторые политики разработаны так, чтобы вести себя по-разному в зависимости от контекста: запрос на другой источник или в пределах текущего источника, безопасность, или и то, и другое (независимо от того, отправляется ли запрос из более безопасного протокола в менее безопасный). Это полезно для ограничения объема информации, передаваемой из разных источников, или для менее безопасных источниковпри сохранении разнообразия рефереров на вашем собственном сайте.

Вот обзор, показывающий, как политики реферера ограничивают данные URL, доступные из заголовка Referer и document.referrer:

Различные политики рефереров и их поведение в зависимости от протокола безопасности и контекста разных источников.

MDN предоставляет полный список политик и примеров поведения.

На заметку:

  • Все политики, которые принимают во внимание схему (HTTPS или HTTP) (strict-origin, no-referrer-when-downgrade и strict-origin-when-cross-origin), обрабатывают запросы от источника HTTP к другому источнику HTTP одинаково как запросы от источника HTTPS к другому источнику HTTPS, даже если HTTP менее безопасен. Это потому, что для этих политик имеет значение, имеет ли место понижение уровня безопасности, то есть может ли запрос предоставить данные из зашифрованного источника в незашифрованный. HTTP → HTTP-запрос всё время не зашифрован, поэтому понижения уровня безопасности не происходит. HTTPS → HTTP-запросы, напротив, представляют собой понижение уровня безопасности.
  • При запросе в пределах одинакового источника схема (HTTPS или HTTP) не меняется; следовательно, понижения уровня безопасности не происходит.

Политики реферера по умолчанию в браузерах #

По состоянию на июль 2020 г.

Если политика реферера не задана, будет использоваться политика браузера по умолчанию.

БраузерПолитика Referrer-Policy умолчанию / Поведение
ChromeПланируется переход на strict-origin-when-cross-origin в версии 85 (ранее no-referrer-when-downgrade)
Fire Fox
  • strict-origin-when-cross-origin (см. закрытую ошибку)
  • strict-origin-when-cross-origin в режиме конфиденциального просмотра и для трекеров
Edge
SafariПолитика, подобная strict-origin-when-cross-origin. Подробности см. в публикации «Предотвращение отслеживания».

Настройка политики реферера: лучшие практики #

Objective: Явно установите политику для повышения конфиденциальности, например, strict-origin-when-cross-origin (или более строгую).

Есть разные способы установить политики реферера для вашего сайта:

  • как заголовок HTTP;
  • в вашем HTML-коде;
  • из JavaScript по запросу.

Вы можете установить разные политики для разных страниц, запросов или элементов.

HTTP-заголовок и метаданные относятся к уровню страницы. Порядок приоритета при определении эффективной политики элемента:

  1. Политика на уровне элементов.
  2. Политика на уровне страницы.
  3. Браузер по умолчанию.

Пример:

index.html:

<meta name="referrer" content="strict-origin-when-cross-origin" />
<img src="..." referrerpolicy="no-referrer-when-downgrade" />

Изображение будет запрошено с политикой no-referrer-when-downgrade, в то время как все остальные запросы подресурсов с этой страницы будут следовать политике strict-origin-when-cross-origin.

Как посмотреть политику реферера? #

Сайт securityheaders.com помогает определить политику, которую использует конкретный сайт или страница.

Вы также можете использовать инструменты разработчика Chrome, Edge или Firefox, чтобы увидеть политику реферера, используемую для конкретного запроса. На момент написания этой статьи Safari не показывает Referrer-Policy, но показывает отправленный заголовок Referer.

Скриншот панели Network в Chrome DevTools с заголовками Referer и Referrer-Policy.
Chrome DevTools, панель Network с выбранным запросом.

Какую политику вы должны установить для своего веб-сайта? #

Резюме: явно установите политику для повышения конфиденциальности, например, strict-origin-when-cross-origin (или более строгую).

Почему «явно»? #

Если политика реферера не задана, будет использоваться политика браузера по умолчаниюфактически, веб-сайты часто подчиняются политике браузера по умолчанию. Но это не самый лучший вариант, потому что:

  • Политики браузеров по умолчанию либо no-referrer-when-downgrade, strict-origin-when-cross-origin, либо более строгиев зависимости от браузера и режима (конфиденциального просмотра или инкогнито). Таким образом, ваш сайт не будет вести себя предсказуемо в разных браузерах.
  • Браузеры принимают более строгие настройки по умолчанию, такие как strict-origin-when-cross-origin и такие механизмы, как referrer trimming для запросов на другой источник. Явный выбор политики повышения конфиденциальности до изменения стандартных настроек браузера дает вам контроль над ситуацией и помогает проводить тесты по своему усмотрению.

Почему strict-origin-when-cross-origin (или более строгая политика)? #

Вам нужна безопасная, обеспечивающая конфиденциальность и полезная политикачто вы подразумеваете под «полезной», зависит от того, что вы хотите от реферера:

  • Безопасность: если ваш веб-сайт использует HTTPS (если нет, сделайте эту задачу приоритетной), вы не хотите, чтобы URL-адреса вашего веб-сайта просачивались в запросы, отличные от HTTPS. Поскольку любой в сети может их видеть, это подвергнет ваших пользователей атакам типа «человек посередине». Политики no-referrer-when-downgrade, strict-origin-when-cross-origin, no-referrer и strict-origin решают эту проблему.
  • Повышение конфиденциальности: при запросах на другие источники no-referrer-when-downgrade передает полный URL-адресэто не способствует повышению конфиденциальности. Политики strict-origin-when-cross-origin и strict-origin отправляют только источник, а no-referrer вообще ничего не отправляет. Это оставляет вам политики strict-origin-when-cross-origin, strict-origin и no-referrer в качестве вариантов повышения конфиденциальности.
  • Польза: no-referrer и strict-origin никогда не отправляют полный URL-адрес, даже для запросов в пределах одного и того же источника, поэтому если вам это нужно, strict-origin-when-cross-originлучший вариант.

Всё это означает, что strict-origin-when-cross-origin, как правило, является разумным выбором.

Пример: установка политики strict-origin-when-cross-origin

index.html:

<meta name="referrer" content="strict-origin-when-cross-origin" />

Или на стороне сервера, например в Express:

const helmet = require('helmet');
app.use(helmet.referrerPolicy({policy: 'strict-origin-when-cross-origin'}));

Что если политика strict-origin-when-cross-origin (или более строгая) не подходит для всех ваших вариантов использования? #

В этом случае используйте прогрессивный подход: установите для вашего веб-сайта политику защиты, такую как strict-origin-when-cross-origin и, если необходимо, менее строгую политику для определенных запросов или элементов HTML.

Пример: политика на уровне элементов #

index.html :

<head>
<!-- document-level policy: strict-origin-when-cross-origin -->
<meta name="referrer" content="strict-origin-when-cross-origin" />
<head>
<body>
<!-- policy on this <a> element: no-referrer-when-downgrade -->
<a src="" href="" referrerpolicy="no-referrer-when-downgrade"></a>
<body></body>
</body>
</head>
</head>

Обратите внимание, что Safari/WebKit может ограничивать заголовок document.referrer или Referer для межсайтовых запросов. Смотрите подробности.

Пример: политика на уровне запроса #

script.js :

fetch(url, {referrerPolicy: 'no-referrer-when-downgrade'});

Что ещё нужно учесть? #

Выбор политики должен определяться вашим веб-сайтом и вариантами использованиярешаете вы, ваша команда и ваша компания. Если некоторые URL-адреса содержат идентифицирующие или конфиденциальные данные, установите политику защиты.

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

Использование реферера из входящих запросов: лучшие практики #

Что делать, если функционал вашего сайта использует URL-адрес реферера из входящих запросов? #

Защитите данные пользователей #

Заголовок Referer может содержать конфиденциальные, личные или идентифицирующие данные, поэтому убедитесь, что вы относитесь к ним как к таковым.

Имейте в виду, что получаемый вами заголовок Referer может измениться #

Использование реферера из входящих запросов на другие источники имеет ряд ограничений:

  • Если у вас нет контроля над реализацией отправителя запросов, вы не можете делать предположения о заголовке Refererdocument.referrer), который вы получаете. Отправитель запроса может в любой момент решить перейти на политику no-referrer или на более строгую политику, чем предыдущая,это означает, что вы получите меньше данных через Referer, чем раньше.
  • Браузеры всё чаще используют для Referrer-Policy значение по умолчанию strict-origin-when-cross-origin. Это означает, что теперь вы можете получать только источник (вместо полного URL-адреса реферера) во входящих запросах на другие источники, если сайт, который их отправляет, не имеет установленной политики.
  • Браузеры могут изменить способ управления Referer; например, в будущем они могут решить всегда обрезать рефереры до источников в запросах подресурсов на другие источники, чтобы защитить конфиденциальность пользователей.
  • Refererdocument.referrer) может содержать больше данных, чем вам нужно, например полный URL-адрес, когда вы хотите только узнать, поступил ли запрос из другого источника.

Альтернативы Referer #

Возможно, вам придется рассмотреть альтернативы, если:

  • Важный функционал вашего сайта использует URL-адрес реферера из входящих запросов на другие источники;
  • И/или если ваш сайт больше не получает ту часть URL-адреса реферера, которая ему нужна в запросе на другой источник. Это происходит, когда отправитель запросов изменил свою политику или когда у них не задана политика, а политика браузера по умолчанию изменилась (как в Chrome 85).

Чтобы определить альтернативы, сначала проанализируйте, какую часть реферера вы используете.

Если вам нужен только источник ( https://site-one.example ):

  • Если вы используете реферер в скрипте, который имеет доступ к странице верхнего уровня, альтернативой является window.location.origin.
  • Если возможно, используйте такие заголовки, как Origin и Sec-Fetch-Site, они дадут Origin или ответ, поступил ли запрос из другого источника. Возможно, именно это вам и нужно.

Если вам нужны другие элементы URL (путь, параметры запроса…):

  • Параметры запроса могут относиться к вашему варианту использования, и это избавляет вас от работы по синтаксическому анализу реферера.
  • Если вы используете реферер в скрипте, который имеет доступ к странице верхнего уровня, альтернативой может быть window.location.pathname Извлеките только раздел пути URL-адреса и передайте его в качестве аргумента, чтобы любая потенциально конфиденциальная информация в параметрах URL-адреса не передавалась.

Если вы не можете использовать эти альтернативы:

  • Проверьте, можно ли изменить ваши системы таким образом, чтобы они ожидали от отправителя запроса (site-one.example) явного задания нужной вам информации в какой-либо конфигурации. Плюсы: более явный, более конфиденциальный для пользователей site-one.example с ориентацией на будущее. Минусы: потенциально большой объем работы с вашей стороны или со стороны пользователей вашей системы.
  • Проверьте, может ли сайт, который отправляет запросы, согласиться установить политику no-referrer-when-downgrade. Минусы: потенциально менее конфиденциальная политика для пользователей site-one.example; может поддерживаться не во всех браузерах.

Защита от подделки межсайтовых запросов (CSRF) #

Обратите внимание, что отправитель запроса всегда может решить не отправлять реферер, установив no-referrer (а злоумышленник может даже подделать реферер).

Используйте токены CSRF в качестве основной защиты. Для дополнительной защиты используйте SameSite, а вместо Refererзаголовки, такие как Origin (доступно в запросах POST и CORS) и Sec-Fetch-Site (если доступно).

Логирование #

Обязательно защитите личные или конфиденциальные данные пользователей, которые могут находиться в Referer.

Если вы используете только источник, проверьте, может ли заголовок Origin применяться в качестве альтернативы. Этот заголовок может дать вам информацию для отладки более простым способом и без необходимости синтаксического анализа реферера.

Платежи #

Платежные сервисы могут полагаться на заголовок Referer входящих запросов для проверок безопасности.

Например:

  • Пользователь нажимает кнопку Купить на online-shop.example/cart/checkout.
  • online-shop.example перенаправляет на payment-provider.example для проведения транзакцим.
  • payment-provider.example проверяет Referer этого запроса на соответствие списку допустимых Referer, установленных продавцами. Если заголовок не соответствует ни одной записи в списке, payment-provider.example отклоняет запрос. Если соответствует, продолжается обработка транзакции пользователя.

Рекомендации по проверке безопасности потока платежей #

Резюме: как платежный сервис вы можете использовать Referer в качестве базовой проверки против простых атак, но вам совершенно необходимо иметь другой, более надежный метод проверки.

Сам по себе заголовок Referer не является надежной основой для проверки: запрашивающий сайт, независимо от того, является ли он легитимным продавцом или нет, может установить политику no-referrer, которая сделает информацию Referer недоступной для платежного сервиса. Но просмотр Referer может помочь вам поймать наивных злоумышленников, которые не установили политику no-referrer. Поэтому вы можете решить использовать Referer в качестве первой базовой проверки. Если вы сделаете это:

  • Не ждите, что Referer всегда будет присутствовать; и если он присутствует, проверяйте только те данные, которые он минимально будет включать: источник. При задании списка разрешенных значений Referer убедитесь, что в него не включен путь, а только источник. Пример: допустимые значения Referer online-shop.example должны быть online-shop.example, а не online-shop.example/cart/checkout. Почему? Поскольку, ожидая либо отсутствия Referer вообще, либо значение Referer, которое является источником запрашивающего веб-сайта, вы предотвращаете непредвиденные ошибки, поскольку вы не делаете предположений о политике Referrer-Policy реферера, установленной вашим продавцом, или о поведении браузера, если у продавца нет установленной политики. И сайт, и браузер могут обрезать Referer отправленный во входящем запросе, только до источника или не отправлять Referer вообще.
  • Если заголовок Referer отсутствует или если он присутствует и ваша базовая проверка заголовка Referer прошла успешно: вы можете перейти к другому, более надежному методу проверки (см. ниже).

Какой метод проверки более надежен?

Один из надежных методов проверкипозволить инициатору запроса хешировать параметры запроса вместе с уникальным ключом. Как платежный сервис, вы можете рассчитать тот же хеш на своей стороне и принять запрос только в том случае, если хеш соответствует вашим расчетам.

Что происходит с Referer, когда торговый сайт HTTP без политики реферера перенаправляет на платежный сервис HTTPS?

Заголовок Referer не будет отображаться в запросе к платежному сервису HTTPS, поскольку большинство браузеров по умолчанию используют strict-origin-when-cross-origin или no-referrer-when-downgrade, если для веб-сайта не задана политика. Также обратите внимание, что переход Chrome на новую политику по умолчанию не изменит этого поведения.

Если ваш веб-сайт использует HTTP, перейдите на HTTPS.

Заключение #

Защитная политика реферераотличный способ предоставить вашим пользователям больше конфиденциальности.

Чтобы узнать больше о различных методах защиты ваших пользователей, ознакомьтесь с коллекцией Safe and secure от web.dev!

Большое спасибо за вклад и отзывы всем рецензентам, особенно Каустубхе Говинду, Дэвиду Ван Кливу, Майку Уэсту, Сэму Даттону, Роуэну Меревуду, Джеку Баски и Кейси Баски.

Ресурсы #

Last updated: Improve article