VPN подключён, но смешанное содержимое по-прежнему блокируется: что исправить
Отсортируйте заблокированный URL по тому, кто его создал, исправьте ссылку или передайте её владельцу хоста, а затем подтвердите исправление в консоли браузера.
Половина страницы отрисовывается, одна таблица стилей показана серой на панели «Сеть», а клиент VPN по-прежнему сообщает об исправном туннеле. Все три наблюдения верны одновременно, потому что браузер оценил запрос, сделанный страницей, а туннель в этой оценке не участвовал. Дело закрывает решение, а не настройка: исправить ссылку, эскалировать её владельцу хоста или отказаться от зависимости. У каждого из этих вариантов есть дешёвая проверка, а выбор неверного стоит цикла поддержки.
Почему туннель не может покрыть подресурс
Смешанное содержимое начинается с HTTPS-документа, который запрашивает подресурс по обычному HTTP. Каждый URL оценивается по собственной схеме, поэтому защита родительского документа никогда не распространяется на дочерний запрос. Шифрование, добавленное ниже браузера, меняет то, что идёт по проводу, а не http://, который запросила разметка.
Современные браузеры делят такие запросы на две группы и обращаются с ними по-разному. Скрипты, таблицы стилей, iframe и вызовы через fetch, XMLHttpRequest или WebSocket отклоняются сразу, без предварительной попытки обновления. Изображения, аудио и видео переписываются на https:// и запрашиваются заново, а загрузка прерывается, когда это безопасное получение не удаётся. URL подресурса, хостом которого является голый IP-адрес, исключён из обновления, поэтому HTTP-изображение на IP-хосте остаётся заблокированным, а не исправляется молча. Это разделение, включая указанное исключение на обновляемой стороне, описано в руководстве Mozilla о смешанном содержимом. Chrome применяет похожий отказ к небезопасным загрузкам, начатым с безопасной страницы, поэтому ссылка на PDF может умереть, пока окружающая страница выглядит целой.
Серая строка, таким образом, доказывает, что проверка работает, а не то, что туннель пропустил открытый текст. Относитесь к строке как к находке, указывающей на одну ссылку, а не на всю страницу.
Определите, кому принадлежит небезопасная ссылка
Отсортируйте проблемный URL по месту, где он создаётся, прежде чем что-либо менять. Этот ответ решает, можете ли вы выпустить исправление сегодня, должен ли его выпустить поставщик или зависимость должна покинуть страницу. Прочитайте его в столбце Initiator на панели «Сеть», потому что разметка на экране часто собирается во время выполнения.
| Откуда берётся URL | Кто может его исправить | Первый шаг |
|---|---|---|
| Жёстко задан в шаблоне или части, которую вы развёртываете | Вы | Замените его формой https:// и затем очистите кеш |
| Внедрён менеджером тегов или пакетом поставщика | Поставщик, с вашим тикетом | Отправьте точный URL, тип запроса и строку консоли |
| Отдаётся только на порту 80 без слушателя TLS | Владелец хоста | Запросите TLS, поставьте перед ним что-то своё или откажитесь от него |
Когда хост уже отвечает на 443, а http говорит только ссылка, исправление локальное: измените ссылку, очистите кеш страницы и подтвердите, что строка стала https. Хост, который слушает только на порту 80, нельзя привести в соответствие правкой, поэтому ресурс переезжает, перед ним ставится что-то, что контролируете вы, или он исчезает. URL, внедрённый менеджером тегов, продолжает появляться, даже когда ваш собственный шаблон чист, и этот случай относится к тикету с точным URL и строкой консоли во вложении. Советовать персоналу разрешить небезопасное содержимое — не один из этих вариантов, потому что это отключает проверку для каждого сайта, который посещает такой профиль браузера.
Исправьте ссылку, а не настройку браузера
Перезагрузите сбойный сценарий с сохранённым журналом сети и отфильтруйте панель по подозрительному хосту. Консоль называет URL и директиву, что решает, был ли запрос отклонён или обновлён, прежде чем вы тронете шаблон.
curl -sSI https://cdn.example.org/vendor.js | head -n 1
curl -sS -o /dev/null -w '%{http_code} %{url_effective}\n' -L https://cdn.example.org/vendor.jsЕсть две вспомогательные проверки, и ни одна не заменяет исправление. Заголовок Content-Security-Policy с upgrade-insecure-requests заставляет браузер переписывать URL подресурсов http, прежде чем они покинут страницу, что ловит старые ссылки, которые вы ещё не нашли. Переписанный запрос всё равно не проходит, когда целевой хост не отдаёт HTTPS, поэтому заголовок меняет лишь то, какой URL пробует браузер. HSTS действует на хост, то есть политика на вашем домене ничего не делает для стороннего CDN, который никогда не присылал заголовок. После правки шаблона очистите кеш страницы и поищите старое имя хоста в отрисованном HTML, потому что тот же URL может прийти и через часть, строку перевода или поле базы данных.
Отслеживайте и перенаправления, потому что цепочка, начинающаяся с https://, может попасть на адрес http://, а браузер оценивает последний переход. Форма -L второй команды выше выводит этот фактический URL за вас. Если последний переход — чистый http, ссылка всё равно неверна, хотя отредактированная вами ссылка выглядела нормально.
Подтвердите страницу консолью и панелью сети
Перезагрузите с отключённым кешем и пройдите сценарий заново, включая кнопки, которые подгружают содержимое по требованию. Первая загрузка страницы скрывает ленивые виджеты, плитки карты и скрипты плеера, которые появляются только после клика. В консоли не должно быть записей о смешанном содержимом, и каждая затронутая строка должна показывать https. Снимите консоль и строку запроса до закрытия тикета, потому что это состояние трудно восстановить после следующего развёртывания.
Когда ресурс принадлежит кому-то другому, отправьте четыре вещи: точный URL, тип запроса, текст консоли и страницу, где он появляется. Скройте идентификаторы сеанса во всём, что вставляете в тикет. Отчёт, который лишь говорит, что изображения сломаны, не даёт владельцу ничего для поиска.
Туннель продолжает делать свою работу, пока исправление лежит в ссылке, создавшей запрос. После развёртывания ещё раз поищите имя хоста в шаблоне и пакете поставщика и закрывайте дело только тогда, когда в консоли не останется ни одной заблокированной записи о смешанном содержимом.