it-swarm.dev

Welche Best Practices sollten in einem PHP Anmeldeskript) angewendet werden?

Ich möchte meine Anmeldeskripte für Kundenwebsites neu schreiben, um sie sicherer zu machen. Ich möchte wissen, welche Best Practices ich in diese implementieren kann. Passwortgeschützte Kontrollfelder sind in Hülle und Fülle vorhanden, aber nur sehr wenige scheinen Best Practices in Bezug auf Code-Schreiben, Geschwindigkeit und Sicherheit umzusetzen.

Ich werde PHP und eine MYSQL-Datenbank verwenden.

Früher habe ich md5 verwendet, aber ich sehe, dass sha256 oder sha512 besser wären (zusammen mit sicherem Hash und Salz).

Einige Anmeldeskripte protokollieren die IP-Adresse während der Sitzung oder sogar des Benutzeragenten, aber ich möchte dies vermeiden, da sie nicht mit Proxyservern kompatibel ist.

Ich bin auch ein wenig hinter der Best Practice bei der Verwendung von Sitzungen in PHP 5) zurück (das letzte Mal, als ich nachgelesen habe, war PHP 4), daher würden einige Best Practices damit funktionieren sei hilfreich.

Vielen Dank.

27
baritoneuk

Der beste Gedanke ist, das Rad nicht neu zu erfinden. Aber ich verstehe, in PHP Welt kann es schwierig sein, eine qualitativ hochwertige Komponente zu finden, die dies bereits tut (selbst ich bin mir ziemlich sicher, dass die Frameworks solche Dinge implementieren und ihre Implementierungen bereits getestet sind , solide, Code-geprüft usw.)

Wenn Sie aus bestimmten Gründen kein Framework verwenden können, finden Sie hier einige Vorschläge:

Sicherheitsbezogene Vorschläge

  • Verwenden Sie PBKDF2 oder Bcrypt, wenn Sie können. Dafür ist es geschafft.

    Begründung: Beide Algorithmen können den Hashing-Prozess beliebig verlangsamen. Genau das möchten Sie beim Hashing von Passwörtern (schnellere Alternativen bedeuten einfachere Brute Force). Idealerweise sollten Sie die Parameter so anpassen, dass der Prozess auf derselben Hardware mit der Zeit immer langsamer wird, während neue, schnellere Hardware veröffentlicht wird.

  • Wenn Sie nicht können, zumindest Verwenden Sie MD5/SHA1 nicht. Noch nie. Vergiss es. Verwenden Sie stattdessen beispielsweise SHA512. Verwenden Sie auch Salz.

    Begründung: MD5 und SHA1 sind zu schnell. Wenn der Angreifer Zugriff auf Ihre Datenbank mit den Hashes hat und über einen (nicht einmal besonders) leistungsstarken Computer verfügt, ist das schnelle Erzwingen eines Kennworts schnell und einfach. Wenn keine Salze vorhanden sind, steigt die Wahrscheinlichkeit, dass der Angreifer das tatsächliche Kennwort findet (was zusätzlichen Schaden anrichten kann, wenn das Kennwort an einer anderen Stelle wiederverwendet wird).

  • Verwenden Sie in PHP 5.5.0 und höher password_hash und password_verify .

    Begründung: Das Aufrufen einer vom Framework bereitgestellten Funktion ist einfach, sodass das Risiko eines Fehlers verringert wird. Mit diesen beiden Funktionen müssen Sie nicht über verschiedene Parameter wie den Hash nachdenken. Die erste Funktion gibt einen single String zurück, der dann in der Datenbank gespeichert werden kann. Die zweite Funktion verwendet diese Zeichenfolge zur Kennwortüberprüfung.

  • Schützen Sie sich vor roher Gewalt. Wenn der Benutzer ein falsches Passwort übermittelt, als er bereits vor 0,01 Sekunden ein anderes falsches Passwort übermittelt hat, ist dies ein guter Grund, es zu blockieren. Während Menschen schnell tippen können, können sie wahrscheinlich nicht das schnell sein.

    Ein weiterer Schutz wäre die Festlegung eines Ausfalllimits pro Stunde. Wenn der Benutzer in einer Stunde 3600 falsche Passwörter übermittelt hat, 1 Passwort pro Sekunde, ist es kaum zu glauben, dass dies ein legitimer Benutzer ist.

    Begründung: Wenn Ihre Passwörter auf unsichere Weise gehasht werden, kann Brute Force sehr effektiv sein. Wenn Kennwörter sicher gespeichert werden, verschwendet Brute Force immer noch die Ressourcen und die Netzwerkbandbreite Ihres Servers, was für legitime Benutzer zu einer geringeren Leistung führt. Brute-Force-Erkennung ist nicht einfach zu entwickeln und richtig zu machen, aber für jedes andere als winzige System lohnt es sich auf jeden Fall.

  • Bitten Sie Ihre Benutzer nicht, ihre Passwörter alle vier Wochen zu ändern. Dies ist äußerst ärgerlich und verringert ​​die Sicherheit, da dies die post-it-basierte Sicherheit fördert.

    Begründung: Die Idee, dass das Erzwingen einer Änderung von Passwörtern alle n Wochen das System vor roher Gewalt schützt, ist falsch. Brute-Force-Angriffe sind normalerweise innerhalb von Sekunden, Minuten, Stunden oder Tagen erfolgreich, wodurch monatliche Kennwortänderungen irrelevant werden. Auf der anderen Seite können sich Benutzer schlecht an Passwörter erinnern. Wenn sie sie außerdem ändern müssen, versuchen sie entweder, sehr einfache Passwörter zu verwenden, oder notieren ihre Passwörter einfach auf Post-its.

  • Jedes Mal alles prüfen. Anmeldungen speichern, aber niemals Passwörter im Überwachungsprotokoll speichern. Stellen Sie sicher, dass das Überwachungsprotokoll nicht geändert werden kann (d. H. Sie können am Ende Daten hinzufügen, aber die vorhandenen Daten nicht ändern). Stellen Sie sicher, dass Überwachungsprotokolle regelmäßig gesichert werden. Im Idealfall sollten Protokolle auf einem dedizierten Server mit sehr restriktiven Zugriffen gespeichert werden: Wenn ein anderer Server gehackt wird, kann der Angreifer die Protokolle nicht löschen, um seine Anwesenheit (und den während des Angriffs eingeschlagenen Pfad) zu verbergen.

  • Erinnern Sie sich nicht an Benutzeranmeldeinformationen in Cookies, es sei denn, der Benutzer fordert Sie dazu auf (das Kontrollkästchen "An mich erinnern" muss standardmäßig deaktiviert sein, um menschliches Versagen zu vermeiden).

Vorschläge zur Benutzerfreundlichkeit

  • Lassen Sie den Benutzer das Passwort merken wenn er möchte, auch wenn die meisten Browser diese Funktion bereits haben.
  • Verwenden Sie den Google-Ansatz nicht, wenn der Benutzer nicht nach Benutzername und Passwort fragt, sondern manchmal nur nach Passwort gefragt wird, wobei der Benutzername bereits in einem <span/> Angezeigt wird. Browser können das Kennwortfeld in diesem Fall nicht ausfüllen (zumindest Firefox kann das nicht), sodass er gezwungen ist, sich abzumelden und sich dann mit einem normalen Formular anzumelden, das vom Browser ausgefüllt wird.
  • Verwenden Sie nicht JavaScript-fähige Popups für die Anmeldung. Es unterbricht die Passwort-Speicherfunktionen des Browsers (und ist in allen Fällen zum Kotzen).
  • Lassen Sie den Benutzer entweder seinen Benutzernamen oder seine E-Mail-Adresse eingeben. Wenn ich mich registriere, ist manchmal der Benutzername, den ich eingeben möchte, bereits vergeben, daher muss ich einen neuen erfinden. Ich habe alle Chancen, diesen Namen in zwei Stunden zu vergessen.
  • Behalten Sie immer einen Link zu "Passwort vergessen" Funktion in der Nähe des Anmeldeformulars. Zeigen Sie es nicht nur an, wenn sich der Benutzer nicht angemeldet hat: Benutzer, die sich überhaupt nicht an ihr Passwort erinnern, haben keine Ahnung, dass sie ein falsches Passwort senden müssen, um den Link "Passwort vergessen" anzuzeigen.
  • Verwenden Sie nicht Sicherheit per Post-it .
  • Erfinde nicht dumme Regeln bezüglich des Passworts, um es schwächer zu machen. Beispiel: "Ihr Passwort muss mit einem Kleinbuchstaben beginnen."; "Ihr Passwort darf keine Leerzeichen enthalten."
21
  1. Ihre Site sollte verwenden Sie HTTPS. Sie sollten zu keinem Zeitpunkt eine Anmeldeseite anzeigen oder Anmeldungen von einer unverschlüsselten Verbindung akzeptieren.
  2. Ihre Cookies sollten auf nur HTTP beschränkt sein und auf sichere Verbindungen beschränkt sein, wenn Sie HTTPS verwenden.
  3. Der Anmeldevorgang sollte mindestens 2 Sekunden dauern (1, wenn Sie 2 Sekunden für zu lang halten). Verwenden Sie einen sicheren Hash beim Speichern und Überprüfen von Passwörtern und verwenden Sie ein Salz, das schwerer zu erraten ist. Verwenden Sie nach Möglichkeit bcrypt. Verwenden Sie andernfalls eine andere Art von iteriertem Hash.
  4. Never ever Verfassen Sie Ihre Datenbankabfragen auf eine Weise, die die Verwendung von Funktionen wie mysql_real_escape_string Erfordert. Verwenden Sie niemals die Verkettung von Zeichenfolgen, um Ihre Abfrage zu erstellen. Verwenden Sie vorbereitete, parametrisierte Abfragen. Die meisten, wenn nicht alle DB-Treiber für PHP unterstützen dies. Wenn Sie dies nicht tun) Ich weiß nicht, wie es geht, verbringe einige Zeit damit, zu lernen, wie man prepare, bind und execute mit der von Ihnen verwendeten Datenbank verwendet. Es ist die nur sicherer Weg, sich vor SQL-Injection zu schützen. PDO unterstützt dies.
  5. Ermutigen Sie Ihre Benutzer, nicht das gleiche Passwort zu verwenden, das sie für ihre E-Mail verwenden. Erinnern Sie sie daran, dass jemand ihre E-Mails entführen kann, wenn Ihre Website kompromittiert ist und sie an beiden Stellen dasselbe Kennwort verwenden.
6
greyfade
  • Verwenden Sie niemals MD5- oder SHA1-Hashing-Algorithmen. Halten Sie sich immer an neuere wie SHA512
  • Verwenden Sie immer ein stark zufällig erzeugtes Salz
  • Senden Sie Ihren Benutzern niemals eine E-Mail mit ihren Passwörtern, auch nicht im Fall von "Passwort vergessen".
  • Verwenden Sie niemals die Funktionen mysql_ *. Sie werden lange abgeschrieben. Halten Sie sich an die gU
  • Speichern Sie niemals Passwörter in Sitzungen oder Cookies
1
Robin Thomas

Verwenden Sie einen gesalzenen Einweg-Hash (vorzugsweise SHA512 mit http://au2.php.net/manual/en/function.hash.php ) ... auf diese Weise, wenn jemand Ihre Datenbank hackt Selbst wenn sie das Salz kennen, können sie die Passwörter nicht extrahieren (ohne eine Rainbow-Tabelle, die für SHA512 zu lang wäre).

Verwenden Sie HTTPS.

Senden Sie keine Benutzernamen-/Passwortbestätigungen per E-Mail an den Benutzer zurück, wenn dieser sich registriert.

Wenn Sie Cookies für "Erinnere dich an mich" zulassen, fügen Sie ein zusätzliches Login hinzu, um auf die Verwaltungs- und Profilbearbeitungsfunktionen zuzugreifen.

Wenn ein Benutzer ein falsches Passwort erhält, sagen Sie nicht, dass er das Passwort falsch geschrieben hat (sagen Sie, dass er immer den 'Benutzernamen oder das Passwort falsch' hat) - auf diese Weise weniger Hinweise auf gültige Benutzernamen.

Versuchen Sie, den Bildschirmnamen im Vergleich zur Anmeldung zu implementieren. Auf diese Weise zeigen weniger Benutzer ihren Anmeldenamen in Benutzerlisten an.

1
HorusKol

Hier ein Tipp: Stellen Sie sicher, dass mit JS nicht auf Ihre Cookies zugegriffen werden kann, um Diebstahl zu verhindern. Siehe Schutz Ihrer Cookies: HttpOnly Artikel von Jeff Atwood

... Durch geschickte Konstruktion schafft es die fehlerhafte URL nur, am Desinfektionsmittel vorbei zu quietschen. Der endgültig gerenderte Code lädt im Browser ein Skript und führt es von diesem Remote-Server aus.

... wer diese mit Skripten injizierte Benutzerprofilseite lädt, hat gerade unabsichtlich seine Browser-Cookies an einen bösen Remote-Server übertragen!

Wie wir bereits festgestellt haben, hat jemand, der Ihre Browser-Cookies für eine bestimmte Website hat, im Wesentlichen die Schlüssel zum Königreich für Ihre Identität dort ...

0
James