пятница, 27 июля 2018 г.

Заголовок сообщения Referrer Policy

Это перевод статьи «A new security header: Referrer Policy» Scott Helme, публикуется с разрешения автора. ©

Рекомендую прокачивать английский и использовать оригинал. В конце концов, из меня такой себе переводчик, своими словами перескажу.

Также статью можно прочитать в конфлюенсе — там есть оглавление и таблички отображаются лучше, чем в блоггере.

Если включить в браузере F12 и отследить любой запрос, в разделе «Основные заголовки» (Headers — General) мы увидим некий Referrer Policy. Вот с ним и будем разбираться.


Чтобы получить скриншот как на картинке:
  1. Откройте http://users.bugred.ru
  2. Включите F12, вкладку Network
  3. В самой системе переключитесь на другую страницу (внизу списка пользователей есть пагинация)
  4. Найдите этот запрос и изучите заголовки.
Это небольшое вступление от меня, а дальше уже текст автора. Свои вставки буду выделять курсивом.

Заголовок Referrer Policy позволяет сайту контролировать значение заголовка Referer для ссылок, ведущих с вашей страницы.


Что такое Referer?

Когда пользователь переходит с одного сайта на другой, второй сайт сохраняет информацию «откуда ко мне пришли». Благодаря этому мы получаем всякие метрики типа Яндекс.Метрики или Google Analytics. И именно благодаря этой информации мы узнаем, откуда к нам приходит трафик. Вот, например, Скотт точно знает, что к нему на сайт за неделю 4000 человек пришло именно из Твиттера. Это видно из заголовка Referer:

Request Headers:...Host: scotthelme.co.ukReferer: https://twitter.com/Scott_Helme/status/760790725776830464Upgrade-Insecure-Requests: 1....

А вот так выглядит трафик в моем блоге за неделю. И эта информация также собирается из заголовка Referer:




Заголовок Referer позволяет понять, откуда к нам пришли пользователи, и это очень удобная фича. Особенно для маркетинга — стоит ли оплачивать рекламу в ФБ, ВК, Яндексе? Это недешево стоит, а оценить выхлоп можно благодаря заголовку. Вложились в рекламу и следим, сколько покупателей пришло в магазин. Так и делаем выводы, окупилась реклама или это деньги «в никуда».

Но бывают случаи, когда мы не хотим показывать информацию в этом заголовке. Или контролировать то, что там отображается. И вот как раз для этого нужен заголовок Referrer Policy.


Заголовок Referrer Policy


Официальная информация по заголовку опубликована 26 января 2017 года, найти ее можно на сайте W3C Candidate Recommendation. Но автор решил вынести ее в свой блог, а я — в свой. Так удобнее, когда ты сам контролируешь свои статьи и не зависишь от сломавшихся ссылок. А еще у Скотта описание более понятное благодаря примерам. Именно поэтому я перевожу его статью, а не официальную документацию.

Referrer Policy — это HTTP response header, заголовок ответа. Он может содержать одно из следующих значений:

enum ReferrerPolicy {
"",
"no-referrer",
"no-referrer-when-downgrade",
"same-origin",
"origin",
"strict-origin",
"origin-when-cross-origin",
"strict-origin-when-cross-origin",
"unsafe-url"
};

Ниже я объясню каждый вариант, что именно он делает.


пустая строка


Пустая строка в заголовке Referrer Policy означает, что сайт не хочет устанавливать значение заголовка, и браузеру придется сделать это самому. Браузер может выбрать заголовок на основании, например, <meta> элемента в HTML, или атрибута referrerpolicy на элементах типа <a> и <link> (ссылочные теги в HTML), или на ключе rel="noreferrer" на элементе <a>. Использования пустую строку, вы никакого воздействия на Referer сами не делаете, оставляя все на откуп сайта.


no-referrer


Значение no-referrer говорит браузеру никогда не слать заголовок referer для запросов с твоего сайта. Это касается как ссылок на внешние ресурсы, так и на другие страницы своего сайта. Полная анонимность.


Source (откуда ссылка)Destination (куда)Referrer (значение заголовка)
https://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/NULL
https://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/NULL
http://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/NULL
http://scotthelme.co.uk/blog1/http://example.comNULL
http://scotthelme.co.uk/blog1/https://example.comNULL
https://scotthelme.co.uk/blog1/http://example.comNULL


Если вы не видите отличий между ссылками, то обратите внимание на разницу HTTP и HTTPS. Автор показывает, что нет разницы, переходим мы с защищенного ресурса или нет. В других значениях заголовка эта разница будет


no-referrer-when-downgrade


Браузер НЕ будет отправлять значение referer при переходе с HTTPS на HTTP, но отправит полную ссылку при переходе с HTTP куда-то еще.

Тут не важно, отличаются ли source и destination, или ведут на один и тот же сайт (кросс-ссылки внутри сайта)

Source (откуда ссылка)Destination (куда)Referrer (значение заголовка)
https://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/NULL
https://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/https://scotthelme.co.uk/blog1/
http://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/http://scotthelme.co.uk/blog1/
http://scotthelme.co.uk/blog1/http://example.comhttp://scotthelme.co.uk/blog1/
http://scotthelme.co.uk/blog1/https://example.comhttp://scotthelme.co.uk/blog1/
https://scotthelme.co.uk/blog1/http://example.comNULL

same-origin


Браузер отправляет значение referer только в том случае, если ссылка ведет на тот же сайт. В любом другом случае значение будет пустое

Source (откуда ссылка)Destination (куда)Referrer (значение заголовка)
https://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/https://scotthelme.co.uk/blog1/
https://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/NULL
https://scotthelme.co.uk/blog1/http://example.comNULL
https://scotthelme.co.uk/blog1/https://example.comNULL

origin


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

Source (откуда ссылка)Destination (куда)Referrer (значение заголовка)
https://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/https://scotthelme.co.uk/
https://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/https://scotthelme.co.uk/
https://scotthelme.co.uk/blog1/http://example.comhttps://scotthelme.co.uk/


strict-origin


Аналогично origin, но данный заголовок запрещает слать информацию на HTTP, только на защищенные ссылки: HTTPS

Source (откуда ссылка)Destination (куда)Referrer (значение заголовка)
https://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/https://scotthelme.co.uk/
https://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/NULL
https://scotthelme.co.uk/blog1/http://example.comNULL
http://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/http://scotthelme.co.uk/
http://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/http://scotthelme.co.uk/
http://scotthelme.co.uk/blog1/http://example.comhttp://scotthelme.co.uk/


origin-when-cross-origin


Браузер отправляет полный URL на тот же сайт, и неполный (только название) на все остальные

Source (откуда ссылка)Destination (куда)Referrer (значение заголовка)
https://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/https://scotthelme.co.uk/blog1/
https://scotthelme.co.uk/blog1/https://example.com/https://scotthelme.co.uk/
https://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/https://scotthelme.co.uk/
https://scotthelme.co.uk/blog1/http://example.com/https://scotthelme.co.uk/
http://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/http://scotthelme.co.uk/

strict-origin-when-cross-origin


Аналогично origin-when-cross-origin, но запрещает делать downgrade безопасности: отправляет пустоту, если пользователь переходит с HTTPS на HTTP

Source (откуда ссылка)Destination (куда)Referrer (значение заголовка)
https://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/https://scotthelme.co.uk/blog1/
https://scotthelme.co.uk/blog1/https://example.com/https://scotthelme.co.uk/
https://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/NULL
https://scotthelme.co.uk/blog1/http://example.com/NULL
http://scotthelme.co.uk/blog1/http://example.com/http://scotthelme.co.uk/

unsafe-url


Браузер всегда посылает полный URL, с любого сайта.

Source (откуда ссылка)Destination (куда)Referrer (значение заголовка)
https://scotthelme.co.uk/blog1/https://scotthelme.co.uk/blog2/https://scotthelme.co.uk/blog1/
https://scotthelme.co.uk/blog1/https://example.com/https://scotthelme.co.uk/blog1/
https://scotthelme.co.uk/blog1/http://scotthelme.co.uk/blog2/https://scotthelme.co.uk/blog1/
https://scotthelme.co.uk/blog1/http://example.com/https://scotthelme.co.uk/blog1/
http://scotthelme.co.uk/blog1/http://example.com/http://scotthelme.co.uk/

Рекомендации

Какой именно заголовок использовать — зависит от вашего желания или выставленных требований. Но от некоторых лучше держаться подальше. Например, автор не рекомендует использовать unsafe-url, который ничего не скрывает.

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

У самого автора нет ничего секретного в URL сайта, поэтому он предпочитает использовать no-referrer-when-downgrade, чисто для сохранности данных при переходе на HTTP.

К слову, потыкав разные сайты, включая https://www.google.com/, я заметила, что значение no-referrer-when-downgrade и правда самое популярное. Практически стандарт!

PS — статью эту я нашла, пока искала материал для курса «Тестирование REST API», переводила в помощь студентам.

4 комментария:

  1. Здесь написано https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
    Что origin-when-cross-origin
    Document Navigation to Referrer
    https://example.com/page.html http://example.com/page.html https://example.com/
    Не совсем так, как у вас

    ОтветитьУдалить
  2. Не смог сдержаться, чтобы просто поблагодарить за статью )
    Спасибо!
    Понравился перевод, дополненный своими замечаниями. Очень легко и складно читается, а свои комментарии - очень к месту и хорошо расширяют оригинал.

    ОтветитьУдалить