Почему открытый HTTP — жёсткая ошибка — Примеры

Пример 1 — Отдача открытой схемы вместо перенаправления

Сервис всё ещё отвечает и по открытой схеме, и по защищённой, поэтому первый запрос каждой сессии читается любым на пути. Приведённая конфигурация отдаёт страницу и так и так. Измените её так, чтобы открытый запрос бессрочно перенаправлялся, а браузер вообще перестал пробовать открытую схему.

server {
    listen 80;
    server_name example.test;
    root /srv/site;
}

Решение

блок server, открытый слушатель:
  return 301 на защищённую схему того же хоста, с тем же путём и запросом
блок server, защищённый слушатель:
  Strict-Transport-Security: max-age=31536000; includeSubDomains

Бессрочное перенаправление сохраняет путь и параметры запроса, поэтому существующие ссылки продолжают работать, а заголовок говорит браузеру вовсе отказаться от открытой схемы на год, что убирает разрыв на первом запросе. includeSubDomains — та директива, что делает раннее включение опасным: она покрывает не мигрированные поддомены, поэтому добавляйте её только когда каждый из них отвечает по защищённой схеме. Обычная ошибка — перенаправить и пропустить заголовок, оставив первый шаг каждой новой сессии открытым.

Пример 2 — Перенаправление, которое проглатывает форму

Форма оформления заказа отправляется на относительный путь, который сервер затем перенаправляет на защищённую схему. Тестировщики сообщают, что заказ приходит пустым, а лог показывает отправку, за которой следует второй запрос без тела. Исправьте форму, чтобы тело дошло до обработчика, и скажите, почему перенаправление этого не может.

<form method="post" action="/checkout">
  <input name="cart" value="a1">
  <button type="submit">Pay</button>
</form>

Решение

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

Перенаправление после POST теряет тело, если клиент не отправит его заново, а большинство клиентов этого не делают, поэтому обработчик видит пустую отправку. Укажите действие на защищённую схему вместо доверия перенаправлению для любого запроса, несущего данные. Обычная ошибка — перенаправлять всё единообразно и считать это безобидным; как раз машинные вызывающие, делающие POST, и ломаются молча при миграции.