Entwicklung einer sicheren PHP-Login- und Authentifizierungsstrategie

8

Ich entwickle ein Login- und Authentifizierungssystem für eine neue PHP-Site und lese die verschiedenen Attacken und Schwachstellen. Es ist jedoch ein wenig verwirrend, also möchte ich überprüfen, ob meine Vorgehensweise sinnvoll ist.

Ich plane die folgenden Daten zu speichern:

  • In der Sitzung: user-id, hashed + salted HTTP_USER_AGENT

  • Im Cookie und in der Datenbank: Zufallstoken, Hashed + gesalzene Kennung

Auf jeder Seite plane ich Folgendes:

  1. Wenn eine Sitzung besteht, authentifizieren Sie sich mit dieser. Überprüfen Sie, ob HTTP_USER_AGENT mit dem in der gespeicherten Sitzung übereinstimmt.

  2. Wenn keine Sitzung vorhanden ist, verwenden Sie das Cookie zur Authentifizierung. Überprüfen Sie, ob das Token und die Kennung im Cookie mit denen in der Datenbank übereinstimmen.

  3. Wenn der Cookie ungültig ist oder nicht existiert, bitten Sie den Benutzer, sich anzumelden.

Gibt es da offensichtliche Mängel? Solange ich eine Auszeit im Cookie setze, sollte ich ziemlich sicher sein, oder? Gibt es etwas, was mir fehlt?

Vielen Dank im Voraus.

    
Philip Morton 16.12.2009, 20:19
quelle

8 Antworten

12

Ein paar zufällige Gedanken:

  1. Was ist, wenn ich den Cookie eines Ihrer Benutzer stehlen möchte (mit einem XSS-Angriff, indem Sie JS-Code in Ihre Website injizieren)? Ich werde dann in Fall 2 fallen und somit in der Lage sein, mich einzuloggen. IMHO, wenn Sie eine wirklich sichere Authentifizierung wollen, verwenden Sie nicht "erinnern mich" -Clients, um Benutzeranmeldeinformationen zu speichern.
  2. Wenn Sie die Zugangsdaten in einem Cookie speichern, speichern Sie das Passwort bitte nicht im Klartext.
  3. Die Überprüfung auf HTTP_USER_AGENT ist ein guter erster Schritt, um Session-Hijacking zu verhindern, aber vielleicht könnten Sie es mit der IP-Adresse kombinieren? Es ist viel schwieriger, auf demselben Host zu sein wie Ihr Ziel, als einfach denselben Browser zu verwenden.

Aber auf jeden Fall, danke, dass Sie sich die Zeit genommen haben, über ein gutes Authentifizierungsschema nachzudenken. Viele PHP-Entwickler tun das nicht.

EDIT: Für die Aufzeichnung, lassen Sie mich hier einen Punkt klarstellen: Es gibt zwei Kekse in dieser Diskussion. Eine wird automatisch von PHP gesetzt, um die Sitzungs-ID zu verbreiten (manchmal sehen wir Webseiten, die sie in die URL setzen, zB www.example.com/page.php?sessionId = [...]), und die zweite wird von Ihnen erstellt um die Benutzerdaten zu speichern und ihn bei Verlust der Sitzung zu authentifizieren. Der XSS-Angriff gilt für beide, dh ein Angreifer könnte entweder das Session-Cookie stehlen und die Sitzung (die eine begrenzte Lebensdauer hat) entführen oder das Anmelde-Cookie stehlen und sich später authentifizieren.

    
Wookai 16.12.2009, 20:31
quelle
2

sollte nicht sein. Die PHP-Sitzung wird auf Ihrem Server gespeichert und nicht der Benutzer. php lässt simpily einen Session-Cookie, der darauf zeigt. Wenn Sie kein Shared Hosting verwenden, muss die Sitzung nicht einmal gehashed werden.

Joe

    
Joe Simpson 16.12.2009 20:21
quelle
2

Das Speichern des Cookies in der Datenbank ist eine HORRILBE-Idee. Das bedeutet, dass ein Angreifer, der über eine Sicherheitsanfälligkeit gegen SQL-Angriffe verfügte, sofort Zugriff erhalten konnte, ohne ein Hash-Passwort knacken zu müssen.

Apropos, Sie müssen sha256 für Passwörter verwenden, wenn Sie md5 () verwenden, sind Sie technisch anfällig für Angriffe und Sie könnten eine CVE-Nummer erhalten.

NIEMALS eigene Session-IDs generieren, verwenden Sie session_start () und $ super SESSION global.

Dies ist eine sichere Möglichkeit, Leute umzuleiten. Wenn du nach header () nicht stirbst, ist der Rest des PHP-Codes STILL EXECUTED, obwohl er von normalen Browsern nicht angezeigt wird (Hacker sehen ihn immer noch:)

%Vor%

Um ehrlich zu sein, wenn die Sicherheit Sie verwirrt, schreiben Sie keine Sicherheitssysteme. Die Leute haben mehr als 1.000 Login-Systeme für PHP allein geschrieben und die Mehrheit ist anfällig. Dieses Projekt verfügt über ein sicheres Authentifizierungssystem: Ссылка

    
rook 17.12.2009 02:34
quelle
1

Hängt davon ab, wie sicher Sie sein wollen ..

Cross-Site-Schwachstellen: Nehmen wir an, eine andere Website weist den Browser an, ein Formular an Ihre Site zu senden, das Spam (oder schlechter) veröffentlicht, wenn dieser Benutzer bereits angemeldet ist. Sie müssen Referer und eine generierte versteckte FormID für jedes Formular prüfen, um sich vollständig davor zu schützen.

Zweitens: Wenn Sie einen hohen bis mittleren Traffic haben, können Sitzungs-IDs wiederholt oder sogar erraten werden. Ich würde dann nach einer aus zweiter Hand generierten ID suchen, die in den Cookies des Benutzers gespeichert ist.

    
MindStalker 16.12.2009 20:32
quelle
1

Das Schema scheint in vielerlei Hinsicht unnötig komplex zu sein, da die zusätzliche Komplexität nichts an Funktionalität oder Sicherheit gewinnt.

  1. Alle Daten, die vom Browser gesendet werden (z. B. Cookies, User-Agent), sind gefälscht. Die Überprüfung von User-Agent hilft nur, wenn der Angreifer sich hinter der gleichen NAT wie der Spoofed-Benutzer befindet und der Angreifer einen anderen Browser verwendet, aber nicht daran denkt, den User-Agent zu ändern.
  2. Sitzungen speichern die Sitzungs-ID clientseitig mit Cookies oder einem URL-Abfrageparameter. Wenn Sie die Lebensdauer einer Sitzung verlängern möchten, verwenden Sie session_set_cookie_params , um den Sitzungscookie länger zu verwenden.

Der User-Agent ist keine geheime Daten, so Hashing ist nicht notwendig.

Die Angriffe, die das Session-Cookie + das Überprüfen der Remote-IP nicht abfangen kann, sind:

  1. Der Angreifer befindet sich hinter demselben NAT wie der Benutzer
  2. Blinde Injektionsattacken, bei denen der Angreifer die IP des Benutzers verfälscht. Obwohl sie schreibgeschützt sind, können sie dennoch etwas Schaden anrichten.
  3. Angriffe, die den eigenen Browser des Benutzers verwenden, wie siteübergreifende Anfragefälschung (CSRF).

2) kann verhindert werden, wenn Sie eine Möglichkeit finden, eine Anfrage an den Browser des Benutzers zu senden, auf die vor dem Ausfüllen der Anfrage geantwortet werden muss. Dies ist jedoch schwierig, wenn Sie den Client nicht geschrieben haben. Mit AJAX kann es gemacht werden. 3) (wie von MindStalker angemerkt) kann verhindert werden, indem der Referer-Header überprüft wird, der funktioniert, weil CSRF-Angriffe nicht die Möglichkeit haben, beliebige Header zu beeinflussen, und XMLHttpRequest sollte nicht zulassen, dass der Referer-Header gesetzt wird (gemäß < a href="http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method"> W3C-Standard , obwohl Implementierungen möglicherweise nicht konform sind). Mit iframes könnte es möglich sein, einen Referer-Check zu umgehen. Der Referer-Header könnte auch clientseitig blockiert sein.

    
outis 16.12.2009 22:53
quelle
1

Die meisten Websites verwenden nur die PHP-Sitzung. Die Sitzungsdaten ($ _SESSION) befinden sich in einer Datei Ihr Server. Alles, was an den Browser gesendet wird, ist eine Sitzungs-ID. Stellen Sie sicher, dass die Sitzung bei jeder Anfrage neu generiert wird ( session_regenerate_id ). Sie müssen nicht zwei Cookies oder ähnliches senden.

Dies ist weniger anfällig für Session-Hijacking, da jede Anfrage eine neue ID ist, so dass eine alte von einem Angreifer abgefangen wird, nutzlos ist.

Die beste Lösung wäre natürlich die Verwendung von SSL während der gesamten Sitzung.

    
Jacob Greenleaf 19.01.2010 22:19
quelle
0

IMHO ist es auch wichtig, dass die Sitzungsinformationen nach einer erfolgreichen Anmeldung geändert werden. Das Speichern der Sitzungsinformationen in einer Datenbank ist aufgrund von Injektionen nicht sicher.

    
DrDol 19.01.2010 23:08
quelle
0

-use sha1 mit Salz Natürlich müssen Sie definieren, dass jedes Formular nicht sicher ist, also Token für jedes Formular. Dass Sie jeden Formulareintrag erstellen und mit preg_match bereinigen. Ein Prozess namens Sanitation.

    
Bryan Paul B. Quinto 01.08.2016 06:54
quelle