Mixed content: pozostałości http:// na stronie https://
Dlaczego jeden zapomniany obrazek lub skrypt po http:// przekreśla bezpieczeństwo strony HTTPS, co przeglądarki blokują albo po cichu podnoszą do https i jak to raz na zawsze posprzątać.
Bezpieczeństwo · Opublikowano: 25 września 2026 · 6 min czytania · Дмитрий Орлов
Przeniesienie witryny na HTTPS zajmuje popołudnie: certyfikat, przekierowanie z portu 80, gotowe. A potem na połowie stron nie pojawia się kłódka, przestaje działać slider albo font po cichu zamienia się w Arial. Sama strona przyszła przez https://, ale coś w jej wnętrzu wciąż prosi o http://. To właśnie mieszana treść, czyli mixed content.
Dlaczego jedno żądanie po http:// ma znaczenie
HTTPS chroni całą stronę tylko wtedy, gdy każdy jej bajt przychodzi szyfrowanym połączeniem. Jeden skrypt wczytany zwykłym HTTP może odczytać i podmienić każdy, kto jest po drodze: publiczne Wi-Fi, przejęty router, dostawca wstrzykujący reklamy. Podmieniony skrypt działa z pełnym dostępem do strony: czyta pola formularzy, przepisuje linki, kradnie dane sesji. Szyfrowanie samego dokumentu HTML przestaje cokolwiek znaczyć.
Przeglądarki dzielą mieszaną treść na dwie grupy według tego, ile szkody może wyrządzić.
- Treść aktywna (blokowalna): skrypty, arkusze stylów, iframe'y, fonty, żądania
fetchi XHR, workery. Wszystko, co może zmienić stronę albo z niej czytać. Nowoczesne przeglądarki blokują ją całkowicie — żądanie nie zostaje wysłane, a w konsoli pojawia się błąd. - Treść pasywna (podnoszalna): obrazy, audio i wideo. Najgorsze, co może zrobić atakujący, to podmienić obrazek. Aktualne Chrome i Firefox w ogóle nie wczytują już takich zasobów po HTTP: automatycznie przepisują adres na https://, a jeśli zasób nie jest dostępny przez HTTPS, po prostu się nie wczytuje.
Starsze przeglądarki i niektóre wbudowane widoki WWW nadal wyświetlają pasywną mieszaną treść bez zmian i oznaczają stronę jako nie w pełni bezpieczną — stąd znikająca albo przekreślona kłódka.
Formularze to osobny przypadek. <form action="http://..."> na stronie HTTPS wysyła wpisane dane bez szyfrowania. Przeglądarki ostrzegają przed wysłaniem takiego formularza, a ostrzeżenie wygląda na tyle groźnie, że wiele osób po prostu rezygnuje.
Skąd się bierze
Niemal każdy problem z mieszaną treścią to pozostałość z czasów sprzed przeprowadzki.
- Zaszyte adresy w bazie CMS. Redaktorzy wstawiali obrazy, gdy witryna działała na HTTP, więc treści wpisów, widżety i ustawienia wciąż zawierają
http://example.com/uploads/.... Zmiana adresu witryny w panelu administracyjnym nie rusza już zapisanych treści. - Stare osadzenia. Odtwarzacze wideo, mapy, liczniki i widżety czatu wklejone lata temu z adresem http://. Część tych usług działa już po HTTPS, części już nie ma.
- CSS.
background-image: url(http://...)w arkuszu stylów albo w atrybuciestyle, a także@font-facewskazujący na hosting fontów po HTTP. - Obrazy responsywne.
srcpoprawiono, alesrcsetwciąż zawiera kandydatów z http://, a na ekranie o dużej gęstości pikseli przeglądarka może wybrać właśnie któregoś z nich. - Szablony i JavaScript. Motyw, który składa adresy bezwzględne z na sztywno wpisanym schematem, albo skrypt, który w trakcie działania strony dołącza zasoby po
http://.
Jak ją znaleźć
DevTools. Otwórz stronę, otwórz konsolę, przeładuj. Każde żądanie z mieszaną treścią zostanie tam zgłoszone z dokładnym adresem i informacją, czy zostało zablokowane, czy podniesione do https. W panelu Network w Chrome filtr mixed-content:all zawęża listę tylko do takich żądań. To działa dla jednej strony naraz.
Statyczny HTML. Szybkie pierwsze przejście po znacznikach:
curl -s https://example.com/ | grep -Eo '(src|href|srcset|action)="http://[^"]+"'
Nie zobaczy adresów w plikach CSS ani tych dodawanych przez JavaScript, ale wyłapie większość pozostałości z CMS.
Raporty CSP. Aby znaleźć mieszaną treść w całej witrynie na prawdziwym ruchu, wyślij politykę w trybie report-only, która dopuszcza wyłącznie źródła HTTPS:
Content-Security-Policy-Report-Only: default-src https: data: blob: 'unsafe-inline' 'unsafe-eval'; report-uri /csp-report
Nic nie zostaje zablokowane, ale każde wczytanie po http:// generuje raport z adresem strony i zasobu. Pamiętaj, że upgrade-insecure-requests nie działa w polityce report-only, a stara dyrektywa block-all-mixed-content jest przestarzała — nowoczesne przeglądarki i tak domyślnie blokują treść aktywną.
Raport SiteScan również to sprawdza: oznacza każdą przeskanowaną stronę, która wczytuje zasoby po http://, w punkcie „Serve every asset over https://”.
Jak to naprawić
Używaj https:// albo adresów względnych. Dla własnych zasobów najpewniejsza jest ścieżka w rodzaju /uploads/photo.jpg: przejmuje schemat i domenę strony. Dla zasobów zewnętrznych przejdź na https:// i sprawdź, czy dostawca rzeczywiście je tak serwuje. Jeśli nie — zamień zasób albo hostuj go u siebie.
Wyszukaj i zamień w bazie — ostrożnie. Najpierw kopia zapasowa. W WordPressie użyj WP-CLI, a nie gołego SQL, bo poprawnie obsługuje zserializowane dane PHP:
wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
Gdy liczby wyglądają sensownie, uruchom ponownie bez --dry-run. Zwykły SQL-owy REPLACE zmienia długość napisów wewnątrz zserializowanych wartości i może uszkodzić ustawienia widżetów i wtyczek.
Dodaj upgrade-insecure-requests jako zabezpieczenie. Z tym nagłówkiem przeglądarka przepisuje każdy podzasób z http:// na https://, zanim go zażąda:
Content-Security-Policy: upgrade-insecure-requests
To siatka asekuracyjna, a nie naprawa: jeśli host nie ma HTTPS, żądanie po prostu się nie powiedzie, a adresy http:// zostaną w treściach i w kanałach RSS.
Włącz HSTS, gdy witryna jest już czysta. Strict-Transport-Security: max-age=31536000; includeSubDomains każe przeglądarce nigdy więcej nie łączyć się z twoją domeną po HTTP. Zacznij od krótkiego max-age i zwiększ go, gdy upewnisz się, że wszystkie subdomeny działają po HTTPS.
Lista kontrolna
- Konsola nie pokazuje ostrzeżeń o mieszanej treści na głównych szablonach.
- Brak adresów http:// w
src,href,srcset,actioni CSS-owymurl(). - Stare adresy w bazie zamienione narzędziem bezpiecznym dla serializacji.
- Osadzenia zewnętrzne ładują się po HTTPS albo zostały usunięte.
upgrade-insecure-requestsustawione jako zabezpieczenie.- HSTS włączone dopiero wtedy, gdy wszystko powyżej jest czyste.
Przeczytaj także
Sprawdź, ile z tego dotyczy Twojej strony
Darmowe skanowanie pokaże uszkodzone linki, błędy JS i problemy z wydajnością w minutę.