Braucht man eine "richtige Server-Session" für Cookie-basierte Authentifizierung?

alinnert

Mitglied
Ich mach mir schon eine ganze Zeit lang Gedanken darüber, wie man eine simple Benutzername-Passwort-gestützte Authentifizierung für http-APIs umsetzt. Ich hab dabei gerade einen Gedankengang, bei dem ich mir aber nicht 100%ig sicher bin, ob es da sicherheitstechnische Probleme gibt. Mein Gedankengang ist folgender:

Bei einem erfolgreichen Login würde ich ein httpOnly-Cookie mit einer ID setzen. Datenbankseitig stell ich eine Verbindung zwischen der ID und dem Nutzer her. So weiß ich beim Auslesen des Cookies über die Datenbank, welcher Nutzer den Request abgesetzt hat. Beim Ausloggen wird das Cookie gelöscht. Das Cookie-TTL beschränkt die maximale Login-Dauer (führt ggf. zu automatischem Logout). Die ID-Benutzer-Verbindungen müssen dann natürlich immer wieder gesäubert werden, damit keine Datensatzleichen entstehen.

Ich bin es nur gewohnt, dass man für Logins in PHP beispielsweise immer PHP-Sessions verwendet. Für so ziemlich jedes Framework gibt es auch spezielle Session-Middlewares. Bei meinem Gedankengang verwende ich aber keine Session im klassischen Sinne. Es ist viel mehr eine selbst implementierte Mini-Session.

Dadurch frag ich mich jetzt primär: Machen die Session-Libraries/-Middlewares etc. irgendwas großartiges, um die Sicherheit einer Anwendung zu erhöhen? Überseh' ich da irgendwas? Oder ist der einzige Mehrwert, dass man zusätzliche temporäre Daten für eine Session speichern kann? Dafür hätte ich bei meinem Projekt nämlich keinen Verwendungszweck. Wenn ich mir das sparen und stattdessen direkt mit dem Cookie interagieren kann, spar ich mir den Ärger mit den Session-Libraries, da sie dann nur Overhead sind.

Edit ‒ Hintergrund der Frage

Ich hab vergleichsweise große Probleme mit den Session-Implementierungen. Entweder sie funktionieren bei meinen Tests nicht (Go, Gorilla Session Package), oder es gibt keinen einfachen Store für kleinere Anwendungen, der anständig weiterentwickelt wird (SQLite, JSON-File..., ich möchte auf eine externe Datenbank verzichten) oder die Doku zum Implementieren eines eigenen Stores ist unvollständig, sodass ich nicht weiß, wie eine Implementierung überhaupt aussieht. Im Falle von Node.js braucht es auch eine funktionierende Type-Definition, da ich mit TypeScript arbeiten möchte.
Das hat mich alles so sehr frustriert, dass ich meine Anforderungen analysiert und aufs Notwendigste runtergebrochen hab. Dabei kam ich dann auf den Trichter: Alles, was ich brauche ist eine ID in einem Cookie und eine Verbindung zwischen den IDs und Benutzerkonten. Den Session-Store, also Session-Variablen, brauch ich gar nicht. Das klingt halt erstmal super simpel. Aber bevor ich das implementiere, möchte ich herausfinden, ob das sicherheitstechnisch überhaupt sinnvoll ist, oder ob ich mir das zu einfach vorstelle.
 
Zuletzt bearbeitet:
Die Libraries nehmen dir viele Sicherheitsüberlegungen und die Sessionverwaltung ab und packen in der Regel von Haus aus sinnvolle Einschränkungen in die Header der Responses. Bei Frameworks haste dann noch aktionsgebundene Nonces/Token und anderen Formularschutz + Validierung. Aber das sind alles natürlich Dinge, die man auch selber implementieren kann.

So von deiner Beschreibung her fallen mir spontan erstmal keine Sicherheitsbedenken ein, außer natürlich dem Standardproblem: Selber implementieren = höhere Chance, dass man etwas vergisst

Weil zum Beispiel Cookieheader vom Client beliebig gesetzt und manipuliert werden können, musst du aufpassen, dass da keiner durch Enumeration oder Abfangen der ID Aktionen im Namen eines anderen Users durchführen kann. Auch könnte es zu unvorhergesehenen Nebeneffekten bei den ID-Vergaben und Cookie-Löschungen kommen und du musst darauf achten, dass die IDs auch bei Leichen und einer großen Anzahl von Sessions immer noch eindeutig zugeordnet werden können.

Sicherheitseinstellungen und Cookies kann man zum Glück zum Großteil mit automatisierten Scans finden. Gibt viele Tools bei Kali und auch einige Online-Scanner. Mit denen kann man auch nach etwas Einarbeitung ganz gut manuelle Tests durchführen.

Grad noch gesehen, dass die OWASP-Seite neues Design und neuen Inhalt hat:
https://owasp.org/www-project-web-s...ing/06-Session_Management_Testing/README.html
(hab's nur überflogen, aber das deckt wohl alle wichtigen Punkte ab und hat sogar Tool-Empfehlungen)
 
Man muss halt auch bei einem grundsätzlich einfachen Mechanismus alles beachten, von der Vermeidung von Session Poisoning bis zur Session-Erneuerung bei Privilegienänderung. Dazu kann ich dieses Cheatsheet empfehlen: Session Management
 
Ok, ich geh mal alle erwähnten Punkte Schritt für Schritt durch. Bitte Feedback geben, wenn ich irgendwo falsch liege.

@Mat

aktionsgebundene Nonces/Token
Meinst du diese hier? Kam mir jetzt noch nicht unter. Auch nicht während der Verwendung von diversen Frameworks oder beim Lesen von Dokumentationen. Wie sieht sowas denn "aktionsgebunden" und in Verbindung mit APIs aus?
Ist das auf Wikipedia im Bild dargestellte Beispiel bei https noch notwendig? Lt. den Infos, die ich bisher aufgesammelt hab, kann man bei einer https-Verbindung Passwörter ohne Probleme im "Klartext" übertragen. Oder verhindert das andere Arten von Angriffen? Das ist von Sessions jetzt zwar unabhängig, aber vllt. dennoch ein wichtiger Punkt.

Formularschutz + Validierung
Ist das nicht ein von Sessions unabhängiger Bestandteil von Frameworks bzw. aus externen Bibliotheken? Mir geht es, wie gesagt, nur um die Session-Funktionalität und um den Session-Store. Ohne Framework und Bibliotheken werde ich definitiv nicht arbeiten.

"...Cookieheader vom Client beliebig gesetzt und manipuliert werden können..."
Das lässt sich doch einfach mit httpOnly-Cookies lösen. Diese können clientseitig weder gelesen noch geschrieben werden. Oder meinst du was anderes?

Was meinst du mit Kali? Aber nicht die hinduistische Götten des Todes und der Zerstörung, oder? :D Kali Linux? Das klingt interessant. Werd ich mir bei Gelegenheit mal anschauen. Und danke für den Link. Ich kenne OWASP zwar schon, aber noch nicht den Bereich der Seite.

@dominik

Session Poisoning
Das geht doch nur bei der Verwendung von Session-Variablen, oder? Die hätte ich nämlich nicht. Das würde somit einen ganzen Angriffsvektor eliminieren. Oder beinhaltet das auch die Manipulation meiner eigenen Session-User-Zuordnungen?

Session-Erneuerung bei Privilegienänderung
Da hab ich mit Session-Bibliotheken aber den gleichen Aufwand, oder nicht? Bei beiden Fällen muss ich aktiv etwas tun.

Eine Sache ist halt auch: Beim Durchsuchen des Quellcodes von einigen Session-Implementierungen ist mir aufgefallen, dass die alle äußerst minimalistisch sind. Einen speziellen Angriffsschutz hab ich da bisher noch nicht gefunden. Ich werde da aber noch weiterforschen.
 
Das geht doch nur bei der Verwendung von Session-Variablen, oder? Die hätte ich nämlich nicht.

Dann theoretisch nicht.

Da hab ich mit Session-Bibliotheken aber den gleichen Aufwand, oder nicht? Bei beiden Fällen muss ich aktiv etwas tun.

Ja, daran musst du auch bei der Verwendung einer Library denken. Jede vernünftige Session-Library bietet dir das allerdings out of the box an und du musst es nicht wieder selbst implementieren. Deshalb nehme ich Session-Libraries (nur OSS) als externe Dependency gerne in Kauf, auch weil Sicherheitslücken bei einer öffentlichen Library viel schneller als bei eigenen Implementierungen auftauchen.
 
aktionsgebundene Nonces/Token
Meinst du diese hier? Kam mir jetzt noch nicht unter. Auch nicht während der Verwendung von diversen Frameworks oder beim Lesen von Dokumentationen. Wie sieht sowas denn "aktionsgebunden" und in Verbindung mit APIs aus?
Ist das auf Wikipedia im Bild dargestellte Beispiel bei https noch notwendig? Lt. den Infos, die ich bisher aufgesammelt hab, kann man bei einer https-Verbindung Passwörter ohne Probleme im "Klartext" übertragen. Oder verhindert das andere Arten von Angriffen? Das ist von Sessions jetzt zwar unabhängig, aber vllt. dennoch ein wichtiger Punkt.
Ah.. mir gings hauptsächlich um Einweg-Nummern. Aber ich habe mich dabei nicht auf Sessions, sondern Vorteile von Frameworks im Allgemeinen bezogen, weil ich fälschlicherweise davon ausging, dass du komplett auf Frameworks verzichten und die gesamte Sicherheit selbst implementieren willst.

Formularschutz + Validierung
Ist das nicht ein von Sessions unabhängiger Bestandteil von Frameworks bzw. aus externen Bibliotheken? Mir geht es, wie gesagt, nur um die Session-Funktionalität und um den Session-Store. Ohne Framework und Bibliotheken werde ich definitiv nicht arbeiten.
Siehe oben. Was Session-Implementierungen angeht, so hat man bei Frameworks in der Regel die freie Wahl zwischen Memory, DB, File Based usw.. Hast ja schon an anderer Stelle geschrieben, dass du dir verschiedene Session-Implementierungen angesehen hast. Wenn sie dir zu viel Overhead haben, kannst du im Idealfall in der Konfiguration beim Framework deinen eigenen SessionManager hinterlegen.

"...Cookieheader vom Client beliebig gesetzt und manipuliert werden können..."
Das lässt sich doch einfach mit httpOnly-Cookies lösen. Diese können clientseitig weder gelesen noch geschrieben werden. Oder meinst du was anderes?
Hm? Wie soll das gehen? Ein Cookie, das nur auf deinem Server liegt? Wie wird der Client authentifiziert? Quantenverschränkung? Magnete? Aliens? Es muss ja vom Client gelesen werden, um anschließend bei der Request vom Client gesendet werden zu können. Ich glaube, du meinst nur Schutz gegen clientseitiges JS, aber Requests können vor dem Versenden bearbeitet werden. Traue den Cookie-Headern nicht, die du erhältst. Oder ich hab dich wieder falsch verstanden.

Was meinst du mit Kali? Aber nicht die hinduistische Götten des Todes und der Zerstörung, oder? :D Kali Linux? Das klingt interessant. Werd ich mir bei Gelegenheit mal anschauen. Und danke für den Link. Ich kenne OWASP zwar schon, aber noch nicht den Bereich der Seite.
Ja genau, oder halt ParrotOS. Also die Hindu-Göttin oder der Papagei. Die sind ganz gut, wenn du dir nicht selbst die Tools zusammensuchen willst. Was Request-Manipulation angeht, gibt's bei Windows z. B. Fiddler (ich glaube das hieß so).
 
Aber ich habe mich dabei nicht auf Sessions, sondern Vorteile von Frameworks im Allgemeinen bezogen, weil ich fälschlicherweise davon ausging, dass du komplett auf Frameworks verzichten und die gesamte Sicherheit selbst implementieren willst.

Ja, ne. So wahnsinnig bin ich dann doch nicht :LOL:

Zum Hintergrund der Frage vielleicht:
Ich hab vergleichsweise große Probleme mit den Session-Implementierungen. Entweder sie funktionieren bei meinen Tests nicht (Go, Gorilla Session Package), oder es gibt keinen einfachen Store für kleinere Anwendungen, der anständig weiterentwickelt wird (SQLite, JSON-File..., ich möchte auf eine externe Datenbank verzichten) oder die Doku zum Implementieren eines eigenen Stores ist unvollständig, sodass ich nicht weiß, wie eine Implementierung überhaupt aussieht. Im Falle von Node.js braucht es auch eine funktionierende Type-Definition, da ich mit TypeScript arbeiten möchte.
Das hat mich alles so sehr frustriert, dass ich meine Anforderungen analysiert und aufs Notwendigste runtergebrochen hab. Dabei kam ich dann auf den Trichter: Alles, was ich brauche ist eine ID in einem Cookie und eine Verbindung zwischen den IDs und Benutzerkonten. Den Session-Store, also Session-Variablen, brauch ich gar nicht. Das klingt halt erstmal super simpel. Aber bevor ich das implementiere, möchte ich herausfinden, ob das sicherheitstechnisch überhaupt sinnvoll ist, oder ob ich mir das zu einfach vorstelle.

Ich werd das vllt. oben im ersten Post noch hinzufügen, da das ggf. ne wichtige Info ist.

Zum Cookie: ok, dann meinst du, dass man Cookies generell nicht trauen kann. Dazu braucht es aber wohl schon spezielle Software, weil ein Browser keine httpOnly-Cookies setzen kann. Da muss am Server dann sichergestellt werden, dass das Cookie wirklich vom Server erstellt wurde. Das dürfte ein Punkt sein, wo mir Session-Bibliotheken diese Arbeit abnehmen. Andererseits klingt das auch nicht schwierig selbst umzusetzen. Dahingehend könnt ich Bibliotheken aber auch mal näher untersuchen.

Edit
Hm, ich wenn aber weiter so drüber nachdenk, ist die manuelle Verbindung zwischen Session-ID und den Benutzern ja nichts anderes als ein eigener Session-Store... :unsure: also über eine eigene Session-Store-Implementierung könnte ich genau das umsetzen, und zwar auch so wie ich das möchte. Ich glaube, ich werd doch nochmal in die Richtung weiterprobieren... Schade eigentlich. :LOL: Aber dann weiß ich zumindest, dass ich mich erstmal auf eigene Implementierungen konzentrieren werd.
Danke trotzdem für eure Zeit und Input. Einiges davon werd ich ja in jedem Fall brauchen können.

Edit 2
Weil "Eigene Session-Store-Implementierung" so zweideutig klingt: Ich meine eine eigene Session-Store-Anbindung. Viele Session-Libraries bieten hier ja eine API an. Diese werd ich dafür nutzen, oder zumindest versuchen zu nutzen.
 
Zuletzt bearbeitet:
Zum Cookie: ok, dann meinst du, dass man Cookies generell nicht trauen kann. Dazu braucht es aber wohl schon spezielle Software, weil ein Browser keine httpOnly-Cookies setzen kann. Da muss am Server dann sichergestellt werden, dass das Cookie wirklich vom Server erstellt wurde.
Ich glaube nicht, dass Browser ihre JS-VM benutzen, um Cookies zu schreiben. Das wird ganz normal über HTTP laufen. Sie müssen die Cookies ja lesen und schreiben können, sonst haben sie nix davon. Und in den Header können sie alles setzen, was das Protokoll hergibt. httpOnly schützt vielleicht den User vor Dritten, aber nicht den Server vor dem User.

Spezielle Software? Nein, curl oder Invoke-Webrequest reicht schon für einfache Fälle. Auslesen zum Beispiel:

Code:
(Invoke-Webrequest -UseBasicParsing -Method Head -Uri https://dev-community.de).Headers

Key                       Value
---                       -----
X-Frame-Options           SAMEORIGIN
X-Content-Type-Options    nosniff
Strict-Transport-Security max-age=31536000; includeSubDomains
X-XSS-Protection          1; mode=block
Referrer-Policy           no-referrer-when-downgrade
Connection                keep-alive
Content-Length            116286
Cache-Control             private, no-cache, max-age=0
Content-Type              text/html; charset=utf-8
Date                      Tue, 12 May 2020 22:00:00 GMT
Expires                   Thu, 19 Nov 1981 08:30:00 GMT
Last-Modified             Tue, 12 May 2020 22:10:00 GMT
Set-Cookie                xf_csrf=abcdefghijklmnop; path=/; secure; HttpOnly; Secure; SameSite=Strict
Server                    Apache


Der Browser sieht anfangs das gleiche und folgt in diesem Beispiel der Anweisung, entsprechende Cookies zu setzen und clientseitig ausgeführtes JS daran zu hindern, die gesetzten Cookies auszulesen und den Cookie-Header zu bearbeiten. Diese Cookies werden dann bei Requests durch den Browser wieder an den Server geschickt. Durch HttpOnly fallen viele JS-Angriffsvektoren auf den User weg, durch TLS wird der Transportweg geschützt. Vorher kann aber vieles mit dem Header der Request passieren, besonders dann, wenn der User der Angreifer ist.

Das ist dann durchaus leichter, wenn man dafür spezielle Programme benutzt, die als Proxy zwischengeschaltet werden, was dir mehr Kontrolle über die Requests an den Server und die im Browser ankommenden Responses gibt. Z. B.:


Und ja genau, da muss dann der Server entscheiden, was er akzeptiert und was nicht.
 
Zurück
Oben Unten