---
layout: post
title: "Лучшие практики по настройке заголовков \tReferer и Referrer-Policy"
subhead: Лучшие практики по настройке заголовка ответа Referrer-Policy и использования реферера во входящих запросах.
authors:
  - maudn
date: 2020-07-30
updated: 2020-09-23
hero: image/admin/kh2IMJFSJ3Cj6Zo8jEv5.jpg
thumbnail: image/admin/kh2IMJFSJ3Cj6Zo8jEv5.jpg
description: |
  Рассмотрите возможность установки политики реферера `strict-origin-when-cross-origin`. Она сохраняет большую часть полезности реферера, одновременно снижая риск утечки данных при запросах на другой источник.
tags:
  - blog
  - security
  - privacy
feedback:
  - api
---

## Резюме

- Неожиданная утечка информации при запросах на другой источник препятствует конфиденциальности пользователей в Интернете. Здесь может помочь защитная политика реферера.
- Рассмотрите возможность установки политики реферера `strict-origin-when-cross-origin`. Она сохраняет большую часть полезности реферера, одновременно снижая риск утечки данных при запросах на другой источник.
- Не используйте рефереры для защиты от подделки межсайтовых запросов (CSRF). Вместо этого используйте [токены CSRF](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#token-based-mitigation) и другие заголовки в качестве дополнительного уровня безопасности.

{% Aside %} Прежде чем мы начнем:

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

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

HTTP-запросы могут включать необязательный [заголовок `Referer`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Referer), указывающий источник или URL-адрес веб-страницы, с которой был сделан запрос. [Заголовок `Referrer-Policy`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy) определяет, какие данные будут доступны в заголовке `Referer`

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

<figure>{% Img src="image/admin/cXgqJfmD5OPdzqXl9RNt.jpg", alt="HTTP-запрос, включая заголовок Referer", width="800", height="573" %}</figure>

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

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

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

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

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

<figure>{% Img src="image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg", alt="URL-адреса с путями, сопоставленными с различными угрозами конфиденциальности и безопасности.", width="800", height="370" %}</figure>

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

URL № 6это [возможность URL](https://www.w3.org/TR/capability-urls/). Вы не хотите, чтобы пароль попал в руки кого-либо, кроме предполагаемого пользователя. Если это произойдет, злоумышленник может завладеть учетной записью этого пользователя.

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

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

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

- нет данных (`Referer` отсутствует);
- только [источник](/same-site-same-origin/#origin);
- полный URL-адрес: источник, путь и строка запроса.

<figure>{% Img src="image/admin/UR1U0HRP0BOF1e0XnyWA.jpg", alt="Данные, которые могут содержаться в заголовке Referer и document.referrer.", width="800", height="255" %}</figure>

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

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

<figure>{% Img src="image/admin/BIHWDY60CI317O7IzmQs.jpg", alt="Различные политики рефереров и их поведение в зависимости от протокола безопасности и контекста разных источников.", width="800", height="537" %}</figure>

MDN предоставляет [полный список политик и примеров поведения](https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy#Directives).

На заметку:

- Все политики, которые принимают во внимание схему (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 г.*

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

<div>
  <table>
    <thead>
      <tr>
        <th>Браузер</th>
        <th>Политика <code>Referrer-Policy</code> умолчанию / Поведение</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Chrome</td>
        <td>Планируется переход на <code>strict-origin-when-cross-origin</code> в <a href="https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default">версии 85</a> (ранее <code>no-referrer-when-downgrade</code>)</td>
      </tr>
      <tr>
        <td>Fire Fox</td>
        <td>
          <ul>
            <li>
<code>strict-origin-when-cross-origin</code> (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1589074">см. закрытую ошибку</a>)</li>
            <li>
<code>strict-origin-when-cross-origin</code> в режиме конфиденциального просмотра и для трекеров</li>
          </ul>
        </td>
      </tr>
      <tr>
        <td>Edge</td>
        <td>
          <ul>
            <li><code>no-referrer-when-downgrade</code></li>
            <li>
<a href="https://github.com/privacycg/proposals/issues/13">Идут эксперименты</a> со <code>strict-origin-when-cross-origin</code>
</li>
          </ul>
        </td>
      </tr>
      <tr>
        <td>Safari</td>
        <td>Политика, подобная <code>strict-origin-when-cross-origin</code>. Подробности см. в публикации <a href="https://webkit.org/blog/9661/preventing-tracking-prevention-tracking/">«Предотвращение отслеживания»</a>.</td>
      </tr>
    </tbody>
  </table>
</div>

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

{% Aside 'objective' %} Явно установите политику для повышения конфиденциальности, например, `strict-origin-when-cross-origin` (или более строгую). {% endAside %}

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

- как заголовок HTTP;
- в вашем [HTML](https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy#Integration_with_HTML)-коде;
- из JavaScript по [запросу](https://javascript.info/fetch-api#referrer-referrerpolicy).

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

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

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

**Пример:**

`index.html`:

```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](https://securityheaders.com/) помогает определить политику, которую использует конкретный сайт или страница.

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

<figure>{% Img src="image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg", alt="Скриншот панели Network в Chrome DevTools с заголовками Referer и Referrer-Policy.", width="800", height="416" %} <figcaption> Chrome DevTools, панель <b>Network</b> с выбранным запросом. </figcaption></figure>

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

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

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

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

- Политики браузеров по умолчанию либо `no-referrer-when-downgrade`, `strict-origin-when-cross-origin`, либо более строгиев зависимости от браузера и режима (конфиденциального просмотра или инкогнито). Таким образом, ваш сайт не будет вести себя предсказуемо в разных браузерах.
- Браузеры принимают более строгие настройки по умолчанию, такие как `strict-origin-when-cross-origin` и такие механизмы, как [referrer trimming](https://github.com/privacycg/proposals/issues/13) для запросов на другой источник. Явный выбор политики повышения конфиденциальности до изменения стандартных настроек браузера дает вам контроль над ситуацией и помогает проводить тесты по своему усмотрению.

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

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

- **Безопасность**: если ваш веб-сайт использует HTTPS ([если нет, сделайте эту задачу приоритетной](/why-https-matters/)), вы не хотите, чтобы 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`:

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

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

```javascript
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` :

```html/6
<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` [для межсайтовых](/same-site-same-origin/#same-site-cross-site) запросов. Смотрите [подробности](https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/).

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

`script.js` :

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

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

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

{% Aside 'warning' %} Данные, которые могут показаться вам не конфиденциальными, могут быть конфиденциальными для ваших пользователей. Другой вариантваши пользователи не ждут, что данные будут незаметно передавать при запросах на другие источники. {% endAside %}

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

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

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

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

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

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

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

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

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

- Важный функционал вашего сайта использует URL-адрес реферера из входящих запросов на другие источники;
- И/или если ваш сайт больше не получает ту часть URL-адреса реферера, которая ему нужна в запросе на другой источник. Это происходит, когда отправитель запросов изменил свою политику или когда у них не задана политика, а политика браузера по умолчанию изменилась (как в [Chrome 85](https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default)).

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

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

- Если вы используете реферер в скрипте, который имеет доступ к странице верхнего уровня, альтернативой является `window.location.origin`.
- Если возможно, используйте такие заголовки, как [`Origin`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Origin) и [`Sec-Fetch-Site`](https://developer.mozilla.org/docs/Web/HTTP/Headers/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 в](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#token-based-mitigation) качестве основной защиты. Для дополнительной защиты используйте [SameSite](/samesite-cookie-recipes/#%22unsafe%22-requests-across-sites), а вместо `Referer`заголовки, такие как [`Origin`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Origin) (доступно в запросах POST и CORS) и [`Sec-Fetch-Site`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Sec-Fetch-Site) (если доступно).

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

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

Если вы используете только источник, проверьте, может ли заголовок [`Origin`](https://developer.mozilla.org/docs/Web/HTTP/Headers/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, поскольку [большинство браузеров](#default-referrer-policies-in-browsers) по умолчанию используют `strict-origin-when-cross-origin` или `no-referrer-when-downgrade`, если для веб-сайта не задана политика. Также обратите внимание, что [переход Chrome на новую политику по умолчанию](https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default) не изменит этого поведения.

{% Aside %}

Если ваш веб-сайт использует HTTP, [перейдите на HTTPS](/why-https-matters/).

{% endAside %}

## Заключение

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

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

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

## Ресурсы

- [Понимание "same-site" и "same-origin"](/same-site-same-origin/).
- [Новый заголовок безопасности: политика реферера (2017)](https://scotthelme.co.uk/a-new-security-header-referrer-policy/).
- [Referrer-Policy на MDN](https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy).
- [Заголовок Referer: проблемы конфиденциальности и безопасности в MDN](https://developer.mozilla.org/docs/Web/Security/Referer_header:_privacy_and_security_concerns).
- [Изменение Chrome: намерение реализации на Blink](https://groups.google.com/a/chromium.org/d/msg/blink-dev/aBtuQUga1Tk/n4BLwof4DgAJ).
- [Изменение Chrome: намерение о запуске на Blink](https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/lqFuqwZDDR8).
- [Изменение Chrome: запись статуса](https://www.chromestatus.com/feature/6251880185331712).
- [Изменение Chrome: сообщение в блоге о бета-версии 85](https://blog.chromium.org/2020/07/chrome-85-upload-streaming-human.html).
- [Реферер обрезает поток GitHub: что делают разные браузеры](https://github.com/privacycg/proposals/issues/13).
- [Спецификация Referrer-Policy](https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-delivery).
