PHP Session Hijacking erschweren

Smssam

Well-known member
ID: 425675
L
6 November 2011
2.790
247
In letzter Zeit habe ich mir Gedanken gemacht, wie ich bei einem Login Script das Session Hijacking erschweren kann, folgender Gedanke kreiste hierbei in meinem Kopf:

Neben einer gestarteten Session wird noch ein Cookie gesetzt (wenn Login erfolgreich), das Dokument überprüft dann die Gültigkeit der Session und auch des Cookies und gestattet dann einem bei Korrektheit den Zugriff auf den geschützten Bereich.

Wenn jetzt jemand erfolgreich eine gültige Session ID "gekappert" hat, erlangt doch dieser dann kein Zugriff auf das Dokument, da ihm das gültige Cookie fehlt, was nur gesetzt wird wenn die Nutzername + Passwort abfrage mit Erfolg verlaufen ist.

Edit: Um zu verdeutlichen was ich vorhabe, hier eine vereinfachte Darstellung:
Code:
Wenn Login erfolgreich -> Session & Cookie setzen -> Wenn Session & Cookie gesetzt und gültig -> Zugriff auf geschütztes Dokument - anderenfalls Fehlschlag.

Nun zu meiner Frage, erschwert diese Maßnahme den Zugriff wirklich oder habe ich was übersehen/nicht bedacht so das ich hier einen Rohrbruch mit einer Packung Tempos zu verhindern versuche?
 
Zuletzt bearbeitet:
Folgende Situationen fallen mir spontan ein:

  • Cookies werden gelöscht
  • Browser akzeptiert keine Cookies
  • Cookies lassen sich fälschen

Vielleicht hilft dir das weiter...
 
Hi,

ich Verstehe jetzt nicht genau was du wirklich vorhast, aber Cookies löschen ist wohl das sinnvollste.
 
Erstmals danke für die Antworten ;)

Folgende Situationen fallen mir spontan ein:

  • Cookies werden gelöscht
  • Browser akzeptiert keine Cookies
  • Cookies lassen sich fälschen

Vielleicht hilft dir das weiter...

Es geht hier um ein Admin Interface, ich werde daher die Cookies in meinen Einstellungen zulassen, aber dennoch wäre dies irrelevant. Da die Session als Cookie wiedergegeben wird...

Cookies lassen sich fälschen das ist mir bewusst, aber da der Angreifer den Inhalt des Cookies nicht kennt, ist es somit ein weiterer Stolperstein der einen Fremdzugriff erschweren sollte (theoretisch).
Hi,

ich Verstehe jetzt nicht genau was du wirklich vorhast, aber Cookies löschen ist wohl das sinnvollste.

Ich will keine löschen sondern eins setzen neben einer Session um Hijacking zu erschweren. Damit es verständlicher wird hier ein kurzes vereinfachtes Schema:

Aktuell:
Code:
Wenn Login erfolgreich -> Session setzen -> Wenn Session gesetzt und gültig -> Zugriff auf geschütztes Dokument - anderenfalls Fehlschlag.

Nun kann man aber die Session ID "knacken" und somit können unbefugte Zugriff auf das geschützte Dokument erlangen, daher war ja mein Gedanke dies zu erschweren in dem ich zusätzlich noch ein Cookie setze.

Daher Vorschlag:
Code:
Wenn Login erfolgreich -> Session & Cookie setzen -> Wenn Session & Cookie gesetzt und gültig -> Zugriff auf geschütztes Dokument - anderenfalls Fehlschlag.

Das ganze umzusetzen ist kein Akt, aber bevor ich das mache würde ich gerne von jemanden mit mehr Erfahrung wissen ob es Sinn macht (?).
 
Grundsätzlich hast du schon recht, zufallsgenerierten Zweitschlüssel im Cookie macht das Ganze sicherer (aber auch nur, wenn du auch CSRF etc. absicherst!). Zusätzlich würde ich die Session an die IP binden.
 
Ein weiteres Cookie-Token zur Session Id ist in meinen Augen nicht wirklich sicherer. Es scheint auf den ersten Blick so, aber wenn man sich die Methoden mal betrachtet, wie man an die Session Id kommt, wird man schnell feststellen, dass man in dem Fall meistens auch das Token direkt mitgeliefert bekommt. Per JS würde man sich ja bspw. document.cookie schicken lassen und da steht nunmal alles drin.

:arrow: https://stackoverflow.com/a/5081453/982902

Der ganze Thread ist zu dem Thema ganz interessant.
 
Danke für eure antworten.

Der Link hat mir sehr weitergeholfen, da standen auch nützliche Sachen drin wie man dies erschweren kann =)
 
Sehr interessantes Thema,

ich habe mich vor kurzem auch damit auseinandergesetzt.

Ich wollte demnächst mal, hauptsächlich um dabei zu lernen eine Login/Session Klasse proggen die komplett auf PHP-Sessions verzichtet.

Meine Gedanken dazu waren:

- Sessions werden in einer MySQL Datenbank gespeichert
- User werden an der IP-Adresse erkannt + zusätzlichem Identifier-Cookie auf dem Rechner (enthält einen, beim Login generierten, zufälligen MD5-Hash)
- Sessions werden nach maximal 60min idle von einem Cronjob gekillt.

Ich denke, wenn man seine MySQL Abfragen sicher macht, kann man sich in so ein System kaum ungewollten Zugang verschaffen. Um die Performance mache ich mir auch keine Sorgen.
 
Sehr interessantes Thema,

ich habe mich vor kurzem auch damit auseinandergesetzt.

Ich wollte demnächst mal, hauptsächlich um dabei zu lernen eine Login/Session Klasse proggen die komplett auf PHP-Sessions verzichtet.

Meine Gedanken dazu waren:

- Sessions werden in einer MySQL Datenbank gespeichert
- User werden an der IP-Adresse erkannt + zusätzlichem Identifier-Cookie auf dem Rechner (enthält einen, beim Login generierten, zufälligen MD5-Hash)
- Sessions werden nach maximal 60min idle von einem Cronjob gekillt.

Ich denke, wenn man seine MySQL Abfragen sicher macht, kann man sich in so ein System kaum ungewollten Zugang verschaffen. Um die Performance mache ich mir auch keine Sorgen.

So ganz würde ich da aber nicht mehr drauf verzichten wollen, du hast nämlich die Möglichkeit, Nutzerbezogene Daten in der Session zu speichern und überall im Script verfügbar zu machen.
Die Session in der DB zu speichern, ist schon ein guter Anfang, aber nur Anhand der IP ist zu ungenau, nimm da lieber noch den User-Agent, Timestamp usw. mit rein.
Setze dabei nicht auf MD5, die Hashes sind nur 32 lang, Whirlpool/sha512 dagegen ist 128 Zeichen lang, belasten aber wohl auch den Server etwas mehr.
Ein Session-Timeout von 1 Stunde...dazu schaue dir mal die Sessionbehandlung bei php.net an ;)
 
Wenn die Sessions in der Datenbank gespeichert werden und die IP-Adresse dazu, würdest du auf jeden Fall die Sicherheit um einiges erhöhen. Dennoch jemand der innerhalb des Netzwerks ist und die Session herausgefunden hat, kann diese ohne Probleme fälschen. Es nützt ja auch nichts wenn du den Browser mit speicherst.

Du könntest zwar noch nach der Macadresse über „arp -s“ Fragen, dennoch kann man dies auch innerhalb des Netzwerks modifizieren und bietet keine wirkliche Sicherheit. Jemand der im Netzwerk aktiv ist kann ohne Probleme dies vorgaukeln. Interessanter wird eventuell noch eine Kombination aus einen Flash Cookie, wenn man diesen beim Client setzen kann.
 
Wenn die Sessions in der Datenbank gespeichert werden und die IP-Adresse dazu, würdest du auf jeden Fall die Sicherheit um einiges erhöhen. Dennoch jemand der innerhalb des Netzwerks ist und die Session herausgefunden hat, kann diese ohne Probleme fälschen. Es nützt ja auch nichts wenn du den Browser mit speicherst.

Du könntest zwar noch nach der Macadresse über „arp -s“ Fragen, dennoch kann man dies auch innerhalb des Netzwerks modifizieren und bietet keine wirkliche Sicherheit. Jemand der im Netzwerk aktiv ist kann ohne Probleme dies vorgaukeln. Interessanter wird eventuell noch eine Kombination aus einen Flash Cookie, wenn man diesen beim Client setzen kann.

Für eine gescheite Session gehört ja nicht nur die eindeutige Identifikation des Nutzer und das erstellen einer ID, sondern auch das passende Cookie, welches auf dem Clientrechner abgelegt wird. Sind die Cookie deaktiviert (das kann man per PHP feststellen), wird ein Hinweis darauf ausgegeben und zum Login geführt.
Flash hat in diesem Bereich einfach nichts verloren, da stecken genug Bugs drin und ein Login sollte niemals von der Software Dritter abhängig gemacht werden.
Beim Login über eine gesicherte HTTPS-Seite (wie es heute eigentlich nötig wäre), würde ein Login vermutlich nicht funktionieren und Nutzer, welche kein Flash installiert haben, werden ausgesperrt.
Es kommt ganz auf den Programmierer an, welcher die Session-Verwaltung schreibt, denn beim doppelten Login (mit unterschiedlichen Parametern) sollte der Account eigentlich gesperrt werden, aber in fast allen Fällen werden die Parameter nicht mehr überprüft. Wird das Passwort in der Datenbank geändert (egal ob mit Salt, irgendwelchen Hashes oder Klartext), sollte es eigentlich ein Logout vom System geben und die Session gelöscht werden, dem ist aber nicht so.
Hier sehe ich schon das erste Problem der vernünftigen Session-Verwaltung (selbst dieses VB-Forum ist davon betroffen)
 
Es gab ja schon zahlreiche Diskussionen darüber. Die Sessions ID kann zum Beispiel auch im Referer auftauchen. Wer den Referer loggt wird da mit einem klick schnell Unheil anrichten.

Die Sessionen IP - basiert zu speichern halte ich für falsch. Vor allem Mobile Nutzer gehen oft über Proxys oder gar Hotspots und können so die selbe IP haben. Das wäre also noch unsicherer. Viel eher die Session selbst über einen IP-Filter laufen lassen, oder noch besser durch die eigene IP md5 verschlüsseln.

Ich würde es so machen. Ich würde die Session getrost durch ein Cookie setzen. Allerdings anstatt der Sessionsid würde ich in das Cookie einen verschlüsselten MD5 Hash setzen. Der beinhaltet dann die Informationen zu deiner IP, deinem Browser, deinem Betriebsystem usw.. und genau dadurch kann die Prüfsumme checken. Es reicht jetzt nicht aus das Cookie zu phishen. Weil das Cookie nur dann akzeptiert wird, wenn der selbe Abruck entsteht. Beispiel:

Selber Browser
Selbe IP
Selbes Betriebsystem
usw....

Statt einer SessionID im Cookie steht nur eine Art digitaler Fingerabdruck aus SessionID, Bowserinfos, Betriebsystem... und was einem noch so kreativ einfällt. Diese Daten lassen sich nun gegen vergleichen. Das Gegenstück steht nun in der Datenbank.

Die SessionID kann so mit Ablauf des Scriptes immer wieder aufs neue terminiert werden und läuft somit sofort aus. Was so viel bedeutet, dass mit jedem Seitenaufruf eine neue ID erzeugt wird, und mit Ausgabe der Seite sofort wieder terminiert wird.

Übrig bleibt ein Cookie dass nach dem Login gesetzt wird. (Sofern PW usw stimmen). Dann setzt man einen Hash der sich wie erwähnt aus einem Fingerabdruck und einer selbst definierten SessionsID zusammen setzt. Diesen Hash bekommt der User ins Cookie und die Kopie des Hashes samt Inforamtionen in die Datenbank.

Ruft jetzt der User die Seite an und liefert das Cookie mit dem Hash kann man nun wunderbar in der Datenbank vergliechen zu wem es gehört und ob der Digitale Fingerabdruck stimmt. Wenn ja wird eine Session neue Session gestartet, die auch sofort wieder terminiert wird. Mit dem nächsten Seitenaufruf das selbe.

Um Sessionsbasierte Daten zu übergeben kann man sich ebenfalls der Datenbank bedienen. Ein Schlüssel dafür könnte register_shutdown_function darstellen.

Es nützt jetzt gar nichts mehr die SessionsID im Referer zu haben. Oder der Cookie klau bringt auch nichts mehr, da der Fingerabdruck nicht der selbe ist.


Hashimcookie verschlüsselt mit Fingerabdruck und ID -> Stimmt der Hash mit der Datenbank überein und stimmt der Fingerabdruck wird eine neue Session erstellt -> Diese Session wird auch sofort wieder terminiert.

So könnte das in etwa aussehen:
PHP:
if(
$_COOKIE['hash'] /*..in db exsisten..*/ && $_COOKIE['hash'] == md5($db['SESSIONID'].getenv('REMOTE_ADDR').$_SERVER['HTTP_USER_AGENT']) /*...*/ 
)
//....usw.
{
session_start();
$_SESSION = //Sessionsdaten aus DB
}
//Sessionsdaten speichern & Session terminieren

Vom Prinzip her bewirkt es einfach nur dass nicht jeder den Schlüssel auch nutzen darf, der daran kommt. Im weiteren gibt es die Session eben nur ein paar Millisekunden lang. Und die Wahre SessionID wird nie herausgegeben.
 
Zuletzt bearbeitet:
@cadaro: ich finde deine idee echt klasse. ich würde noch die mac adresse auslesen. ich glaube es war mit "arp -s" oder so. dann scheit es fast unmöglich zu sein die session zu klauen.