Почему открытый 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, и ломаются молча при миграции.