HTTPS (HTTP, зашифрованный с помощью SSL или TLS) — это важная часть мер по защите трафика на веб-сайте, которая значительно затрудняет перехват, изменение или подмену трафика между пользователем и сайтом.
Когда пользователь вводит вручную адрес домена без указания префиксов http:// или https:// или переходит по HTTP-ссылке, первый запрос к сайту отправляется в незашифрованном виде по протоколу HTTP. Большинство веб-серверов обычно сразу же перенаправляют пользователя на HTTPS-соединение. Однако, потенциальный злоумышленник, оказавшийся в нужном месте, может организовать атаку типа "человек посередине" (MITM), чтобы перехватить первоначальный HTTP-запрос и с этого момента контролировать сеанс пользователя.

HSTS устраняет потенциальную уязвимость, сообщая браузеру, что доступ к домену возможен только по протоколу HTTPS. Даже если пользователь переходит по обычной HTTP-ссылке, браузер автоматически переключает соединение на HTTPS.
Политика HSTS формируется путем отправки следующего заголовка HTTP-ответа с защищенных (HTTPS) веб-сайтов:
Strict-Transport-Security: max-age=31536000Когда браузер видит этот заголовок на HTTPS-сайте, он узнает, что доступ к этому домену возможен только по протоколу HTTPS (SSL или TLS). Эта информация сохраняется в кэше на max-age (обычно 31 536 000 секунд, что соответствует примерно 1 году).
- 5 минут:
max-age=300; includeSubDomains - 1 неделя:
max-age=604800; includeSubDomains - 1 месяц:
max-age=2592000; includeSubDomains
Необязательный параметр includeSubDomains сообщает браузеру, что политика HSTS также применяется ко всем поддоменам текущего домена.
Strict-Transport-Security: max-age=31536000; includeSubDomainsНапример, HTML-ответ для https://www.example.com может включать запрос к ресурсу с https://example.com, чтобы убедиться, что HSTS настроен для всех поддоменов example.com.
Настройка HSTS в Nginx
Сама настройка простая. Нужно добавить заголовок:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;Параметр always гарантирует, что заголовок будет установлен для всех ответов, включая ответы с внутренними ошибками. Более старые версии NGINX (до версии 1.7.5) не поддерживают параметр always.
Прописать заголовок можно на уровне server. Но помните, в nginx есть известная проблема: если в location используется add_header, то заголовки с уровня server не наследуются.
server {
listen 443 ssl;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# This 'location' block inherits the STS header
location / {
root /usr/share/nginx/html;
}
# Because this 'location' block contains another 'add_header' directive,
# we must redeclare the STS header
location /servlet {
add_header X-Served-By "My Servlet Handler";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
proxy_pass http://localhost:8080;
}
}Т.е. добавляем настройку на уровень server и во все location, в которых уже имеются другие заголовки add_header.
Проверить, используется ли на сайте политика HSTS, можно здесь:

Вот пример проверки сайта с отключенной политикой HSTS. Видим рейтинг A.

Включаем HSTS и видим:
HTTP Strict Transport Security (HSTS) with long duration deployed on this server.
Рейтинг поднимается до A+.

Параметр "Strict Transport Security (HSTS)" отображается как Yes.
Редирект с HTTP на HTTPS
Если вы включаете на сайте HSTS, до одновременная поддержка обоих протоколов HTTP и HTTPS нецелесообразна. Настройте редирект.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# Discourage deep links by using a permanent redirect to home page of HTTPS site
return 301 https://$host;
# Alternatively, redirect all HTTP links to the matching HTTPS page
# return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}Недостатки HSTS
HSTS не является идеальным решением для защиты от перехвата HTTP-сессии. Пользователи по-прежнему уязвимы для атак, если заходят на защищенный HSTS сайт по протоколу HTTP, если у них:
- Никогда раньше не посещали этот сайт
- Недавно переустановили операционную систему
- Недавно переустановили браузер
- Перешли на новый браузер
- Сменили устройство
- Удалили кэш браузера
- Не посещали сайт в последнее время, и max-age времени прошло
Чтобы решить проблему с первой загрузкой, Chrome ведет список доменов с строгой политикой HSTS, которые используют только протокол HTTPS. Этот список предварительной загрузки HSTS встроен в Chrome. Запросы к этим доменам будут отправляться только по протоколу HTTPS; любые HTTP-запросы будут преобразованы в HTTPS, а при недоступности HTTPS соединение не будет установлено. В других популярных браузерах (Firefox, Safari, IE 11 и Edge) также есть списки предварительной загрузки HSTS, основанные на списке Chrome.
Можно подать заявку:
Чтобы ваш сайт был включен в список предварительной загрузки HSTS, он должен соответствовать следующим требованиям:
- Используйте действительный сертификат.
- Перенаправьте трафик с HTTP на HTTPS на том же хосте, если вы прослушиваете порт 80.
- Обслуживайте все субдомены по протоколу HTTPS.
- В частности, вы должны поддерживать HTTPS для поддомена www, если для него существует DNS-запись.
- Примечание: предварительная загрузка HSTS применяется ко всем поддоменам, включая внутренние поддомены, которые не являются общедоступными.
- Добавьте заголовок HSTS в базовый домен для HTTPS-запросов:
- Значение max-age должно быть не менее 31536000 секунд (1 год).
- Необходимо указать директиву includeSubDomains.
- Необходимо указать директиву preload.
- Если вы выполняете дополнительное перенаправление с HTTPS-сайта, на этом перенаправлении также должен быть указан заголовок HSTS (а не на странице, на которую оно перенаправляет).
- Более подробную информацию о HSTS можно найти в RFC 6797.
Имейте в виду, что после установки заголовка STS или добавления доменов в список предварительной загрузки HSTS удалить его будет невозможно. Это необратимое решение, которое сделает ваши домены доступными только по протоколу HTTPS.
А ещё Google не проверяет владельца домена.
Ещё недостатки HSTS
В результате работы антивируса, подменяющего сертификаты налету, или из-за реальной атаки MITM могут всплыть проблемы.
Примеры
Google Chrome начал при входе на сайт выдавать ошибку:
NET::ERR_CERT_AUTHORITY_INVALID
Веб-сайт example.com использует механизм HSTS. Открыть сайт в настоящее время нельзя. Сбой мог быть вызван сетевой ошибкой или действиями злоумышленников. Скорее всего, сайт заработает через некоторое время.
Google Chrome — отключаем HSTS
Edge начал при входе на сайт выдавать ошибку:
You cannot visit example.com right now because the website uses HSTS
