RomanD: Umleitung auf HTTPS - zerstörter Quellcode

Hi,

wenn ich mittels
header('Location: '.$redirect,true, 101);
auf eine HTTPS Seite ohne Zertifikat umleite, wird der Quellcode der Seite durch verschiedene Hex-Zahlen zerstört.
Kann man jemand erklären, warum das so ist? Das es daran liegt, dass kein Zertifikat vorhanden ist weis ich, aber woher kommten diese Hex Zahlen im Quellcode?

Gruß

  1. Moin!

    wenn ich mittels
    header('Location: '.$redirect,true, 101);
    auf eine HTTPS Seite ohne Zertifikat umleite, wird der Quellcode der Seite durch verschiedene Hex-Zahlen zerstört.

    Du hast eine merkwürdige Art, das zu tun.

    HTTP-Statuscode 101 ist zwar theoretisch für "Switching Protocol" definiert, aber alle schnell auffindbaren Quellen sagen "Wird derzeit noch nicht verwendet".

    Warum verwendest du ihn dann?

    Und wo in deiner Weiterleitung definierst du, auf welches Protokoll umgeschaltet werden soll? Was steht in $redirect drin? EIne vollständige URL, so wie es der Standard verlangt, also inklusive HTTPS vorne dran? Dann bräuchtest du einfach nur einen Redirect-Statuscode nehmen (temporäres Redirect passiert automatisch bei PHP, permanentes Redirect erfordert den passenden Statuscode manuell).

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
    1. $redirect = "https://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'];

      Eigendlich war es dafür gedacht, um wenn man das Bestellformular aufruft, auf https umzuschalten. Mittlerweile hab ich es anders gelöst, aber darum geht es mir nicht.

      Mich interessiert nur wo diese Zahlen herkommen.

      1. Hallo,

        Mich interessiert nur wo diese Zahlen herkommen.

        Das kann man nur raten. Bei mir wird bei exakt Deinem gleichen Code nämlich einfach nur eine weiße Seite (nach einer gewissen Zeit, es wird ein Timeout erreicht) angezeigt.

        Du könntest mit Wireshark o.ä. mal Deinen eigenen Netzwerkverkehr mitsniffen und so feststellen, was tatsächlich über das Netzwerk wandert.

        Im Gegensatz zu dem, was Sven sagte, ist 101 Switching Protocols in HTTP/1.1 tatsächlich definiert. Allerdings verletzt Du den HTTP/1.1-Standard, indem Du keinen 'Upgrade'-Header sendest und beim Connection-Header auch kein upgrade als Schlüsselwort mitsendest und vor allem direkt 101 sendest obwohl der Client selbst keinen Upgrade-Header geschickt hat! Mir scheint, Du hast den Sinn von 101 nicht ganz verstanden.

        Zuerst einmal: So SOLLTE 101 funktionieren:

        1. Der Client stellt eine Anfrage mit Connection: Upgrade und
           Upgrade: NeuesProtokoll (oder eine Liste von Protokollen). Damit
           signalisiert er dem Server, das er aktualisieren WILL.
        2. Der Server antwortet mit HTTP/1.1 101 Switching Protocols
           Er sendet folgende beiden Header mit (vorgeschrieben nach dem Standard!):
                Connection: upgrade
                Upgrade: NeuesProtokoll
        3. Client und Server fangen nun über die gleiche (!) TCP/IP-Verbindung an, das neue Protokoll zu sprechen.

        Das wird im Prinzip gar nicht wirklich verwendet bisher.

        Was Du *EIGENTLICH* willst, ist den Browser so umleiten, dass er jetzt HTTPS verwendet. Das heißt aber konkret, dass der Browser eine NEUE Verbindung aufbauen soll zum HTTPS-Port, dort dann mit dem Server TLS-Handshake durchführen und dann über die gesicherte TLS-Verbindung mit dem Server HTTP sprechen soll. Switching Protocols bezieht sich aber immer auf die bestehende Verbindung.

        Was Du also konkret willst, ist eine stinknormale Weiterleitung mit einem 300er-Statuscode, die den User auf den HTTPS-Bereich weiterleitet. Das geschieht über einen ganz normalen HTTP/1.1 301 Moved Permanently o.ä. + Location-Header. Dann ruft der Browser das ganze auch über HTTPS ab.

        Um außerdem mal RFC 2616 zu zitieren (den HTTP-Standard):

        |    The Upgrade header field cannot be used to indicate a switch to a
        |    protocol on a different connection. For that purpose, it is more
        |    appropriate to use a 301, 302, 303, or 305 redirection response.

        Übrigens: Der Ansatz, den Du gewählt hast, wäre sowieso zum Scheitern verurteilt. Selbst WENN Du sowas senden würdest wie:

        HTTP/1.1 101 Switching Protocols
        Connection: upgrade
        Upgrade: HTTPS

        ... selbst dann würde das nicht funktionieren KÖNNEN, weil der Client das Upgrade selbst angefordert haben MUSS!

        Was Du im HTTP-Kontext machst, ist also kompletter Unfug. Dass da teilweise auch Zahlensalat rauskommt, ist nicht verwunderlich, auch wenn ich Dir (ohne Netzwerksniffer) nicht GENAU sagen kann, woher der nun bei Dir ausgerechnet kommt.

        Es GIBT allerdings einen Standard, der genau das implementiert, was Du willst: RFC 2817, Upgrading to TLS Within HTTP/1.1.

        Im Prinzip definiert RFC 2817 erstmal folgendes: Der Browser KANN anfordern, dass die Verbindung "upgegradet" wird, d.h. er kann folgendes senden:

        GET /resource HTTP/1.1
        Host: example.com
        Upgrade: TLS/1.0
        Connection: Upgrade

        Der Server hat dann zwei Möglichkeiten:

        1. Die Anfrage unverschlüsselt normal beantworten, d.h. als ob Upgrade und Connection: Upgrade nicht gegeben wären.
        2. Die Anfrage mit folgender Antwort beantworten:

        HTTP/1.1 101 Switching Protocols
        Upgrade: TLS/1.0, HTTP/1.1
        Connection: Upgrade

        NACH dieser Antwort handeln Client und Server über die gleiche Verbindung per TLS dann einen verschlüsselten Kanal aus und kommunizieren darüber.

        RFC 2817 bietet auch die Möglichkeit für den Browser, den Server zu zwingen, TLS zu verwenden, indem er als erste Anfrage überhaupt folgendes schickt:

        OPTIONS * HTTP/1.1
        Host: example.com
        Upgrade: TLS/1.0
        Connection: Upgrade

        Der Server hat dann zwei Möglichkeiten:

        1. Er kann unverschlüsselt den OPTIONS-Request beantworten, dann weiß der Browser, dass der Server nicht verschlüsseln kann oder will und kann somit abbrechen.
        2. Er kann die Anfrage wieder mit obigem 101 Switching Protocols beantworten, dann geht's verschlüsselt weiter.

        Das ist allerdings alles vom Client initiiert.

        Von der Serverseite aus kannst Du jedoch auch folgendes machen: Wenn eine Anfrage kommt, die nur verschlüsselt erreichbar sein soll, dann kannst Du folgendes machen:

        HTTP/1.1 426 Upgrade Required
        Upgrade: TLS/1.0, HTTP/1.1
        Connection: Upgrade

        Dann wird der Client angewiesen "Sorry, ohne Uprade geht's nicht". Dann kann der Client entweder die Fehlerseite, die Du bei 426 mitschickst, anzeigen, ODER er kann die Anfrage mit Upgrade-Header nochmal stellen, woraufhin der Server dann mit 101 antwortet, woraufhin dann erst die Verbindung gesichert ist.

        Das dumme: RFC 2817 wird meines Wissens von noch keinem EINZIGEN Browser mit nennenswerter Verbreitung implementiert. Und der Apache kann das per Default meines Wissens auch nicht, könnte aber sein, dass jemand mal einen Patch / ein Modul geschrieben hat. Nützt Dir also absolut GAR NICHTS.

        Und ich möchte Dir nochmal den Unterschied klar machen, was das eigentlich alles genau heißt:

        1. Wenn Du per 300er-Code umleitest, dann weist Du den Browser an, eine neue Verbindung mit dem HTTPS-Port aufzubauen und dort eine neue Anfrage abzusetzen.

        2. Wenn Du das RFC2817-Verfahren anwenden würdest (funktioniert halt in der Paxis nicht), dann weist Du den Browser an, auf der GLEICHEN Verbindung Verschlüselung (TLS ist der SSL-Nachfolger) zu verwenden oder eben eine Fehlerseite anzuzeigen, wenn der Browser das nicht kann. Bei aktuellen Browsern führt 426 jedoch grunsätzlich zu einer Fehlerseite, das Verfahren ist damit wertlos - zudem wird Dein Apache das eh nicht Out-of-the-Box können, daher nützt es Dir selbst mit einem Browser der das kann nichts.

        Viele Grüße,
        Christian

        1. Moin!

          Im Gegensatz zu dem, was Sven sagte, ist 101 Switching Protocols in HTTP/1.1 tatsächlich definiert.

          Nö, genau das hab' ich gesagt. :)

          Deine Langform gefällt mir aber auch ganz gut. :)

          Weitere Quellen in der Wikipedia deuten darauf hin, dass der Status 101 wohl auch bei WebDAV Verwendung finden könnte. Das würde deine Theorie stützen, dass es bei keinem dir bekannten Browser und Apache-Server funktioniert - weil WebDAV gewöhnlich spezielle Clients und Servermodule erfordert, denen man diesen Statuscode extra beigebracht haben könnte.

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
      2. Hi,

        Mich interessiert nur wo diese Zahlen herkommen.

        Könnte sein, daß die Seite "chunked" ausgeliefert wird, und der Client damit, aus welchen Gründen auch immer, nicht klarkommt. Hex-Zahlen werden hier als Längenangabe des nächsten Chunks gesendet.

        Ein HTTP-Sniffer kann die Erleuchtung bringen ...

        Gruß, Cybaer

        --
        Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!