Norman: Session hijacking verhindern

Hey Forum!

Ich würde gern wissen wie ich zuverlässig Session-hijacking verhindern kann.
Ich erzwinge Sessions per Cookie aber was kann ich dagegen tun wenn jemand den Inhalt des Cookies weiter gibt (Session fixation ist bereits ausgeschlossen)?
Ich würde die Session gern noch an weitere Daten koppeln damit die übernahme einer Session nicht nur von der ID anhängt. Ein Ansatz wäre es, einen Token in einer Datenbank und der Session zu speichern und diese gegeneinander zu vergleichen.

Wie kann man also Session-hijacking zuverlässig verhindern? Oder ist das überhaupt möglich wenn man nichtmal den cookies vertraut?

Norman

  1. Hallo,

    Ich würde die Session gern noch an weitere Daten koppeln damit die übernahme einer Session nicht nur von der ID anhängt. Ein Ansatz wäre es, einen Token in einer Datenbank und der Session zu speichern und diese gegeneinander zu vergleichen.

    Das ist ohnehin übliche Praxis, aber eher um Cross-Site Request Forgery zu verhindern. Nennt sich z.B. authenticity token. Jeder Request mit Seiteneffekten (üblicherweise POST, PUT, DELETE usw.) muss zusätzlich zum Session-Cookie den Token im Body übertragen. Wenn das nicht der Fall ist, kann dem Request nicht vertraut werden.

    Das schützt aber nicht vor Session-Hijacking, soweit ich das sehe. Denn der Token wird bei einem GET-Request im HTML mitgeliefert, z.B. als verstecktes Formularfeld. Wenn ich die Session-ID habe, kann ich mir auch den Token holen.

    Es ließe sich natürlich eine Request-Charakteristik erstellen, z.B. auf Basis von IP-Adresse und User-Agent. Das kann leider auch False Positives erzeugen. Die IP-Adresse kann sich während einer Session ändern und der User-Agent von Proxies geändert werden. Große Sites nutzen daher Zwei-Faktor-Authentifizierung, wenn sie verdächtige Muster feststellen. Der Nutzer wird aufgefordert, neu einzuloggen und z.B. ein Token einzugeben, das per SMS zugestellt wurde.

    Mathias

    1. Ein echt interessantes Thema, ich verschlinge es gerade. Jedoch drängt sich mir bei deinem Post ein paar fragen auf.

      Und zwar habe ich eine Login Tabelle. Jeder User der sich einloggt bekommt einen Eintrag in der Login Tabelle. Es wird ein zufälliger aber eindeutiger Wert erzeugt und sowohl in der Tabelle als auch in der Session gespeichert. Bei jeder Aktion die der Nutzer macht wird geprüft ob er noch angemeldet ist in dem die zwei Werte verglichen werden.

      Jetzt nehmen wir mal den Fall der User möchte seinen eigene Daten ändern. Ich benutze aktuell ein Formular mit method=post. Jetzt behaupte ich das Cross-Site-Request-Forgery bei mir nicht zutrifft, da man die Daten nicht mittels Link ändern kann - richtig?

      Du schreibst man soll einen Token mitschicken. Was für ein Token ist das? Ist das der Wert, den ich in die Login Tabelle gespeichert habe? Oder soll noch ein wert generiert werden? Wenn ja, müsste ich diesen erneut verwalten - sprich eine neue Tabelle für Formular-Tokens?

      Gruß
      Sicherheitsexperte
      T-Rex

      1. Und zwar habe ich eine Login Tabelle. Jeder User der sich einloggt bekommt einen Eintrag in der Login Tabelle. Es wird ein zufälliger aber eindeutiger Wert erzeugt und sowohl in der Tabelle als auch in der Session gespeichert. Bei jeder Aktion die der Nutzer macht wird geprüft ob er noch angemeldet ist in dem die zwei Werte verglichen werden.

        nimm 2 verschiedene tokens. eins als session-id und das andere in der login-tabelle als CSRF-token.
        prüfe bei post-requests die session, die im cookie steht, und das token, das per formular übergeben wurde.
        idealerweise solltest du das user-token regelmässig ändern.
        oder du schreibst es nur mit in die session-tabelle rein.

        Jetzt nehmen wir mal den Fall der User möchte seinen eigene Daten ändern. Ich benutze aktuell ein Formular mit method=post. Jetzt behaupte ich das Cross-Site-Request-Forgery bei mir nicht zutrifft, da man die Daten nicht mittels Link ändern kann - richtig?

        CSRF ist auch bei post-requests möglich, lediglich etwas komplizierter auf der angreiferseite zu initiieren (i.d.R. javascript nötig).

        es ist trotzdem sinnvoll, auf der serverseite zu prüfen, ob auch wirklich post verwendet wurde, schützt aber ohne CSRF-token nicht vor CSRF.

        1. Sorry deine erste Ausführung verstehe ich glaub ich nicht richtig.
          Also was ich aktuell habe ist eine Überprüfung ob der User angemeldet ist. Sonst könnte ja jeder auch ohne große Hacker Kenntnisse einfach Daten ändern. Ich denke soweit ist das auch ganz gut.
          Du sagst ich soll zwei verschiedene Token nehmen. Daraus schließe ich das der zweite Token nichts mit der Überprüfung der Anmeldung zu tun haben sollte. Ist ja auch sinnvoll.
          Also erzeuge ich einen Token, schmeiße ihn in das Formular. Beim absenden überprüfe ich ob der Token stimmt? richtig so?

          Wenn ich das alles so richtig wiedergegeben habe, frage ich mich wo speichere ich den Token? Du sagst in der Session Tabelle. Was ist das? Meinst du damit das $_SESSION Array?
          Wie oft soll ich den Token erneuern? Was passiert wenn gerade jemand im Formular ist und der Token wird erneuert, dann ist das senden des Formulars ungültig?
          Wenn der Token wirklich in der Session steht, diese jedoch von jemand fremden übernommen wurde, wie soll ich dann noch sicher sein? - wuaaahhhhhh.....

          Gruß
          das Problem aus den Augen verlierender
          T-Rex

          1. Wenn ich das alles so richtig wiedergegeben habe, frage ich mich wo speichere ich den Token? Du sagst in der Session Tabelle. Was ist das? Meinst du damit das $_SESSION Array?

            Ja, das geht. Oder in der Datenbank, falls du dort eine Session-Tabelle hast.

            Wie oft soll ich den Token erneuern?

            Z.B. bei jedem erfolgreichen Login.

            Was passiert wenn gerade jemand im Formular ist und der Token wird erneuert, dann ist das senden des Formulars ungültig?

            Ja. Deshalb solltest du den Token nicht mitten in einer Session erneuern.

            Wenn der Token wirklich in der Session steht, diese jedoch von jemand fremden übernommen wurde, wie soll ich dann noch sicher sein?

            Der CSRF-Token ist kein zweiter Session-Cookie. Er schützt gegen *andere* Angriffe, gegen die der Session-Cookie nicht hilft. Klar, wenn der Angreifer den Session-Cookie kompromittieren konnte, ist der CSRF-Token ebenfalls kompromittiert und kein weiterer Schutz.

            Mathias

            1. Hallo!

              Meinst du damit das $_SESSION Array?
              Ja, das geht.

              Wäre das nicht irgendwie recht sinnfrei gegen CSRF?
              Bei CSRF geht es doch gerade darum, dass man die Session des Opfers ausnutzt. Deshalb gehört der Token auch expliziet in die Formulare und z.B. eine Datenbank und nicht in die Session.

              Grüße, Matze

              1. Meinst du damit das $_SESSION Array?
                Ja, das geht.

                Wäre das nicht irgendwie recht sinnfrei gegen CSRF?

                Nein, wieso? $_SESSION ist für den Angreifer nicht einsehbar.

                Bei CSRF geht es doch gerade darum, dass man die Session des Opfers ausnutzt.

                Bei CSRF kennt der Angreifer den Inhalt der Session nicht. Er nutzt lediglich aus, dass der gültiger Session-Cookie vorhanden ist und mit jedem HTTP-Request mitgesendet wird, auch wenn der Request von einer fremden Site initiiert wurde.

                Deshalb gehört der Token auch expliziet in die Formulare und z.B. eine Datenbank und nicht in die Session.

                Die Session = ein auf dem Server gespeicherter Datensatz, der unter der Session-ID gespeichert wird.

                Ob die Sessiondaten nun in einer Datenbank oder als Dateien im Datensystem gespeichert werden (wie PHP es meines Wissens standardmäßig macht), spielt keine Rolle.

                Manche Systeme speichern die Sessiondaten sogar im Cookie selbst und signieren und/oder verschlüsseln diesen mit einem auf dem Server gespeicherten Schlüssel. Auch das ist kein Problem an sich (solange man darin keine Daten speichert, die nicht einmal der eingeloggte Nutzer sehen darf). Der Angreifer kann den Cookie ja nicht lesen. Zumindest nicht ohne weitere Sicherheitslücken (z.B. XSS). Wenn der Cookie kompromittiert wird, dann ist der CSRF-Token ohnehin hinfällig.

                Natürlich muss der CSRF-Token in jedes Formular eingebunden werden und der Token aus dem Formular muss mit dem Token aus der Session überprüft werden.

                Grüße,
                Mathias

                1. Hallo!

                  Nein, wieso? $_SESSION ist für den Angreifer nicht einsehbar.

                  Wozu auch wenn er sich darauf verlassen kann, dass der Token dort drin steht?
                  Die Gefahr besteht dann wenn der Angriff auf der Seite mit dem Formular stattfindet.
                  Dann steht der Token nämlich in der Session und gleichzeitig im Formular.

                  Er nutzt lediglich aus, dass der gültiger Session-Cookie vorhanden ist und mit jedem HTTP-Request mitgesendet wird, auch wenn der Request von einer fremden Site initiiert wurde.

                  Genau. Und wenn der Token in der Session gespeichert ist, kann der Angreifer unter der Session Formulare absenden.

                  Wo ist mein Denkfehler?

                  Grüße, Matze

                  1. Hallo,

                    Nein, wieso? $_SESSION ist für den Angreifer nicht einsehbar.

                    Wozu auch wenn er sich darauf verlassen kann, dass der Token dort drin steht?

                    Er kann sich zumeist darauf verlassen, ja. So ist es schließlich in großen Web Application Frameworks implementiert.

                    Wo genau der Token serverseitig abgespeichert ist, ob in einer Datei oder in einer Datenbank, oder ob er sogar im Cookie steht, ist eigentlich irrelevant. Ohne weiteres kann eine fremde Site den Token eines Users nicht einsehen.

                    Die Gefahr besteht dann wenn der Angriff auf der Seite mit dem Formular stattfindet.
                    Dann steht der Token nämlich in der Session und gleichzeitig im Formular.

                    Von was für einen Angriff genau sprichst du. Reden wir noch von CSRF?

                    Und wenn der Token in der Session gespeichert ist, kann der Angreifer unter der Session Formulare absenden.

                    Durch CSRF kann der Angreifer zwar POST-Requests mit gewissen Formulardaten abschicken (z.B. ein POST-Request mit application/x-form-urlencoded). Bei reinem CSRF ist dem Angreifer der CSRF-Token aber nicht einsehbar. Also ist es ihm nicht möglich, den Token in die gefälschten Formulardaten zu schreiben. Der Browser sendet zwar automatisch den Cookie-Header mit der Session-ID, aber nicht den CSRF-Token. Der muss Teil des POST-Bodys sein (= der übertragenen Formulardaten).

                    Von XSS und MITM-Angriffen abgesehen kann ein Angreifer nicht Formulare auslesen und absenden, wie sie vom Ursprungsserver generiert werden. Im Browser kann ich nicht einfach eine andere Site in einem iframe laden, dort Quatsch in ein bestehendes Formular schreiben und es absenden. Das verhindert die Same-Origin-Policy. Ich kann nicht auf die DOM-Objekte der fremden Site zugreifen.

                    Wenn der Angreifer hingegen die Session-ID aus dem Cookie ergattern kann, hat er so gut wie gewonnen. Dann braucht er kein CSRF zu versuchen, welches ja immer ein Opfer benötigt, das mit seinem Browser die präparierte Site des Angreifers öffnet und gleichzeitig bei der Zielseite eingeloggt ist. Sondern er kann direkt Requests an die Zielseite schicken und die Session übernehmen.

                    Mir scheint, du unterliegst einem ähnlichen Missverständnis wie Norman.

                    Grüße,
                    Mathias

                    1. Hallo!

                      Von XSS und MITM-Angriffen abgesehen kann ein Angreifer nicht Formulare auslesen und absenden, wie sie vom Ursprungsserver generiert werden.

                      Ja, da war mein Denkfehler. Ein Angreifer könnte nicht ohne weiteres ein Formular mit dem selben Token wie in der Session absenden.

                      Danke auch für deine weiteren Erklärungen!

                      Grüße, Matze

  2. Hi,

    Ich würde gern wissen wie ich zuverlässig Session-hijacking verhindern kann.
    Ich erzwinge Sessions per Cookie aber was kann ich dagegen tun wenn jemand den Inhalt des Cookies weiter gibt (Session fixation ist bereits ausgeschlossen)?

    Du meinst *absichtlich*? Das wäre kein “Hijacking”.

    Ich würde die Session gern noch an weitere Daten koppeln damit die übernahme einer Session nicht nur von der ID anhängt.

    IP-Adresse (mit Vorsicht zu geniessen), Browser-Fingerprinting.

    Ein Ansatz wäre es, einen Token in einer Datenbank und der Session zu speichern und diese gegeneinander zu vergleichen.

    Was soll das nützen? Wenn ich an eine gültige Session-ID komme, findest du dazu in der Datenbank den Token – und vergleichst beide erfolgreich.

    Wie kann man also Session-hijacking zuverlässig verhindern? Oder ist das überhaupt möglich wenn man nichtmal den cookies vertraut?

    Wenn du wirklich von absichtlicher Weitergabe des Cookies redest – dann sind es deine Nutzer, denen du nicht vertraust.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Hi!

      Du meinst *absichtlich*? Das wäre kein “Hijacking”.

      Ich dachte da eher an eingeschleustes JavaScript oder Browserexploits.

      IP-Adresse (mit Vorsicht zu geniessen), Browser-Fingerprinting.

      Ja aber wie molily meinte, können sich die Daten ja auch während der Session ändern.

      Norman

      1. Moin!

        Du meinst *absichtlich*? Das wäre kein “Hijacking”.

        Ich dachte da eher an eingeschleustes JavaScript oder Browserexploits.

        Wenn man auf deiner Seite Javascript einschleusen kann, hast du ein viel größeres Problem als Session-Hijacking, nämlich Cross-Site-Scripting (XSS).

        Und durchgehend hast du das Problem von Cross-Site-Request-Forgery zu lösen (CSRF).

        Wenn du diese zwei Probleme angegangen bist, verbleibt von dem Session-Hijacking eigentlich nur noch das des schlechten Zufalls zum Generieren der Session-ID.

        IP-Adresse (mit Vorsicht zu geniessen), Browser-Fingerprinting.

        Ja aber wie molily meinte, können sich die Daten ja auch während der Session ändern.

        Der Browser-Fingerprint eher nicht, die IP eher schon - aber das ist irrevelant, wenn du als Bedrohungsszenario "eingeschleustes Javascript" annimmst, denn bei sowas wird die originale IP und der originale Browser des Opfers benutzt - das kannst du nicht serverseitig erkennen.

        Wenn du dir die OWASP Top 10 Liste von 2013 ansiehst, kriegst du ein Gefühl für die relevanten Probleme in Webapplikationen.

        - Sven Rautenberg

        1. Hi!

          Und durchgehend hast du das Problem von Cross-Site-Request-Forgery zu lösen (CSRF).

          Du meinst also ich sollte an jeden Link und in jedes Formular einen Token hängen, das Token in der Session speichern und bei jedem Request das Token des Links mit dem in der Session vergleichen?

          Wenn du dir die OWASP Top 10 Liste von 2013 ansiehst, kriegst du ein Gefühl für die relevanten Probleme in Webapplikationen.

          Danke für den Link, ich hoffe ich hab es richtig verstanden.

          Norman

          1. Hallo,

            Du meinst also ich sollte an jeden Link und in jedes Formular einen Token hängen, das Token in der Session speichern und bei jedem Request das Token des Links mit dem in der Session vergleichen?

            Nicht bei jedem Link, sondern bei jedem authentifizierten Request mit serverseitigen Nebeneneffekten.

            Genauer gesagt Anfragen auf URLs, die einen angemeldeten Nutzer und ggf. bestimmte Nutzerrechte erfordern sowie auf dem Server etwas ändern. Das sind üblicherweise Formulare zum Anlegen, Editieren oder Löschen von Datensätzen.

            Das bloße Anzeigen von Daten (z.B. GET /products/123) erfordert keinen Token, auch nicht das Durchsuchen von Datensätzen (z.B. GET /search?q=schrauben). Das Schreiben eines Datensatzes über ein Formular hingegen bedarf eines Tokens. Ansonsten könnte dieses Formular von einer fremden Website abgesendet werden und der reine Besuch der Websites des Angreifers könnte bei dir Datensätze erzeugen, editieren oder löschen.

            Bitte macht dich einmal im Web schlau, was CSRF genau bedeutet.

            Grüße,
            Mathias

            1. Hi!

              Das bloße Anzeigen von Daten (z.B. GET /products/123) erfordert keinen Token, auch nicht das Durchsuchen von Datensätzen (z.B. GET /search?q=schrauben).

              Aber wenn der Benutzer keine Leserechte hat?

              Bitte macht dich einmal im Web schlau, was CSRF genau bedeutet.

              Was hab ich denn hier falsch verstanden?

              Norman

              1. Aber wenn der Benutzer keine Leserechte hat?

                Dann prüfst du doch wohl intern die entsprechenden Rechte und gibst ne Fehlermeldung aus.  Wenn die Daten, die nicht gelesen werden sollen, bis zum Browser kommen, hast du ein Konzeptproblem auf dem Server, keins mit dem Client

              2. Hallo,

                Das bloße Anzeigen von Daten (z.B. GET /products/123) erfordert keinen Token, auch nicht das Durchsuchen von Datensätzen (z.B. GET /search?q=schrauben).

                Aber wenn der Benutzer keine Leserechte hat?

                Ob der angemeldete Benutzer ausreichend Rechte hat, um den angeforderten Inhalt anzusehen, musst du natürlich prüfen, ja. Dazu reicht der Session-Cookie, es bedarf keines weiteren Tokens. Ein zusätzlicher Token, den du vorher im Request-Body zum Client gesendet hast, verbessert die Sicherheit nicht, soweit ich das beurteilen kann. Wenn man das Prinzip des Session-Cookies zweimal anwendet, kommt nicht doppelte Sicherheit heraus.

                Das Überprüfen der Zugriffsrechte hat mit CSRF zu tun. Eine fremde Site kann den Browser dazu bringen, einen Request zu deiner Website abzusenden. Wenn der User bei dir authentifiziert ist, wird der gültige Session-Cookie mitgeschickt und deine Serversoftware glaubt, alles sei korrekt. Das ist nur dann gefährlich, wenn der Request Nebeneffekte hat. (Von Denial of Service einmal abgesehen.)

                Mathias

                1. Das Überprüfen der Zugriffsrechte hat mit CSRF zu tun.

                  • nichts :)
                  1. Hi!

                    Genauer gesagt Anfragen auf URLs, die einen angemeldeten Nutzer und ggf. bestimmte Nutzerrechte erfordern sowie auf dem Server etwas ändern.

                    Das Überprüfen der Zugriffsrechte hat [nichts] mit CSRF zu tun.

                    Du verwirrst mich! Machst du einen Unterschied zwischen Nutzer- und Zugriffsrechten?
                    Ich muss doch sowieso ständig prüfen welche Rechte ein Benutzer hat. Ich verstehe gerade nicht wieso ich da beim Lesen kein Token setzen soll, bei Formularen aber doch.
                    Und was für einen Unterschied macht es ob ich den Token als hidden field oder in der Session oder "per Hand" in einem Cookie speichere?

                    Norman

                    1. Ich muss doch sowieso ständig prüfen welche Rechte ein Benutzer hat.

                      Ja, aber das passiert auf dem Server nicht im Client.
                      Also ist es völlig egal, ob jemand die Session kapert, der Angreifer darf auch nur das, was der reaguläre User darf.

                      1. Hi!

                        Ja, aber das passiert auf dem Server nicht im Client.
                        Also ist es völlig egal, ob jemand die Session kapert, der Angreifer darf auch nur das, was der reaguläre User darf.

                        Und was bedeutet das jetzt? Sorry aber ich komme langsam überhaupt nicht mehr mit.
                        Wie muss ich meine Sessions denn nun absichern?

                        Norman

                        1. Und was bedeutet das jetzt? Sorry aber ich komme langsam überhaupt nicht mehr mit.
                          Wie muss ich meine Sessions denn nun absichern?

                          Nochmal: Die Absicherung der Session hat mit Leserechten auf dem Server nichts zu tun.

                          Sessionklau -> Clientproblem
                          Rechteprüfung -> Serverproblem

                          1. Hi!

                            Sessionklau -> Clientproblem
                            Rechteprüfung -> Serverproblem

                            Ach bin ich dumm... Ich glaub jetzt hab ich es verstanden. Die gelesenen Daten werden bei CSRF ja nie beim Angreifer landen. Es geht ja "nur" darum Daten über den eingeschleusten Request zu manipulieren. Zum Beispiel eine Überweisung tätigen. Dabei kann der Angreifer auch nur das machen wofür das Opfer entsprechende Rechte hat. Er könnte das Opfer also zwar "lesen lassen", das würde ihm aber nichts bringen weil er die Daten nie sehen wird.
                            Die Token-Prüfung ergibt also nur Sinn wenn durch einen Link oder ein Formular Daten geändert werden, der Token muss also auch nur dort angehängt werden.

                            Sorry, manchmal dauert es ebend ein bisschen länger bis man das Astloch im Brett vor dem Kopf gefunden hat und die Welt dahinter sieht.

                            Danke für eure Geduld!

                            Norman

                    2. Du verwirrst mich! Machst du einen Unterschied zwischen Nutzer- und Zugriffsrechten?

                      Nein.

                      Ich verstehe gerade nicht wieso ich da beim Lesen kein Token setzen soll, bei Formularen aber doch.

                      Das habe ich dir schon zweimal versucht zu erklären… falls ich es nicht schaffe zu vermitteln, was CSRF ist, so schaue dich bitte einmal selbst um.

                      CSRF = Beim Besuch einer fremden Website wird automatisch ein Request auf deinen Server gestartet. Das ist technisch möglich, ohne dass der Nutzer es merkt.

                      Wenn das nur ein Lesezugriff ist, der auf dem Server nichts verändert, ist das kein Sicherheitsrisiko.

                      Wenn die fremde Website aber ein Formular absendet, welches bei dir einen Datensatz erzeugt/ändert/löscht, ist das ein Sicherheitsrisiko. Denn der Benutzer könnte bei dir eingeloggt sein. Das ist CSRF und das muss man verhindern. Ein Cookie alleine tut das nicht!

                      CSRF funktioniert so:

                      1. Nutzer loggt auf example.com ein, Session-Cookie wird gesetzt. Jeder Request an example.com sendet nun den Cookie mit.
                      2. Nutzer besucht die Website des Angreifers attacker.example.net. Diese beinhaltet ein POST-Formular, welches http://example.com/delete-record als Ziel hat. Per JavaScript wird das Formular automatisch abgesendet.
                      3. Der Browser startet einen POST-Request zu example.com, ohne dass der Nutzer es merkt. Der Session-Cookie wird mitgesendet, die Session ist gültig und der Nutzer hat auch Schreibrechte.
                      4. Für die Software auf example.com sieht alles so aus, als wäre die Aktion vom Nutzer initiiert. Also wird im Beispiel ein Datensatz gelöscht. In Wirklichkeit wurde der Nutzer ausgetrickst.

                      Und was für einen Unterschied macht es ob ich den Token als hidden field oder in der Session oder "per Hand" in einem Cookie speichere?

                      Der Cookie wird automatisch bei jedem Request auf die Site, die den Cookie gesetzt hat, mitgesendet. Eine fremde Site kann einen Request auf deine Site erzeugen und der Cookie wird automatisch als Request-Header übermittelt. Das Vorhandensein des Cookies bedeutet nicht, dass der Nutzer die Aktion initiiert hat.

                      Eine fremde Site kann jedoch keinen Request erzeugen, welcher den Token im Request-Body übermittelt. Die fremde Website kann nämlich nicht an diesen Token kommen. (Es sei denn, es gibt z.B. eine XSS-Sicherheitslücke in deiner Site.) Wenn der Token also fehlt, liegt ein CSRF-Versuch vor.

                      Cookie im HTTP-Request-Header + Token im HTTP-Request-Body (z.B. in den Formulardaten) = Schutz vor CSRF

                      Mathias

                      1. Hi!

                        Wenn das nur ein Lesezugriff ist, der auf dem Server nichts verändert, ist das kein Sicherheitsrisiko.

                        Das sehe ich aber anders. Wenn Lesezugriffe kein Sicherheitsrisiko wären, bräuchten wir keinen Datenschutz. Ich hätte auch etwas dagegen wenn eine beliebige Person meine Kontodaten einsehen könnte - auch ohne etwas zu buchen.

                        CSRF funktioniert so:

                        Das habe ich schon verstanden aber die weiteren Erklärungen hier verwirren mich halt mehr als sie mich weiter bringen :/
                        Ich sehe ja sicherheitstechnisch keinen Unterschied zwischen lesen und einer beliebigen anderen Aktion. Insofern müsste ich den Token also doch an jeden Link hängen bzw. könnte er auch ins action-Attribut anstatt in ein hidden field eines Formulars.

                        Norman

                        1. Ich hätte auch etwas dagegen wenn eine beliebige Person meine Kontodaten einsehen könnte - auch ohne etwas zu buchen.

                          Du hast immer noch nicht verstanden, was Client- und was Serverseitig passiert. Erst wenn du das verstanden hast, wirst du dein Problem lösen.

      2. Du meinst *absichtlich*? Das wäre kein “Hijacking”.

        Ich dachte da eher an eingeschleustes JavaScript oder Browserexploits.

        Du wirfst verschiedene Angriffszenarien durcheinander. Cross-Site-Scripting (XSS), das besagte CSRF und Session-Hijacking sind verschiedene Dinge. XSS ist eingeschleustes JavaScript und damit verbunden eingeschleustes HTML und CSS. CSRF ist das Senden von scheinbar autorisierten Requests von fremden Websites aus. Session-Hijacking ist z.B. wenn ein Angreifer in einem ungesicherten WLAN die Cookies von anderen mitliest, etwa mit Firesheep.

        XSS und CSRF sind weitaus häufiger und einfacher als Session-Hijacking über derartige Man-in-the-middle-Attacks. Und gegen Browserexploits kannst du auf deiner Website wenig tun. Wenn der Angreifer den Browser unter Kontrolle hat, kann alles, was den Server erreicht, gefälscht sein, und der Nutzer kann durch den Angreifer getäuscht worden sein.

        Mathias

  3. Ich erzwinge Sessions per Cookie [...]

    Zum eigentlichen Thema kann ich nicht viel sagen, da ich eher Halbwissen/Vermutungen hab als alles andere.

    Aber ich habe mal eine Frage:

    Mir ist nach und nach aufgefallen, dass wenn es um Sessions und Sicherheit geht, dass meist im Startpost erwähnt wird, dass die Session-ID als Cookie gespeichert ist.

    Macht das wirklich einen Unterschied, ob die Session-ID als Cookie oder als GET-/POST-Parameter übetragen wird? Im Endeffekt steht sie doch generell irgendwie im Request drin oder?

    Dem zur Folge wäre doch die eigentliche effektive (mit bösen Nebeneffekten) Methode nach jedem Request eine neue Session-ID zu generieren oder? (Unter paranoider Betrachtung wäre ja noch nicht mal das 100% sicher)

    MfG
    bubble

    --
    If "god" had intended us to drink beer, he would have given us stomachs. - David Daye
    1. Dem zur Folge wäre doch die eigentliche effektive (mit bösen Nebeneffekten) Methode nach jedem Request eine neue Session-ID zu generieren oder?

      Was sollte das denn bringen? Wenn jemand mitliest,ist es völlig egal ob die Session bleibt oder sie 10mal in der Sekunden wechselt, gekapert wird die immer.

      1. Dem zur Folge wäre doch die eigentliche effektive (mit bösen Nebeneffekten) Methode nach jedem Request eine neue Session-ID zu generieren oder?
        Was sollte das denn bringen? Wenn jemand mitliest,ist es völlig egal ob die Session bleibt oder sie 10mal in der Sekunden wechselt, gekapert wird die immer.

        Naja, das war mein Gedankengang:
        Bei jedem Request, bedeutet ja quasi, wenn der Angreifer zb. via Bruteforce doch mal eine gültige ID gefunden hat, die Seite aufruft und eine neue Session-ID bekommt. Wenn der eigentliche Benutzer dann aber auf einen Link klickt oder irgendwie sonst ein Request verursacht, wird er wohl ein Login-Formular zu Gesicht bekommen, sich neu einloggen, damit ist die gekaperte Session-ID auch wieder hinfällig und der Angreifer/sein Programm würde nur noch das Login-Formular zu Gesicht bekommen und müsste erneut mit Bruteforce auf die Suche gehen. Quasi hat der Angreifer nur die Zeit sein eigenes Ziel zu verfolgen, während der ursprüngliche Besitzer nichts tut bzw. noch nicht neu eingeloggt hat.

        Trifft natürlich nur zu solange wie der Angreifer nur raten kann, wenn er allerdings die Session-ID direkt vom eigentlichen Benutzer kommt, kann man da gegen als Seitenbetreiber eh nichts mehr machen.

        MfG
        bubble

        --
        If "god" had intended us to drink beer, he would have given us stomachs. - David Daye
        1. Hallo,

          Bei jedem Request, bedeutet ja quasi, wenn der Angreifer zb. via Bruteforce doch mal eine gültige ID gefunden hat, die Seite aufruft und eine neue Session-ID bekommt. Wenn der eigentliche Benutzer dann aber auf einen Link klickt oder irgendwie sonst ein Request verursacht, wird er wohl ein Login-Formular zu Gesicht bekommen, sich neu einloggen, damit ist die gekaperte Session-ID auch wieder hinfällig […]

          Wenn ich dich richtig verstehe, würde alleine das parallele Öffnen von Seiten derselben Domain in Tabs – aus Seite A werden B und C in zwei Tabs geöffnet – einen falschen Alarm erzeugen. C würde mit der Session-ID von A anstatt der von B angefordert werden würde, was deinem Model zufolge die Sessions zerstören würde.

          Solch ein Vorgehen widerspricht Grundprinzipien von HTTP. HTTP kennt eben nativ keine synchronen Verbindungen bzw. Sitzungen, daher lässt sich die Anforderung, dass eine Ressource immer mit exakt dem Token aufgerufen werden muss, der im jeweils vorherigen Request übertragen wurde, schwer realisieren.

          Mathias

          1. Wenn ich dich richtig verstehe, würde alleine das parallele Öffnen von Seiten derselben Domain in Tabs – aus Seite A werden B und C in zwei Tabs geöffnet – einen falschen Alarm erzeugen. C würde mit der Session-ID von A anstatt der von B angefordert werden würde, was deinem Model zufolge die Sessions zerstören würde.

            Ja, das wäre der "böse Nebeneffekt". Wobei ich mir da nun auch nicht 100%ig sicher bin, ob das bei Cookies auch der Fall ist. Angenommen die ID-Änderung wäre ein bloßes Inkrementieren, öffnet Tab A, bekommt SID=1, öffnet von Tab B, bekommt SID=2, würde der Browser dann, wenn man von Tab A Tab C öffnet dann SID=1 schicken, weil es zu der Zeit ja SID=1 war, oder die aktuelle SID=2? (Das würde allerdings auch wieder spätestens dann schief laufen, wenn man nicht wartet bis Tab B geladen ist)

            MfG
            bubble

            --
            If "god" had intended us to drink beer, he would have given us stomachs. - David Daye
            1. Hallo,

              öffnet Tab A, bekommt SID=1, öffnet von Tab B, bekommt SID=2, würde der Browser dann, wenn man von Tab A Tab C öffnet dann SID=1 schicken, weil es zu der Zeit ja SID=1 war, oder die aktuelle SID=2?

              Beides ist möglich. Es hängt davon ab, ob B fertig geladen und verarbeitet wurde, bevor die Anfrage zu C geschickt wird. In meinem Szenario werden B und C kurz nacheinander geschickt. Es wird also nicht auf die Antwort für B gewartet. Das kann beim normalen Surfen durchaus passieren.

              Wenn B einen Cookie setzt, wird der natürlich bei der Anfrage zu C mitgesendet, wenn diese nach dem Empfangen und Verarbeiten von B angesendet wird.

              Mathias

    2. Hallo,

      Macht das wirklich einen Unterschied, ob die Session-ID als Cookie oder als GET-/POST-Parameter übetragen wird?

      Ja, es macht einen Unterschied. Siehe z.B. Session Fixation.

      Im Endeffekt steht sie doch generell irgendwie im Request drin oder?

      Ja, aber sie sollte nicht in der URL stehen.

      Dem zur Folge wäre doch die eigentliche effektive (mit bösen Nebeneffekten) Methode nach jedem Request eine neue Session-ID zu generieren oder?

      Was sollte das bringen? Wenn ich eine Session-ID habe, kann ich so die nächste bekommen.

      Mathias

      1. Macht das wirklich einen Unterschied, ob die Session-ID als Cookie oder als GET-/POST-Parameter übetragen wird?
        Ja, es macht einen Unterschied. Siehe z.B. Session Fixation.

        Ahh, den Begriff hab ich irgendwie überlesen :s

        Dem zur Folge wäre doch die eigentliche effektive (mit bösen Nebeneffekten) Methode nach jedem Request eine neue Session-ID zu generieren oder?
        Was sollte das bringen? Wenn ich eine Session-ID habe, kann ich so die nächste bekommen.

        In meinem anderen Post hab ich schon geschrieben, was mein Gedankengang war.

        MfG
        bubble

        --
        If "god" had intended us to drink beer, he would have given us stomachs. - David Daye
      2. Hi!

        Was sollte das bringen? Wenn ich eine Session-ID habe, kann ich so die nächste bekommen.

        Vielleicht nicht unbedingt bei jedem Request, aber hier und hier hab ich auch gelesen, dass eine neue Session-Id session fixation verhindert. Irgendwo stand auch noch der Zusatz, dass man das auch bei jedem Request machen könne, die Seite finde ich aber leider gerade nicht mehr.

        Was ist da also dran?

        Norman