PHP-Sitzungssicherheit

125

Was sind einige Richtlinien zur Aufrechterhaltung einer verantwortungsvollen Sitzungssicherheit mit PHP? Es gibt Informationen im ganzen Web und es ist an der Zeit, dass alles an einem Ort landet!

saint_groceon
quelle

Antworten:

88

Es gibt einige Dinge zu tun, um Ihre Sitzung sicher zu halten:

  1. Verwenden Sie SSL, wenn Sie Benutzer authentifizieren oder vertrauliche Vorgänge ausführen.
  2. Generieren Sie die Sitzungs-ID neu, wenn sich die Sicherheitsstufe ändert (z. B. Anmelden). Sie können sogar die Sitzungs-ID bei jeder Anforderung neu generieren, wenn Sie dies wünschen.
  3. Haben Sie eine Auszeit für die Sitzungen
  4. Verwenden Sie keine Registerglobale
  5. Speichern Sie die Authentifizierungsdetails auf dem Server. Senden Sie also keine Details wie den Benutzernamen in den Cookie.
  6. Überprüfen Sie die $_SERVER['HTTP_USER_AGENT']. Dies fügt der Sitzungsentführung eine kleine Barriere hinzu. Sie können auch die IP-Adresse überprüfen. Dies führt jedoch zu Problemen für Benutzer, deren IP-Adresse sich aufgrund des Lastausgleichs bei mehreren Internetverbindungen usw. ändert (was in unserer Umgebung hier der Fall ist).
  7. Sperren Sie den Zugriff auf die Sitzungen im Dateisystem oder verwenden Sie die benutzerdefinierte Sitzungsbehandlung
  8. Bei vertraulichen Vorgängen müssen angemeldete Benutzer ihre Authentifizierungsdetails erneut angeben
grom
quelle
15
Die Verwendung von SSL nur für einige Vorgänge reicht nicht aus, es sei denn, Sie haben separate Sitzungen für verschlüsselten und unverschlüsselten Datenverkehr. Wenn Sie eine einzelne Sitzung über HTTPS und HTTP verwenden, stiehlt der Angreifer diese bei der ersten Nicht-HTTPS-Anforderung.
Kornel
6
-1 Der Benutzeragent ist trivial zu fälschen. Was Sie beschreiben, verschwendet Code und ist kein Sicherheitssystem.
Turm
24
@ The Rook, es kann eine triviale Barriere sein (der Angreifer kann den Benutzeragenten eines Opfers über seine eigene Site erfassen) und verlässt sich auf Sicherheit durch Dunkelheit, aber es ist immer noch eine zusätzliche Barriere. Wenn sich das User-Agent-HTTP während der Sitzungsnutzung ändern würde, wäre dies äußerst verdächtig und höchstwahrscheinlich ein Angriff. Ich habe nie gesagt, dass Sie es alleine verwenden können. Wenn Sie es mit den anderen Techniken kombinieren, haben Sie eine viel sicherere Site.
Grom
5
@grom Ich denke, es ist, als würde man ein Stück Klebeband über die Tür kleben und sagen, es würde verhindern, dass Leute einbrechen.
Turm
8
Wenn Sie den Benutzeragenten überprüfen, blockieren Sie alle Anforderungen von IE8-Benutzern, wenn diese den Kompatibilitätsmodus umschalten. Sehen Sie, wie viel Spaß es mir gemacht hat, dieses Problem in meinem eigenen Code aufzuspüren : serverfault.com/questions/200018/http-302-problem-on-ie7 . Ich nehme den User Agent Check-out, weil es so trivial ist, zu fälschen, wie andere gesagt haben.
Bestattendance
15

Eine Richtlinie besteht darin, session_regenerate_id jedes Mal aufzurufen, wenn sich die Sicherheitsstufe einer Sitzung ändert. Dies hilft, Sitzungsentführungen zu verhindern.

saint_groceon
quelle
11

Meine zwei (oder mehr) Cent:

  • Traue niemandem
  • Filtereingabe, Escape-Ausgabe (Cookie, Sitzungsdaten sind auch Ihre Eingabe)
  • Vermeiden Sie XSS (halten Sie Ihr HTML gut geformt, schauen Sie sich PHPTAL oder HTMLPurifier an )
  • Verteidigung in der Tiefe
  • Stellen Sie keine Daten zur Verfügung

Zu diesem Thema gibt es ein kleines, aber gutes Buch: Essential PHP Security von Chris Shiflett .

Grundlegende PHP-Sicherheit http://shiflett.org/images/essential-php-security-small.png

Auf der Homepage des Buches finden Sie einige interessante Codebeispiele und Beispielkapitel.

Sie können die oben beschriebene Technik (IP & UserAgent) verwenden, die hier beschrieben wird: So vermeiden Sie Identitätsdiebstahl

Takeshin
quelle
+1 für XSS-Prävention. Ohne das ist es unmöglich, sich vor CSRF zu schützen, und somit kann jemand die Sitzung "reiten", ohne auch nur die Sitzungs-ID zu erhalten.
Kornel
11

Ich denke, eines der Hauptprobleme (das in PHP 6 angesprochen wird) ist register_globals. Derzeit ist eine der Standardmethoden zur Vermeidung register_globalsdie Verwendung von $_REQUEST, $_GEToder$_POST Arrays.

Der "richtige" Weg, dies zu tun (ab 5.2, obwohl es dort ein wenig fehlerhaft ist, aber ab 6 stabil, was bald kommt), sind Filter .

Also statt:

$username = $_POST["username"];

Du würdest:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);

oder auch nur:

$username = filter_input(INPUT_POST, 'username');
cmcculloh
quelle
2
Dies hat überhaupt nichts mit der Frage zu tun.
Der Pixel-Entwickler
5
"Ja wirklich?" Warum erwähnen sie dann in der akzeptierten Antwort, keine Registerglobale zu verwenden? Würden für die meisten herkömmlichen Entwickler nicht die Registrierung von Globals und die Handhabung von Formularvariablen unter den Begriff "Sitzungen" fallen, selbst wenn dies technisch nicht Teil des Objekts "Sitzung" ist?
cmcculloh
9
Ich stimme zu, dies beantwortet die Frage nicht vollständig , aber es ist definitiv ein Teil der Antwort auf die Frage. Auch dies konkretisiert einen Punkt in der akzeptierten Antwort "Verwenden Sie keine Registerglobale". Dies sagt, was stattdessen zu tun ist.
cmcculloh
5

Die Verwendung einer IP-Adresse ist meiner Erfahrung nach nicht die beste Idee. Beispielsweise; Mein Büro hat zwei IP-Adressen, die je nach Auslastung verwendet werden, und wir haben ständig Probleme mit der Verwendung von IP-Adressen.

Stattdessen habe ich mich dafür entschieden, die Sitzungen in einer separaten Datenbank für die Domänen auf meinen Servern zu speichern. Auf diese Weise hat niemand im Dateisystem Zugriff auf diese Sitzungsinformationen. Dies war sehr hilfreich bei phpBB vor 3.0 (sie haben dies inzwischen behoben), aber ich denke, es ist immer noch eine gute Idee.

Eric Lamb
quelle
3

Dies ist ziemlich trivial und offensichtlich, aber stellen Sie sicher, dass session_destroy nach jedem Gebrauch . Dies kann schwierig zu implementieren sein, wenn sich der Benutzer nicht explizit abmeldet, sodass ein Timer dafür eingestellt werden kann.

Hier ist ein gutes Tutorial zu setTimer () und clearTimer ().

halloandre
quelle
3

Das Hauptproblem bei PHP-Sitzungen und der Sicherheit (neben dem Hijacking von Sitzungen) liegt in der Umgebung, in der Sie sich befinden. Standardmäßig speichert PHP die Sitzungsdaten in einer Datei im temporären Verzeichnis des Betriebssystems. Ohne besondere Überlegungen oder Planung ist dies ein weltweit lesbares Verzeichnis, sodass alle Ihre Sitzungsinformationen für jeden zugänglich sind, der Zugriff auf den Server hat.

Zum Verwalten von Sitzungen über mehrere Server. An diesem Punkt ist es besser, PHP auf vom Benutzer behandelte Sitzungen umzustellen, in denen die bereitgestellten Funktionen in CRUD aufgerufen werden (Erstellen, Lesen, Aktualisieren, Löschen) der Sitzungsdaten. Zu diesem Zeitpunkt können Sie die Sitzungsinformationen in einer Datenbank oder einer memcacheähnlichen Lösung speichern, sodass alle Anwendungsserver Zugriff auf die Daten haben.

Das Speichern eigener Sitzungen kann auch von Vorteil sein, wenn Sie sich auf einem gemeinsam genutzten Server befinden, da Sie diese in der Datenbank speichern können, über die Sie häufig mehr Kontrolle haben als über das Dateisystem.

John Downey
quelle
3

Ich richte meine Sitzungen so ein:

auf der Anmeldeseite:

$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);

(Ausdruck auf einer Konfigurationsseite definiert)

dann auf der Kopfzeile, die sich im Rest der Site befindet:

session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {       
    session_destroy();
    header('Location: http://website login page/');
    exit();     
}
Tschad
quelle
3

php.ini

session.cookie_httponly = 1
change session name from default PHPSESSID

eq Apache Header hinzufügen:

X-XSS-Protection    1
user956584
quelle
httpd.conf -> <FilesMatch "\. (php | phtml | aspx | htm | html) $"> Header-Set X-XSS-Schutz "1" </ FileMatch>
user956584
Seien Sie sich bewusst, dass dies überhaupt X-XSS-Protectionnicht wirklich nützlich ist. Tatsächlich könnte der Schutzalgorithmus selbst tatsächlich ausgenutzt werden, was ihn schlimmer macht als zuvor.
Pacerier
2

Ich würde sowohl IP als auch User Agent überprüfen, um festzustellen, ob sie sich ändern

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
    //Something fishy is going on here?
}
Teifion
quelle
5
Die IP kann sich rechtmäßig ändern, wenn sich der Benutzer hinter einer Proxy-Farm mit Lastenausgleich befindet.
Kornel
2
Und user_agent kann sich jedes Mal ändern, wenn ein Benutzer seinen Browser aktualisiert.
Scotts
3
@scotts Ich stimme dem IP-Teil zu, aber für das Browser-Upgrade würden Sie die Sitzung festlegen, wenn sie sich anmelden, sodass ich nicht sehe, wie sie ihren Browser aktualisieren würden, ohne eine neue Sitzung zu erstellen, sobald sie sich erneut anmelden.
JasonDavis
Ich glaube, der user_agent kann sich auch ändern, wenn zwischen dem kompatiblen Modus in IE8 umgeschaltet wird. Es ist auch sehr leicht zu fälschen.
Ja, aber was ist mit Benutzern, die statisches IP-Equalizer-GSM hatten und jede halbe Stunde gewechselt werden? Also, gespeicherte IP in Sitzung + Hostname, WENN IP! = REMOTE_ADDR Host überprüfen und Hostanmes Gl. 12.12.12.holand.nl-> wann ist holand.nl == true. Aber einige Host hatte IP-basierten Hostnamen Dann müssen Vergleichsmaske 88.99.XX.XX
user956584
2

Wenn Sie session_set_save_handler () verwenden , können Sie Ihren eigenen Session-Handler festlegen. Beispielsweise könnten Sie Ihre Sitzungen in der Datenbank speichern. In den Kommentaren zu php.net finden Sie Beispiele für einen Datenbank-Sitzungshandler.

DB-Sitzungen sind auch gut, wenn Sie mehrere Server haben. Wenn Sie andernfalls dateibasierte Sitzungen verwenden, müssen Sie sicherstellen, dass jeder Webserver Zugriff auf dasselbe Dateisystem hat, um die Sitzungen zu lesen / schreiben.

Ejunker
quelle
2

Sie müssen sicherstellen, dass die Sitzungsdaten sicher sind. Wenn Sie sich Ihre php.ini ansehen oder phpinfo () verwenden, finden Sie Ihre Sitzungseinstellungen. _session.save_path_ gibt an, wo sie gespeichert sind.

Überprüfen Sie die Berechtigung des Ordners und seiner Eltern. Es sollte nicht öffentlich (/ tmp) sein oder von anderen Websites auf Ihrem freigegebenen Server zugänglich sein.

Angenommen, Sie möchten weiterhin eine PHP-Sitzung verwenden, können Sie PHP so einstellen, dass ein anderer Ordner verwendet wird, indem Sie _session.save_path_ ändern, oder die Daten in der Datenbank speichern, indem Sie _session.save_handler_ ändern.

Möglicherweise können Sie _session.save_path_ in Ihrer php.ini (einige Anbieter erlauben dies) oder für apache + mod_php in einer .htaccess-Datei in Ihrem Site-Stammordner festlegen: php_value session.save_path "/home/example.com/html/session" . Sie können es auch zur Laufzeit mit _session_save_path () _ festlegen.

Überprüfen Sie das Tutorial von Chris Shiflett oder Zend_Session_SaveHandler_DbTable, um einen alternativen Sitzungshandler festzulegen .

Dinoboff
quelle