Layer 8Ehrlicher Tech-Support
SoftwareSchweregrad: LästigMixed Content: The page at … was loaded over HTTPS, but requested an insecure … This request has been blocked; the content must be served over HTTPS.

Sichere Seite bleibt halb leer: Gemischte Inhalte werden blockiert

Die Seite läuft über HTTPS, lädt aber Bilder oder Skripte per HTTP nach. Der Browser blockiert sie — und die halbe Seite fehlt. Warum das gut ist.

Aufwand:
ca. 45 Min.
Voraussetzung:
Ein Browser mit Entwicklerwerkzeugen, Zugriff auf den Quelltext oder das Redaktionssystem, Terminal mit curl und grep
Gilt für:
Alle aktuellen Browser, W3C Mixed Content, Candidate Recommendation Draft vom 23.02.2023

Das Symptom

Die Adresszeile zeigt ein Schloss, die Seite ist erreichbar — und trotzdem stimmt etwas nicht. Das Logo fehlt, die Bildergalerie bleibt weiß, das Kontaktformular reagiert auf keinen Klick, oder die Schriftart sieht plötzlich aus wie 1998. Auf dem eigenen Testrechner war alles in Ordnung. In der Konsole der Entwicklerwerkzeuge stehen dafür rote Zeilen mit den Worten Mixed Content und dem Hinweis, eine Anfrage sei blockiert worden.

Die „Layer 8“-Wahrheit

Der erste Reflex lautet „die Seite ist kaputt“. Tatsächlich funktioniert hier genau das, was funktionieren soll: Der Browser hält ein Versprechen, das die Seite selbst gegeben hat.

HTTPS bedeutet nicht nur, dass niemand mitliest. Es bedeutet auch, dass niemand unterwegs etwas verändert. Genau dieses zweite Versprechen bricht in dem Moment, in dem eine verschlüsselte Seite ein Skript unverschlüsselt nachlädt. Wer die Leitung kontrolliert — das offene WLAN, ein Zwischenknoten beim Provider, ein manipulierter Router —, tauscht dieses Skript aus und hat damit die vollständige Kontrolle über eine Seite, die dem Besucher weiterhin ein Schloss anzeigt. Die Verschlüsselung des Rests hilft dann überhaupt nichts mehr. Das Schloss wäre eine Behauptung ohne Deckung, und deshalb liefert der Browser lieber eine löchrige Seite als eine unehrliche.

Nicht alles wird gleich behandelt, und das erklärt die verwirrende Beobachtung, dass manche Dinge fehlen und andere nicht. Bilder, Audio und Video stuft die Spezifikation als aufwertbar ein: Der Browser schreibt die Adresse still auf https um und versucht es damit noch einmal. Klappt das, merkt niemand etwas. Klappt es nicht, ist das Bild weg. Alles Übrige — Skripte, Stylesheets, Abrufe per JavaScript — gilt als blockierbar und wird ohne zweiten Versuch abgewiesen. Deshalb ist ein fehlendes Skript so viel spektakulärer als ein fehlendes Bild: Es reißt die Bedienung der Seite mit.

Die Reparatur ist unspektakulär. Erst die Konsole lesen, weil dort die exakte Adresse steht. Dann prüfen, ob der Zielserver HTTPS überhaupt beherrscht — wenn nicht, ist der Anbieter das Problem und nicht dein Quelltext. Dann die Verweise umstellen, und zwar auch die, die tief in der Datenbank des Redaktionssystems schlummern. Wer den Bestand nicht vollständig überblickt, setzt zusätzlich die Kopfzeile, die den Browser die Aufwertung selbst erledigen lässt. Was man nicht tun sollte: die Warnung im Browser wegklicken und die Seite für repariert halten. Der eigene Browser ist die einzige Stelle auf der Welt, an der diese Ausnahme gilt.

Die echte, verifizierte Lösung

1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:

  1. 1.

    Die Konsole öffnen und lesen, was wirklich fehlt

    Vor jeder Vermutung steht die Meldung. Die Entwicklerwerkzeuge des Browsers öffnest du mit F12, den Reiter Konsole auswählen und die Seite neu laden. Blockierte gemischte Inhalte melden sich dort mit dem Stichwort `Mixed Content` und nennen die genaue Adresse, die nicht geladen wurde. Diese Adresse ist die einzige Information, die du wirklich brauchst — alles andere ist Raten.

  2. 2.

    Prüfen, ob das Ziel überhaupt HTTPS kann

    Bevor du irgendetwas umschreibst: Beantwortet der fremde Server dieselbe Adresse auch verschlüsselt? Ein Statuscode 200 heißt ja, ein Verbindungsfehler oder ein Zertifikatsfehler heißt nein. Im zweiten Fall hilft kein Suchen-und-Ersetzen, dann muss der Anbieter gewechselt oder die Datei selbst gehostet werden.

    curl -sSI https://cdn.example.com/logo.png | head -1
    
  3. 3.

    Alle unverschlüsselten Verweise im eigenen Quelltext finden

    Der Klassiker sind fest eingetragene `http://`-Adressen, die aus der Zeit vor der Umstellung stammen. Das Suchen im Projektverzeichnis kostet zehn Sekunden und findet die meisten Fälle. Ein Verweis auf `http://www.w3.org/2000/svg` in einem SVG ist dabei kein Fund, den du anfassen musst: Das ist ein Namensraum-Bezeichner, keine Adresse, die geladen wird.

    grep -rn "http://" src/ public/
    
  4. 4.

    Die ausgelieferte Seite selbst durchsuchen

    Was im Quelltext sauber ist, kann trotzdem unverschlüsselt beim Besucher ankommen — weil das Redaktionssystem alte Adressen aus der Datenbank einsetzt oder ein Baukasten sie erzeugt. Deshalb wird die fertige Seite geprüft, nicht das Repository. Der Befehl listet jede unverschlüsselte Adresse im ausgelieferten HTML auf.

    curl -s https://example.com/ | grep -oE "http://[^\"' >]+" | sort -u
    
  5. 5.

    Fehlende Verweise auf HTTPS umstellen

    Wo der Zielserver HTTPS beherrscht, wird der Verweis schlicht geändert. Verwende dabei die vollständige Adresse mit `https://` und nicht die alte Schreibweise ohne Schema (`//cdn.example.com/…`): Die spart zwar Tipparbeit, verschleiert aber, was tatsächlich passiert, und bricht beim lokalen Öffnen einer Datei. In Redaktionssystemen muss zusätzlich der Datenbestand angefasst werden — dafür bringen die meisten Systeme ein Werkzeug zum Suchen und Ersetzen mit.

  6. 6.

    Als Netz darunter Autoupgrade erzwingen

    Für große Altbestände, in denen sich nicht jeder Verweis von Hand finden lässt, gibt es eine Kopfzeile, die den Browser anweist, unverschlüsselte Anfragen vor dem Abruf umzuschreiben. Das ist ein Sicherheitsnetz und kein Ersatz für saubere Verweise — es hilft nichts, wenn der Zielserver kein HTTPS spricht. Die Zeile gehört in die Serverkonfiguration; hier für nginx:

    add_header Content-Security-Policy "upgrade-insecure-requests" always;
    
  7. 7.

    Am Ende noch einmal die Konsole prüfen

    Nach der Änderung die Seite mit geleertem Zwischenspeicher neu laden und die Konsole erneut ansehen. Erst wenn dort keine `Mixed Content`-Meldung mehr steht, ist die Sache erledigt. Kontrolliere dabei mehrere Unterseiten: Der eine übrig gebliebene Verweis sitzt erfahrungsgemäß im Fußbereich einer selten aufgerufenen Seite.

Häufige Fragen (FAQ)

?Warum blockiert der Browser überhaupt etwas, das doch bisher funktioniert hat?

Weil das Schloss in der Adresszeile sonst eine Lüge wäre. Eine Seite über HTTPS ist gegen Mitlesen und Verändern auf dem Weg geschützt. Lädt diese Seite auch nur ein einziges Skript unverschlüsselt nach, kann jeder, der die Leitung kontrolliert — das offene WLAN im Café, ein Zwischenknoten beim Provider —, dieses Skript austauschen und damit die komplette Seite übernehmen. Die W3C-Spezifikation nennt das Ziel klar: Sie will „better security and privacy guarantees and a better security UX, while minimizing breakage“. Der Browser wählt also im Zweifel die Sicherheit und nimmt in Kauf, dass ein Bild fehlt.

?Warum fehlt bei mir ein Skript komplett, ein Bild aber nur manchmal?

Weil die Spezifikation zwei Klassen unterscheidet. Bilder, Audio und Video gelten als „upgradeable“ — der Browser versucht, die Adresse still von `http` auf `https` umzuschreiben, und blockiert erst, wenn das scheitert. Alles andere ist „blockable“: „Any mixed content that is not upgradeable as defined above is considered to be blockable. Typical examples of this kind of content include scripts, plugin data, data requested via XMLHttpRequest, and so on.“ Ein Skript wird also gar nicht erst versucht, sondern hart abgewiesen. Deshalb ist bei fehlendem JavaScript sofort die halbe Seite tot, während ein Bild oft unbemerkt heil ankommt.

?Kann ich das nicht einfach im Browser erlauben?

Manche Browser bieten diese Möglichkeit an — die Spezifikation erlaubt sie ausdrücklich („A user agent MAY offer users the ability to override its decision to block blockable mixed content on a particular page“) und schiebt im selben Atemzug die Warnung hinterher, dass gerade das Zulassen gemischter Skripte eine sehr gefährliche Option ist. Vor allem aber löst es nichts: Deine Besucher klicken das nicht an. Sie sehen eine kaputte Seite und gehen. Die Ausnahme im eigenen Browser ist ein Diagnosewerkzeug, keine Reparatur.

Belege

Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler

SWLästigblocked by CORS policy

Browser blockiert Anfrage wegen CORS

Die Konsole meldet einen CORS-Fehler und die Anfrage scheitert? Nicht der Browser ist schuld — der Server muss den Zugriff von deiner Herkunft erlauben.

SWLästigNET::ERR_CERT_AUTHORITY_INVALID

Browser: NET::ERR_CERT_AUTHORITY_INVALID

Der Browser warnt, das Zertifikat stamme von keiner vertrauenswürdigen Stelle? Oft schneidet Software mit oder es ist selbst signiert.

NETLästigERR_TOO_MANY_REDIRECTS

ERR_TOO_MANY_REDIRECTS beheben

Der Browser meldet ERR_TOO_MANY_REDIRECTS und die Seite lädt nie fertig? Eine Weiterleitungsschleife ist schuld. So findest du sie auf Client und Server.