HTTP Strict Transport Security (HSTS, хотя согласно RFC – просто STS) – заголовок столь же «раскрученный», сколь и переоцененный. Этот заголовок говорит агенту пользователя, что к отправившему его сайту следует обращаться только на «Вы» и шепотом по защищенному HTTP – HTTPS. Говорит уже после того, как к сайту обратились, причем именно по HTTPS.

Если же агент зашел на сайт по HTTP, то цитирую RFC: UA must ignore any present STS header field(s). То есть, если агент получил ответ от сайта по HTTP, он должен проигнорировать заголовок HSTS и продолжать общаться по незащищенному протоколу (если его принудительно не переключат на защищенный, но тогда какой смысл посылать заголовок?)

Чтоб понять этот смысл, давайте вспомним, что соответствующий RFC приняли в 2012 году, а разрабатывать начали не позже 2008, когда HTTPS еще не был обязательным крайне желательным, создавал дополнительную нагрузку на веб-сервер, стоил совсем других денег (спасибо тебе, Let's Encrypt!), а клиенты могли не уметь в HTTPS и на них не показывали пальцем.

Заголовок объяснял клиентам две вещи:

  1. Раз уж они однажды зашли на сайт по HTTPS, впредь следует поступать так же, даже если по HTTP сайт тоже доступен.
  2. Все, что они хотят загрузить с этого сайта по HTTP, требуется загружать по HTTPS, д��же если протокол не указан или указан незащищенный протокол (и куки тоже, даже если не установлен флаг Secure).

Опциональная директива includeSubDomains требовала, чтобы тот же подход применялся и к субдоменам: только HTTPS, только хардкор!

Таким образом, сегодня, на сайте, который поддерживает только HTTPS (принудительно переключает на него с HTTP средствами сервера), единственный практический смысл этого заголовка в переопределении поведения клиента при ошибке защищенного соединения. Обычное поведение – сообщить об ошибке и предложить пользователю выбор: убежать без оглядки или проигнорировать просроченный/самоподписанный/левый TLS-сертификат и прочие подобные «мелочи». Заголовок HSTS говорит клиенту, что он должен разорвать соединение и не устанавливать его «до устранения», даже если пользователь не против поэкспериментировать.

HSTS позволяет также слегка ускорить загрузку с сайта и снизить нагрузку на сервер, преобразуя еще на стороне клиента URI с http:// в URI с https:// и, тем самым, избавляя сервер от нелепых телодвижений с отдачей кода состояния HTTP 301 Moved Permanently, но это уже история про производительность, а не безопасность.

И, наконец, если HTTPS на сайте почему-то отвалился и сервер начал общаться с клиентами по HTTP, заголовок HSTS поможет админу быстрее получить фидбек от пользователей: а-а-а, сайт недоступен!

Чтоб два раза не вставать, упомяну и проталкиваемую Google нестандартную директиву Preload. Директива, внезапно, предназначена не для агента пользователя, а исключительно для специализированного бота Google, поддерживающей реестр доменов, к которым следует обращаться только по HTTPS. Если админ вручную добавил свой домен в реестр Google, бот компании проверит правомочность добавления по наличию директивы Preload в заголовках, отдаваемых с соответствующего веб-сервера, и тогда агенты пользователя, полагающиеся на этот реестр, будут даже первый запрос к внесенным в него сайтам посылать по HTTPS.

Вроде как хуже не будет, если заранее не прочесть disclaimer Корпорации Бобра: preload list domain removal may take 6-12 weeks to reach most Chrome users, and may take longer for other browsers. Вольный перевод: если вам понадобится (временно) отключить HTTPS на своем сайте, то без директивы Preload вы это можете сделать за секунду и пользователи даже ничего не заметят (кроме смены префикса с https:// на http:// в адресной строке), а с директивой – подождите, пока Google рассмотрит вашу заявку, иначе посетители будут долбиться по HTTPS и получать от ворот поворот, т.к. Google сказала им, что по HTTP на этот сайт – нельзя.

Впрочем, подобную проблему вы можете создать себе сами, без помощи Google, если последуете распространенной рекомендации устанавливать время действия заголовка HSTS в «минимум год». Напоминаю: принудительный HTTPS здорового человека обеспечивается не с помощью этого заголовка, который не для того предназначен, а средствами веб-сервера.

Резюме


  1. Если сайт отдается только по HTTPS (как и должно быть сегодня), наличие заголовка HSTS не добавит ему безопасности от слова совсем.
  2. Если на сайте случатся проблемы с HTTPS, заголовок поможет админу быстрее узнать о них и (возможно, частично) нивелировать их негативные последствия.
  3. Если сайт отдается и по HTTP, и по HTTPS, заголовок ничего не даст клиентам, подключившимся по незащищенному HTTP, но позволит остальным избежать mixed security context.

P.S.: в рамках проекта «Монитор госсайтов» мы обнаруживаем на исследуемых сайтах госорганов заголовок HSTS примерно в 1% случаев, причем едва ли не в половине из них этот заголовок передается с ошибками.