Moin!
Spontan würde mir aber als weg einfallen, User Agent und Remote Address in der Session zu speichern und bei jedem Request zu vergleichen
Ein User ist nicht eindeutig einer IP-Adresse zuzuordnen. Eine Session ist nicht einmal eindeutig einem User-Agent zuzuordnen.
Ja, aber als Angreifer, Session-ID, UA und IP-Adresse zu erraten, selbst wenn es nur UA & IP-Adresse ist, sollte doch sehr unwahrscheinlich sein, oder?
100% risikofrei gibt es sowieso nicht.
Die Sicherheit bei Nutzung von "Sessions" kommt primär aus a) dem sehr großen Zahlenbereich möglicher IDs, aus dem möglichst kryptographisch zufällig eine ausgewählt wird (macht es unmöglich, die ID zu erraten) b) dem Abschotten dieser Information während der Kommunikation zwischen Browser und Server.
Aus diesem Grund b) will man die Session-ID ausschließlich per Cookie übertragen (das Cookie kommt nicht unabsichtlich in Links und Formulardaten vor), und auch niemals eine Session-ID aus anderen Quellen als Cookies akzeptieren (PHP könnte so konfiguriert werden, dass eine Session-ID beim ersten Request im Link drinsteht, danach ins Cookie geschoben wird).
Weiterhin wird man zur Absicherung der Session nach dem Erhöhen des Rechte-Levels einer Session (üblicherweise der Login - vorher ist man anonym und kann nichts, hinterher hat man z.B. Schreibrechte auf seine Accountdaten) eine neue Session-ID generieren und die Session unter dieser neuen ID mit den erhöhten Rechten fortsetzen, um zu verhindern, dass doch irgendwie die vorherige ID bekannt geworden ist.
Und das Session-Cookie selbst sollte auch bestmöglich abgesichert werden. Es gibt dazu ein paar Stellschrauben: Definitiv sollte es HTTP-only sein (Javascript braucht die Session nie für legitime Zwecke wissen, bei Ajax-Requests wird es ja automatisch wieder mitgeschickt), idealerweise auch "secure" (also SSL/TLS benutzen). Weiterhin sollte man vermeiden, die Cookie-Domain allzu freizügig zu wählen, denn bei der Nutzung von Wildcard-Domains steigt die Zahl der möglicherweise gehackten Server, die das Cookie evtl. unbeabsichtigt erfahren, enorm. Man sollte genau die Domain für das Cookie erlauben, auf der sich die Applikation befindet. Befinden sich mehrere Applikationen auf demselben Server, die parallel verschiedene Sessions benutzen, sollte man auch den Pfad, bei dem das Cookie mitgesendet wird, entsprechend auf seinen eigenen Pfad eingrenzen:
http://de1.php.net/manual/de/function.session-set-cookie-params.php
session_set_cookie_params(0, '/the_app', 'www.example.com', false, true);
In der Reihenfolge der Parameter:
0 - Timeout des Cookies, hier: Bis der Browser geschlossen wird. Es gibt vielleicht Gründe, hier eine explizite Zeit anzugeben, aber man sollte sich der Konsequenzen daraus bewußt sein. Es hilft jedenfalls nicht im Hinblick auf die Sicherheit.
'/the_app' - Pfad der Applikation. Wenn ALLE Requests, die mit Session zu tun haben, sich im Pfad mit diesem Anfangsverzeichnis abspielen, kriegt ein Skript außerhalb des Pfades das Cookie nicht.
'www.example.com' - die Domain, auf der die Session gelten soll. Für Sessions übergreifend über mehrere Subdomains würde hier sowas wie '.example.com' stehen und das Risiko erhöhen.
false - Secure-Flag verhindert, dass das Cookie gesendet wird, wenn der Browser keine HTTPS-Verbindung benutzt. Wenn man also kein SSL hat, will man das Flag nicht setzen, sonst würde nichts funktionieren. Andererseits will man es unbedingt setzen, wenn man ausschließlich SSL benutzen kann.
true - HTTP-only-Flag verhindert, dass Javascript an das Cookie rankommt. Will man immer haben.
Wenn es um Sicherheit geht, sollte man nicht versuchen, etwas eigenes zu erfinden, es sei denn, man hat sich intensiv mit vorhandenen Lösungen auseinandergesetzt. Sonst kommt etwas heraus, das tausendmal unsicherer ist als bewährte Lösungen.
Ich möchte eben nichts neues erfinden, sondern wissen wie ich es am besten mache.
Aus deinem Post interpretier ich, dass Session-Cookies schlimm genug sind und ich lieber kein Fallback via GET-Parameter machen soll. (Jede Seite als Antwort als POST-Request fällt ja sowieso aus)
Session-Cookies sind eigentlich kein soo schlimmes Problem, aber man muss in PHP schon einiges an Extra-Arbeit und -Konfiguration leisten, um eine bessere Sicherheit zu erhalten. Für Applikationen ohne SSL-Verschlüsselung dürfte das zwar nicht viel helfen, weil es sowieso unsicher ist, aber es hebt das Schutzniveau zumindest etwas.
Ganz fatal sind jedenfalls Session-IDs, die in Links und Formularen übertragen werden, oder vom Server darin akzeptiert werden. Dann kann ein Angreifer eine ihm bekannte Session-ID in einen Link schreiben und jemandem zumailen, und kann dann die Session übernehmen.
- Sven Rautenberg