Login-System

cr4m0

Angesehenes Mitglied
Ich habe ein Login-System programmiert. Das ganze funktioniert so:
1) Beim Anmelden wird ein Cookie mit dem Usernamen und dem Passwort (MD5) erstellt.
2) Die Datei "xyz.php" wird auf allen Seiten per "include" eingebunden.
3) Diese Datei zählt die Datenbankeinträge, die als Namen den Cookie-Namen und als Passwort das Cookie-Passwort haben. Ist die Anzahl größer als 0, dann setzt das Script die Variable "eingeloggt" auf 1 und legt die entsprechende User-ID fest.
Meint ihr, das System ist so sicher? Oder ist das mit Cookies allgemein ein Risiko? Sollte ich besser Session-IDs nehmen? Danke im Voraus!
 
Sicher gegen was?
Cookies sind allgemein kein Problem. Es kommt drauf an, was drin steht.
SessionIDs in Cookies und Passwörter in Cookies haben einen unterschiedlichen Zweck. Was willst du erreichen?
 
eingeloggt=1...ist das ein Cookie?

Dann ist es komplett unsicher.

Wenn es in einer DB ist, dass muss unbedingt noch ein IP Check her! ==> Problem bei Firmen mit Load Balancern.

COOKIES sind ein Problem. Cookies können via JavaScript ausgelesen werden => XSS.

Du musst das Cookie so setzen, dass ein Auslesen via JS nicht möglich ist.

Desweiteren haben die User im normalfall schlechte Passwörter wie z.B. "1234", "love" oder "sex". Desshalb muss das Passwort salted sein. MD5 alleine genügt nicht!
 
Danke schonmal! Ich mache jetzt mal ein Beispiel, sodass es besser verständlich ist:

-----------

Ein User hat den Namen "Haus" und das Passwort "Auto". Dann wird nach dem Absenden des Login-Formulars ein Cookie gesetzt, das den folgenden Inhalt hat: "Haus==06b9281e396db002010bde1de57262eb".
Bei jedem Seitenaufruf wird der Inhalt ausgelesen, per explode() werden dann beide Teile getrennt. Die Abfrage lautet dann: "SELECT id FROM users WHERE name LIKE 'Haus' AND passwort LIKE '06b9281e396db002010bde1de57262eb'". Wenn die Anzahl der gefundenen Datensätze > 0 ist, dann werden zwei Variablen gesetzt:
$userid = ID_AUS_DER_SQL_ABFRAGE
$eingeloggt = 1
Mit den Variablen arbeite ich dann weiter. Ist das so verständlicher?
smile.gif


-----------

Jetzt kommen zwei Sachen, die ich nicht verstanden habe. Könntet ihr die bitte noch einmal ausführlicher erklären?
1) "Wenn es in einer DB ist, dass muss unbedingt noch ein IP Check her!" Was ist jetzt genau damit gemeint? Wieso muss der IP-Check her?
2) "Du musst das Cookie so setzen, dass ein Auslesen via JS nicht möglich ist." Wie geht das?

-----------

Also wäre mein Passwort viel sicherer gespeichert, wenn ich es so mache?
md5(md5(md5(md5(md5($passwort.$salt)))))
Ist das richtig?
 
Hier zur Erklärung, warum schlechte PAsswörter per MD5 einfach rauszukriegen sind:
http://md5.thekaine.de/?hash=06b9281e396db...10bde1de57262eb

Noch ein kleines Rechenbeispiel:
Auto hat mit 4 Stellen nur eine Wahrscheinlichkeit von 4^64
zf91hsbmiz8hch690sslAuto hat eine Wahrscheinlichkeit von 24^64

Mit dem salting, mach es so (nur ein Beispiel)
$salt="zf91hsbmiz8hch690ssl";
$pw="1234";
md5($salt$pw);

Die IP Sperre muss her, damit man ausgeloggt wird, wenn man z.B. das Cookie lokal (physisch) gestohlen hat.

Cookie welches via JS nicht ausgelesen werden kann.
setcookie("passwort", "$md5_salted", time()+2592000, NULL, NULL, NULL, TRUE);

Hier kannst Du Dich etwas einlesen:
http://techblog.tilllate.com/2007/03/25/si...kt-und-behoben/
 
OK, danke!
Was haltet ihr denn davon, die Passwörter mehrfach mit md5 zu verschlüsseln? Zum Beispiel 789 Mal hintereinander, dann wird es doch extrem schwer, den Hash zu knacken, oder?

Wie soll denn die IP-Sperre funktionieren? Der "echte" User bekommt ja auch ständig eine neue IP, wie kann ich ihn dann von einem "unechten", also dem Cookie-Dieb, unterscheiden?
 
QUOTE (cr4m0 @ Fr 29.02.2008, 21:49) OK, danke!
Was haltet ihr denn davon, die Passwörter mehrfach mit md5 zu verschlüsseln? Zum Beispiel 789 Mal hintereinander, dann wird es doch extrem schwer, den Hash zu knacken, oder?

Wie soll denn die IP-Sperre funktionieren? Der "echte" User bekommt ja auch ständig eine neue IP, wie kann ich ihn dann von einem "unechten", also dem Cookie-Dieb, unterscheiden?

extrem inperformant.
 
Ja OK, man muss es ja nicht so übertreiben. Aber wenn man es so 8 Mal macht oder so, bringt das dann was? Derjenige, der das Ganze knacken will, weiß ja nicht, wie oft du MD5 angewendet hast. Also kann er es doch nur sehr schwer rausfinden, oder?

Und wie funktioniert jetzt so eine IP-Sperre? Es wäre super, wenn das einer mal erklären könnte. Ich versteh das irgendwie nicht...
smile.gif
 
Ich versehe den Sinn von mehreren MD5 nicht. Salting ist sicherer...

Ip-Sperre ist falsch...

Provider sperre wäre richtig.
 
Ein mehrfaches MD5 macht die Sache nicht sicherer, sondern im Gegenteil, extrem unsicher, lass das lieber sein. Und verwende, wie schon hier gesagt, unbedingt das Salting.

Kurz zur Info. MD5 ist ein kryptografischer Hash, einfach gesagt eine Checksumme. Für kurze Texte existieren Datenbanken, die per Rechenleistung alle MD5-Werte ausgerechnet haben ("Regenbogentabellen"). Wenn Du also einen MD5 für z.B. ein 6-stelliges Passwort benutzt, kann Dir ein versierter Hacker leicht sagen, mit welchem Passwort Dein MD5 gelöst wird. Kurz gesagt: MD5 an sich ist für sehr kurze Texte unsicher. Das Salting macht die Nutzung von Tabellen schwieriger. Denn anstatt einer Tabelle braucht ein Angreifer dann (bei 32-Bit-Salt) theoretisch 2^32 Tabellen. Bei wenig Mehraufwand ein großer Sicherheitsgewinn. Abgesehen davon hat MD5 bei den Kryptologen keinen besonders guten Ruf mehr, es steht im Verdacht, "knackbar" zu sein.

Schau Dir auf jeden Fall mal die Login-Systeme von beliebten CMS-Systemen etc. an. Wenn Du dann ein bisschen in der Entwicklugnsgeschichte herumstöberst wirst Du finden, dass bei vielen nur kleine Fehler zu großen Exploits geführt haben. Gut, um davon zu lernen.
 
OK, ich habe jetzt die Salts integriert. Beim Login wird zuerst der Salt-String des angegebenen Benutzernamens aus der Datenbank gelesen. Dann wird der Salt-String direkt hinter das eingegebene Passwort gesetzt und dieser String mit MD5 verschlüsselt. In der Datenbank sind dann nur noch die "gesalteten" Passwörter. Das ist doch so richtig, oder?

Jetzt bleibt nur noch das Problem mit dem Cookie-Diebstahl. Was meint ihr, wie kann man das verhindern?
- IP-Sperre: Probleme bei dynamischen IPs
- Provider-Sperre: Wenn ein User den Provider wechselt, kann er sich nicht mehr einloggen
Was gibt es noch für Möglichkeiten?
 
QUOTE (cr4m0 @ Sa 1.03.2008, 13:32)Jetzt bleibt nur noch das Problem mit dem Cookie-Diebstahl. Was meint ihr, wie kann man das verhindern?

Sorg dafür, dass deine Benutzer kein HTML verwenden können, dann brauchst du dir um XSS auch keine Gedanken machen.
 
Gut, ich verarbeite alle Eingaben mit strip_tags() und addslashes(), das sollte dann reichen, oder?
 
Das Salzen ist noch nicht richtig. Du solltest mit unterschiedlichen, zufälligen Salts arbeiten. Das gibt dann Einträge a la "saltedHash = salt . MD5(salt.pw)".
 
Ich arbeite mit unterschiedlichen Salts. Jedem Nutzer wird bei der Registrierung ein Salt zugewiesen, der aus zufällig ausgewählten Zeichen besteht. Der String wird dann in die Datenbank eingetragen.
Aber wie soll ich die Salts jetzt verarbeiten, welche der drei folgenden Möglichkeiten ist die beste?
1) $saltedpw = md5($passwort.$salt);
2) $saltedpw = md5(md5($passwort).$salt);
3) $saltedpw = $salt.md5($passwort.$salt);
 
2) wäre ein Fehler. Und für den Hash sollte das Salt am Anfang stehen, also immer MD5($salt.$pw) und nicht MD5($pw.$salt). Also üblicherweise:

4) $saltedpw = $salt.md5($salt.$pw)

Und wenn Du die Salts gesondert speichern willst:

5) $saltedpw = md5($salt.$pw)

Schau Dir vielleicht auch mal die Zufallsfunktionen bei Squirrelmail an - das geht auch weit über ein einfaches rnd() hinaus...
 
OK, danke!
Wieso sollte denn der Salt am Anfang des neuen Strings stehen? Ist das nicht egal?
 
Das Salt ist ja nur dafür da, um sich gegen Tabellen-Attacken zu schützen. Ohne Salt bräuchte ein Angreifer nur eine Tabelle. Mit einem wirklich zufälligen Salt (32 bit), bräuchte ein Angreifer 2^32 Tabellen.

Bei der Variante md5($passwort.$salt) wäre dein effektives Salt nicht "$salt", sondern die ersten vier Zeichen von $passwort. Und wenn Du das auf passworttypische alphanumerische Zeichen einschränkst, bräuchte ein Angreifer statt 2^32 "nur" (26+26+10)^4 Tabellen. Das ist zwar immer noch sehr viel, aber Du würdest Dein Salt ja ohne Not schwächen.

PS: für Prüfsummen auf z.B. Dateien ist MD5 nicht mehr sicher, bzw. muss zusammen mit anderen Mitteln genutzt werden. Es gibt mittlerweile automatische Tools zur Ausnutzung der MD5-Schwächen. Damit lassen sich Dateien mit beliebigen MD5-Prüfsummen erstellen.
 
Für mich ist das ganze Konzept nicht schlüssig.

Nutzernamen und Passwörter haben nichts in Cookies zu suchen - völlig egal, ob im Klartext oder mit welchem Aufwand verschlüsselt.

Wenn sich ein Nutzer anmeldet, dann starte eine Session mit einem Session-Cookie. Die Session verfällt nach einer gewissen Zeit der Inaktivität.

Theoretisch könnte man dein Konzept nutzen, um ein permanentes Anmelden zu ermöglichen. Das geht aber auch dann, wenn man bei der Anmeldung eine Zufallszeichenfolge erzeugt und die (1) zusätzlich in der Nutzertabelle, (2) in einem Cookie mit Standardnamen abspeichert - für die Nutzer, die eine Option 'immer angemeldet sein' nutzen möchten.

Und die Datenbank muß man ohnehin direkt schützen - bsp. gegen Sql-Injektionen. Wenn jemand unberechtigt Spalten auslesen kann, dann ist dies das Problem - eine Spalte (hier: Die mit dem Passwort) zu verschlüsseln nützt dann auch nicht mehr so viel, ist eher Kosmetik.

Wenn Sql-Injektionen möglich sind, dann muß ich kein Passwort mehr hacken.
 
Zurück
Oben