Ich versuche mehr über PHP Session Fixation & Hijacking zu verstehen und wie man diese Probleme verhindert. Ich habe die folgenden zwei Artikel auf der Website von Chris Shiflett gelesen:
Ich bin mir jedoch nicht sicher, ob ich die Dinge richtig verstehe.
Um eine Sitzungsfixierung zu verhindern, reicht es aus, session_regenerate_id (true) aufzurufen. nach erfolgreicher Anmeldung? Ich denke, ich verstehe das richtig.
Er spricht auch über die Verwendung von Token, die in URLs über $ _GET weitergegeben werden, um Sitzungsentführungen zu verhindern. Wie würde das genau gemacht werden? Ich vermute, wenn sich jemand anmeldet, generieren Sie sein Token und speichern es in einer Sitzungsvariablen. Dann würden Sie auf jeder Seite diese Sitzungsvariable mit dem Wert der Variablen $ _GET vergleichen?
Müsste dieses Token nur einmal pro Sitzung oder bei jedem Laden der Seite geändert werden?
Ist dies auch eine gute Möglichkeit, Entführungen zu verhindern, ohne einen Wert in den URLs weitergeben zu müssen? das wäre viel einfacher.
Antworten:
Ok, es gibt zwei separate, aber verwandte Probleme, und jedes wird anders behandelt.
Sitzungsfixierung
Hier legt ein Angreifer explizit die Sitzungskennung einer Sitzung für einen Benutzer fest. Normalerweise geschieht dies in PHP, indem man ihnen eine URL wie gibt
http://www.example.com/index...?session_name=sessionid
. Sobald der Angreifer dem Client die URL gibt, entspricht der Angriff einem Sitzungsentführungsangriff.Es gibt einige Möglichkeiten, um die Sitzungsfixierung zu verhindern (alle ausführen):
In
session.use_trans_sid = 0
Ihrerphp.ini
Datei einstellen. Dadurch wird PHP angewiesen, den Bezeichner nicht in die URL aufzunehmen und die URL für Bezeichner nicht zu lesen.In
session.use_only_cookies = 1
Ihrerphp.ini
Datei einstellen. Dadurch wird PHP angewiesen, niemals URLs mit Sitzungskennungen zu verwenden.Generieren Sie die Sitzungs-ID immer dann neu, wenn sich der Status der Sitzung ändert. Das bedeutet Folgendes:
Sitzungsentführung
Hier erhält ein Angreifer eine Sitzungskennung und kann Anforderungen senden, als ob er dieser Benutzer wäre. Das bedeutet, dass der Angreifer, da er die Kennung hat, vom gültigen Benutzer in Bezug auf den Server so gut wie nicht zu unterscheiden ist.
Sie können die Entführung von Sitzungen nicht direkt verhindern. Sie können jedoch Schritte einleiten, um die Verwendung sehr schwierig und schwieriger zu machen.
Verwenden Sie eine starke Sitzungs-Hash-ID:
session.hash_function
inphp.ini
. Wenn PHP <5.3 ist, setzen Sie essession.hash_function = 1
für SHA1. Wenn PHP> = 5.3, setzen Sie es aufsession.hash_function = sha256
odersession.hash_function = sha512
.Senden Sie einen starken Hash:
session.hash_bits_per_character
inphp.ini
. Stellen Sie dies auf einsession.hash_bits_per_character = 5
. Dies macht das Knacken zwar nicht schwieriger , macht jedoch einen Unterschied, wenn der Angreifer versucht, die Sitzungskennung zu erraten. Die ID ist kürzer, verwendet jedoch mehr Zeichen.Legen Sie eine zusätzliche Entropie mit
session.entropy_file
undsession.entropy_length
in Ihrerphp.ini
Datei fest. Stellen Sie erstere aufsession.entropy_file = /dev/urandom
und letztere auf die Anzahl der Bytes ein, die beispielsweise aus der Entropiedatei gelesen werdensession.entropy_length = 256
.Ändern Sie den Namen der Sitzung von der Standard-PHPSESSID. Dies wird erreicht, indem Sie vor dem Aufruf
session_name()
mit Ihrem eigenen Bezeichnernamen als erstem Parameter aufrufensession_start
.Wenn Sie wirklich paranoid sind, können Sie auch den Sitzungsnamen drehen. Beachten Sie jedoch, dass alle Sitzungen automatisch ungültig werden, wenn Sie dies ändern (z. B. wenn Sie ihn von der Zeit abhängig machen). Abhängig von Ihrem Anwendungsfall kann dies jedoch eine Option sein ...
Drehen Sie Ihre Sitzungskennung häufig. Ich würde dies nicht bei jeder Anfrage tun (es sei denn, Sie benötigen wirklich diese Sicherheitsstufe), sondern in zufälligen Abständen. Sie möchten dies häufig ändern, da ein Angreifer, der eine Sitzung entführt, nicht möchte, dass er sie zu lange verwenden kann.
Schließen Sie den Benutzeragenten von
$_SERVER['HTTP_USER_AGENT']
in die Sitzung ein. Wenn die Sitzung beginnt, speichern Sie sie grundsätzlich in so etwas wie$_SESSION['user_agent']
. Überprüfen Sie dann bei jeder nachfolgenden Anforderung, ob sie übereinstimmt. Beachten Sie, dass dies gefälscht werden kann, so dass es nicht 100% zuverlässig ist, aber es ist besser als nicht.Fügen Sie die IP-Adresse
$_SERVER['REMOTE_ADDR']
des Benutzers von in die Sitzung ein. Wenn die Sitzung beginnt, speichern Sie sie grundsätzlich in so etwas wie$_SESSION['remote_ip']
. Dies kann bei einigen ISPs problematisch sein, die mehrere IP-Adressen für ihre Benutzer verwenden (wie dies früher bei AOL der Fall war). Aber wenn Sie es verwenden, wird es viel sicherer sein. Die einzige Möglichkeit für einen Angreifer, die IP-Adresse zu fälschen, besteht darin, das Netzwerk irgendwann zwischen dem tatsächlichen Benutzer und Ihnen zu gefährden. Und wenn sie das Netzwerk gefährden, können sie weitaus schlechter abschneiden als eine Entführung (wie MITM-Angriffe usw.).Fügen Sie der Sitzung und auf der Browserseite ein Token hinzu, das Sie häufig erhöhen und vergleichen. Grundsätzlich für jede Anfrage
$_SESSION['counter']++
auf der Serverseite tun . Machen Sie auch etwas in JS auf der Browserseite, um dasselbe zu tun (unter Verwendung eines lokalen Speichers). Wenn Sie dann eine Anfrage senden, nehmen Sie einfach eine Nonce eines Tokens und stellen Sie sicher, dass die Nonce auf dem Server identisch ist. Auf diese Weise sollten Sie in der Lage sein, eine entführte Sitzung zu erkennen, da der Angreifer nicht über den genauen Zähler verfügt. Andernfalls haben Sie zwei Systeme, die die gleiche Anzahl übertragen, und können feststellen, dass eines gefälscht ist. Dies funktioniert nicht für alle Anwendungen, ist jedoch eine Möglichkeit, das Problem zu bekämpfen.Ein Hinweis zu den beiden
Der Unterschied zwischen Sitzungsfixierung und Hijacking besteht nur darin, wie die Sitzungskennung kompromittiert wird. Bei der Fixierung wird der Bezeichner auf einen Wert gesetzt, den der Angreifer vorher kennt. Beim Hijacking wird es entweder erraten oder dem Benutzer gestohlen. Ansonsten sind die Auswirkungen der beiden gleich, sobald die Kennung kompromittiert wird.
Regeneration der Sitzungs-ID
Immer wenn Sie die Sitzungskennung mit
session_regenerate_id
der alten Sitzung neu generieren, sollte diese gelöscht werden. Dies geschieht transparent mit dem Core Session Handler. Einige benutzerdefinierte Sitzungshandler, diesession_set_save_handler()
dies verwenden, tun dies jedoch nicht und sind offen für Angriffe auf alte Sitzungskennungen. Stellen Sie sicher, dass Sie bei Verwendung eines benutzerdefinierten Sitzungshandlers den von Ihnen geöffneten Bezeichner nachverfolgen und den Bezeichner des alten explizit löschen (oder ändern), wenn er nicht derselbe ist, den Sie speichern.Wenn Sie den Standard-Sitzungshandler verwenden, können Sie nur anrufen
session_regenerate_id(true)
. Dadurch werden die alten Sitzungsinformationen für Sie entfernt. Die alte ID ist nicht mehr gültig und führt dazu, dass eine neue Sitzung erstellt wird, wenn der Angreifer (oder sonst jemand) versucht, sie zu verwenden. Seien Sie jedoch vorsichtig mit benutzerdefinierten Sitzungshandlern ....Eine Sitzung zerstören
Wenn Sie eine Sitzung zerstören möchten (z. B. beim Abmelden), stellen Sie sicher, dass Sie sie gründlich zerstören. Dies beinhaltet das Deaktivieren des Cookies. Verwenden von
session_destroy
:quelle
session_regenerate_id
macht die Sitzung, die noch der alten ID zugeordnet ist, nicht ungültig; Nur wenn der Parameter delete_old_session auf true gesetzt ist, wird die Sitzung zerstört. Was aber, wenn ein Angreifer diese ID-Regeneration initiiert hat?session.entropy_file = /dev/urandom
. Die interne Entropieerzeugung von PHP ist nachweislich extrem schwach und der Entropiepool von / dev / random oder / dev / uranom ist der beste, den Sie auf einem Webserver ohne Hardware-Rng erhalten können.session.cookie_httponly
undsession.cookie_secure
. Der erste hilft, xss zu vereiteln (aber es ist nicht perfekt). Der 2. ist der beste Weg, um OWASP A9 zu stoppen ...Beide Sitzungsangriffe haben dasselbe Ziel: Zugriff auf eine legitime Sitzung eines anderen Benutzers. Die Angriffsvektoren sind jedoch unterschiedlich:
In einem Session - Fixation - Angriff , der Angreifer hat bereits Zugriff auf eine gültige Sitzung und versucht , das Opfer zu zwingen , diese bestimmte Sitzung zu verwenden.
Bei einem Session Hijacking- Angriff versucht der Angreifer, die ID der Sitzung eines Opfers abzurufen, um seine Sitzung zu verwenden.
Bei beiden Angriffen ist die Sitzungs-ID die vertrauliche Daten, auf die sich dieser Angriff konzentriert. Es ist also die Sitzungs-ID, die sowohl für einen Lesezugriff (Session Hijacking) als auch für einen Schreibzugriff (Session Fixation) geschützt werden muss.
Auch in diesem Fall gilt die allgemeine Regel zum Schutz sensibler Daten mit HTTPS. Darüber hinaus sollten Sie Folgendes tun:
Stellen Sie Folgendes sicher, um Angriffe zur Sitzungsfixierung zu verhindern :
true
) und mache es nur für HTTPS, wenn möglich (setze session.cookie_secure auftrue
); Sie können beides mit tunsession_set_cookie_params
.Stellen Sie Folgendes sicher, um Angriffe auf Sitzungsentführungen zu verhindern :
true
).Stellen Sie Folgendes sicher, um beide Sitzungsangriffe zu verhindern :
session_regenerate_id(true)
nach einem Authentifizierungsversuch (true
nur bei Erfolg) oder einer Änderung der Berechtigungen und Zerstören der alten Sitzung. (Stellen Sie sicher, dass Sie alle Änderungen der$_SESSION
Verwendung speichern ,session_write_close
bevor Sie die ID neu generieren, wenn Sie die der alten ID zugeordnete Sitzung beibehalten möchten. Andernfalls ist nur die Sitzung mit der neuen ID von diesen Änderungen betroffen.)quelle
Die Token, die Sie erwähnen, sind eine "Nonce" -Nummer, die einmal verwendet wird. Sie müssen nicht unbedingt nur einmal verwendet werden, aber je länger sie verwendet werden, desto höher ist die Wahrscheinlichkeit, dass das Nonce erfasst und zur Entführung der Sitzung verwendet werden kann.
Ein weiterer Nachteil von Nonces ist, dass es sehr schwierig ist, ein System zu erstellen, das sie verwendet und mehrere parallele Fenster in derselben Form zulässt. Beispiel: Der Benutzer öffnet zwei Fenster in einem Forum und beginnt mit der Arbeit an zwei Posts:
Wenn Sie nicht in der Lage sind, mehrere Fenster zu verfolgen, haben Sie nur eine Nonce gespeichert - die von Fenster B / Q. Wenn der Benutzer dann seinen Beitrag aus Fenster A einreicht und nonce 'P' übergibt, lehnt dieses System den Beitrag als ab
P != Q
.quelle
Ich habe Shifletts Artikel nicht gelesen, aber ich denke, Sie haben etwas falsch verstanden.
Standardmäßig übergibt PHP das Sitzungstoken in der URL, wenn der Client keine Cookies akzeptiert. Andernfalls wird das Sitzungstoken im häufigsten Fall als Cookie gespeichert.
Dies bedeutet, dass wenn Sie ein Sitzungstoken in die URL einfügen, PHP es erkennt und versucht, es anschließend zu verwenden. Die Sitzungsfixierung erfolgt, wenn jemand eine Sitzung erstellt und dann einen anderen Benutzer dazu verleitet, dieselbe Sitzung freizugeben, indem eine URL geöffnet wird, die das Sitzungstoken enthält. Wenn sich der Benutzer auf irgendeine Weise authentifiziert, kennt der böswillige Benutzer das Sitzungstoken eines authentifizierten Benutzers, der möglicherweise über andere Berechtigungen verfügt.
Wie Shiflett sicher erklärt, besteht die übliche Vorgehensweise darin, jedes Mal, wenn sich die Berechtigungen eines Benutzers ändern, ein anderes Token neu zu generieren.
quelle
Ja, Sie können die Sitzungsfixierung verhindern, indem Sie die Sitzungs-ID bei der Anmeldung einmal neu generieren. Auf diese Weise, wenn der Angreifer den Cookie-Wert der neu authentifizierten Sitzung nicht kennt. Ein anderer Ansatz, der das Problem vollständig stoppt, ist
session.use_only_cookies=True
in Ihrer Laufzeitkonfiguration festgelegt. Ein Angreifer kann den Wert eines Cookies nicht im Kontext einer anderen Domäne festlegen. Die Sitzungsfixierung basiert auf dem Senden des Cookie-Werts als GET oder POST.quelle