Перейти к содержанию
Innovialabs

Что такое HSTS и как безопасно его включить

Практика3 мин

Коротко

HSTS — заголовок ответа, который велит браузеру ходить на ваш домен только по HTTPS в течение заданного срока и тем самым блокирует атаки понижения; включать его нужно постепенно, увеличивая max-age шагами и добавляя includeSubDomains и preload только когда все поддомены работают по HTTPS.

Коротко

HSTS (HTTP Strict Transport Security) — это один заголовок ответа:

Strict-Transport-Security: max-age=31536000; includeSubDomains

Получив его по HTTPS, браузер в течение max-age секунд:

  • сам превращает любой запрос http:// к вашему домену в https:// ещё до отправки в сеть;
  • не даёт пользователю «пройти дальше» при ошибке сертификата на этом домене.

От какой атаки защищает HSTS

Редиректа с HTTP на HTTPS недостаточно. Когда пользователь вводит example.com или открывает старую ссылку http://, первый запрос браузера уходит без шифрования. Злоумышленник в том же Wi-Fi или на взломанном роутере может его перехватить и провести SSL stripping:

  1. Атакующий отвечает пользователю по обычному HTTP.
  2. Параллельно он общается с вашим настоящим сервером по HTTPS и пересылает страницы.
  3. Пользователь видит работающий сайт без замка и вводит пароль, который атакующий читает.

С HSTS браузер вообще не отправляет первый HTTP-запрос — перехватывать нечего. Остаётся только самый первый визит, до того как браузер увидел заголовок, — его закрывает preload-список.

Директивы

ДирективаЧто делаетРекомендация
max-ageСколько секунд браузер помнит правилоНаращивать постепенно до одного или двух лет
includeSubDomainsРаспространяет правило на все поддоменыТолько после проверки всех поддоменов
preloadСообщает о согласии на включение во встроенные списки браузеровТолько после стабильного внедрения, см. ниже

Браузеры игнорируют заголовок, пришедший по обычному HTTP, поэтому отдавать его нужно в HTTPS-ответах.

Безопасный план внедрения

  1. Составьте список поддоменов. DNS-записи, старые админки, веб-интерфейсы почты, staging, внутренние сервисы, оборудование. У каждого должен быть действующий сертификат и рабочий HTTPS.
  2. Начните с малого: max-age=300 без includeSubDomains. Проверьте сайт, вход, оплату, встроенные виджеты.
  3. Увеличивайте шагами: сутки (86400), неделя (604800), месяц (2592000). Между шагами следите за ошибками.
  4. Добавьте includeSubDomains снова с коротким max-age и затем увеличивайте.
  5. Дойдите до года (31536000) или двух (63072000).
  6. Рассматривайте preload, только когда уверены, что весь домен останется на HTTPS.

Если что-то сломалось, отдайте max-age=0. Это сбросит правило только у тех браузеров, которые зайдут снова, — пользователи, получившие длинный max-age и не вернувшиеся, останутся привязаны к HTTPS до его истечения. Поэтому постепенность и важна.

Preload-список

Браузеры поставляются со встроенным списком доменов, которые работают только по HTTPS с первого визита. Чтобы подать домен на hstspreload.org, как правило, нужно:

  • действующий сертификат и редирект с HTTP на HTTPS на том же хосте;
  • все поддомены работают по HTTPS;
  • на основном домене заголовок с max-age не меньше года, плюс includeSubDomains и preload.

Удаление возможно, но медленно: оно доходит до пользователей только с новыми версиями браузеров. Считайте preload долгосрочным обязательством для всего домена, включая поддомены, которые вы создадите в будущем.

Настройка в nginx и частая ловушка

server {
    listen 443 ssl;
    server_name example.com;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
  • always заставляет nginx отдавать заголовок и в ответах с ошибками.
  • Если в блоке location есть свой add_header, nginx не наследует заголовки с уровня server, и HSTS там молча пропадает. Повторите его или вынесите общие заголовки в отдельный include-файл.

Проверка:

curl -sI https://example.com | grep -i strict-transport-security

В Chrome посмотреть и удалить сохранённое правило для домена можно на странице chrome://net-internals/#hsts.

Частые ошибки

  • includeSubDomains включён, а внутренний или старый поддомен работает только по HTTP.
  • Сразу выставлен max-age на год.
  • Домен подан в preload «на всякий случай», без плана для будущих поддоменов.
  • Заголовок задан только в приложении, а статика и страницы ошибок отдаются без него.
  • Для локальной разработки используются .dev или .app: эти зоны целиком в preload-списке и требуют HTTPS.

Частые вопросы

Нет. Сам редирект идёт по обычному HTTP, и его можно перехватить. HSTS заставляет браузер вообще пропустить HTTP-запрос.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.