• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Das "perfekte" Login-System...

DarkDragon193

Neues Mitglied
Hallo, liebe HTML.de-Comm!

Ich frage mich hin und wieder, ob mein Login-System auch wirklich gut ist... Leider habe ich jetzt konkret keinen Source Code, da ich diesen zur Zeit noch entwickle. Aber im Grunde sieht der ungefähr so aus:
  1. User registriert sich.
  2. User bekommt eine Bestätigungs-E-Mail.
  3. User loggt sich ein.
  4. Da ich mit Sessions arbeite überprüfe ich, ob die User-ID in $_SESSION gesetzt ist.
  5. Zusätzliche Inhalte sind "freigeschalten".

Wie könnte man das System verbessern? Ich habe so ein Gefühl, dass die Abfrage nach der User-ID nicht gerade die beste ist. Außerdem, welche Vulnerabilites muss ich beachten? htmlspecialchars um Eingaben des Benutzers, die auf der Homepage ausgegeben werden, und mysql_real_escape_string um Datenbankabfragen, die vom Benutzer manipuliert werden, abzusichern. Außerdem lade ich nicht "dynamisch" mit
PHP:
include $_GET[ "page" ];
oder sonst etwas und mein Server ist sowieso gegen http-include geschützt. Gibt es dennoch Wege, eigenen Code extern einzubringen? Eine Liste mit bekannten XSS-Attacken würde Abhilfe schaffen... ;)

Apropos, hier geht es nicht nur um die Sicherheit des Scriptes, sondern auch um ästhetische Verbesserungen. Was gehört in ein Login-/Account-System und was ist ein NoGo?

Ich hoffe, es ist alles klar, was ich sagen will, ansonsten muss ich an meiner Ausdrucksweise arbeiten. xD

Mit freundlichen Grüßen,


DarkDragon1993
 
Werbung:
Ziemlich unsicher.
Du solltest nicht nur die User-ID überprüfen, sondern in der Session auch das Passwort speichern und bei jedem Seitenaufruf, bei dem man eingeloggt sein muss, muss beides wieder geprüft werden.
Ein Tipp zu User-Eingaben:
Wenn z.B. eine ID oder eine Zahl gefragt ist, dann überprüfe so:
PHP:
$id = $_GET['id']+0;
PHP wandelt die Eingabe dann in eine Zahl um, egal was es ist. Wenn es keine Zahl ist, wird 0 draus.
Wenn du nur verschiedene Möglichkeiten als Eingabe hast, dann kannst du einen Array mit den Möglichkeiten erstellen und dann überprüfen, ob die Eingabe in dem Array vorkommt.
Alleine auf htmlspecialchars würde ich mich nicht verlassen.
 
dafür gibt es intval. in der session das passwort zu speichern ist auch eine schlechte idee. damit liegen alle passwörter im /tmp und können ausgelesen werden.
 
Werbung:
naja häufige angriffsmethode ist z.b. SQL-Injection.
desweiteren würde ich die passwörter "salzen" (z.b. bei md5-hashes) d.h. eine random zahl mit in den hash einbauen der in der datenbank gespeichert ist.

was es auch gibt ist ein kurzzeitpasswort.
also es wird nur 1mal überprüft, ob der user das richtige passwort eingeben hat.
danach wird ein zufallspasswort erstellt, das für eine bestimmt weile aktiv ist (z.b. 15min). fals jemand dieses passwort klaut, kommt er nicht weit, weil das pw nicht zu dem user passt.
 
Zum intval:
Meine Möglichkeit ist genauso richtig und dazu noch um einiges kürzer.
Zum Password:
Das Passwort sollte natürlich nur als Hash vorliegen. Bei einem vernünftigen Passwort kann das niemand herauslesen. Dazu ist das eigentlich egal, da die meisten Internetuser das Passwort eh unverschlüsselt vom Browser speichern lassen. Die Möglichkeit von Mad Dog ist natürlich sicherer.
 
Das mit der "Typumwandlung" ist mir schon vorher bewusst gewesen genauso wie man aus einer Zahl mit
PHP:
$num = 0;
echo $num . "";
einen String machen kann. Dennoch danke.
MD5 wollte ich sowieso noch mit einbringen, keine Frage. Habe ich wohl vergessen zu erwähnen. Bei Passwörtern bin ich immer ziemlich vorsichtig und habe bisher bei den richtig wichtigen Seiten eine erneute Eingabe des Passwortes gefordert... Das mit dem temporären Passwort klingt allerdings sehr gut. ;)
Ich habe auch gedacht, dass reCaptcha bei der Registrierung nützlich wäre. Was haltet ihr davon? Ich sehe da keine Probleme...
 
Werbung:
Ein CAPTCHA ist immer gut. Wenn du das mit Hash's lösen willst, dann benütze bitte sha. md5 ist veraltet.
So z.B.:
PHP:
$hash = hash('sha256', $password);

Wenn du das noch ein wenig sicherer machen willst, dann kannst du, wie Mad Dog schon gesagt, den Hash ein wenig Salzen.
z.B. die User-ID an das Passwort anhängen und dann erst den Hash draus machen. Dass das dann in einer Rainbowtabelle steht, ist sehr unwahrscheinlich (z.B.: meinpasswort243521):
PHP:
$hash = hash('sha256', $password.$user_id);
 
Zuletzt bearbeitet:
md5 veraltet? So ein Humbug. Nur weil es jetzt enorme Tabellen gibt, die einen den Hashwert umkehrt, heißt das noch lange nicht, dass es veraltet ist. Wenn man das Passwort richtig salzt, ist das kein Problem.

Die Typenkonvertierung macht man nicht mit irgendwelchen Hacks, das macht man mit den Typecasting-Statements oder mit den dafür vorgesehenen Funktionen.
 
Ich sage nur das, was so gut wie alle Quellen berichten. Für eine normale Webseite wird md5 auf jedenfall reichen, aber sha ist sicherer. Und: Was spricht gegen diese Hacks und was für die Funktionen?
 
Werbung:
Die Hacks (es sind meines Erachtens Hacks) nutzen eben nur implizites Typecasting. Der Einsatz von Funktionen beziehungsweise der expliziten „Operatoren“ ((string), (int), …) ist dagegen einfach aussagekräftiger.

Zumindest ich empfinde es als sauberer, explizit im Code lesen zu können, dass eine Typumwandlung erfolgt, statt wissen zu müssen, dass PHP als schwach typisierte Sprache den „Seiteneffekt“ hat, beim „+“-Operator je nach Datentypen der Operanden entweder einen Float oder einen Integer zu erzeugen.

Wie gesagt, Float oder Integer:

PHP:
var_dump(+"12.5");

Du könntest dann noch schreiben:

PHP:
$id = floor($_GET['id'] + 0);

Selbst das wäre noch ein Float.

It's not worth it.
 
Hallo,
Generell dazu übergehen in PHP "Prepared Statements" (PDO) zu verwenden.
Damit hat man das Thema SQL Injections schon zum weitesten Teilen abgearbeitet.
Alle Eingaben, die auf User-Eingaben beruhen oder von außen offensichtlich modifizierbar sind auf Validität prüfen.
Vorsicht bei der mail() Funktion und Header-Injection.
 
das hin und her casten von typen mag in der praxis super funktionieren, ist jedoch sehr unschön. das gehashte passwort in den tmp zu schieben halte ich auch für ungünstig, ich arbeite idr. dann mit einem handshake der sich zwischen jedem seitenaufruf ändern. wenn man parallele Requests hat, muss man natürlich anders vorgehen...
 
Werbung:
Erstmal erneut danke für die zahlreichen Antworten.

Nochmal zum Typecasting: In der Regel verwende ich explizit die dazu vorgesehenen Funktionen, eben auch aus dem Grund, dass es schön leserlich und in 3 Wochen noch immer leicht nachvollziehbar ist.

Zum eigentlichen Thema: Es scheinen da ein paar Unstimmigkeiten zu geben, wie ich erwartet hatte. Mich würde aber auch interessieren, was es mit der mail-Funktion und der Header-Injection auf sich hat? Ich persönlich wandele alle Benutzereingaben XSS-sicher um und kann mir eigentlich relativ wenige Vulnerabilites vorstellen... Was aber wohl eher an mangelndem Wissen liegt.
Was PDO betrifft... Ich habe mich jetzt nicht gerade ausführlich darüber belesen, denke aber, dass ich das sowieso nicht verwende, es sei denn es ist fest in PHP integriert und wird bei mysql_connect gebraucht. Bezweifle ich aber gerade. ;)

Also, bis jetzt baue ich in mein Login-System also noch gesalzte sha256-Hashes ein. Gut gesalzen wäre wohl noch mit einem Time-Stamp, schätze ich.
Auch reCaptcha findet jetzt Einzug in meine Homepage, da ich allerdings mit jQuery und AJAX arbeite muss ich die Implementation noch richtig zum Laufen bringen...

Übrigens, ich versuche durch eine "bestimmte Methodik" den Zugriff auf "geschützte" Variablen zu verhindern. Diese Methode ist mir aufgefallen, als ich das Framework Prototype etwas durchforstet habe... Ich finde sie echt klasse. :) Und falls jetzt etwas kommt von wegen Benutzer, die kein JavaScript unterstützen: Ich habe ein Fallback auf PHP eingebaut.

Falls noch weitere Vorschläge kommen freue ich mich auch über diese!

Mit freundlichen Grüßen,


DarkDragon1993
 
Ich veränder gerne die Zeichenfolge meiner Passworthashes und negiere diese. Dadurch, dass alle Hashes die gleiche Länge haben, entsteht quasi ein Private Key, der nur im Programmcode vorkommt.
 
Ist auch eine Möglichkeit. Egal was ich mir einfallen lasse, wenn es ausgefuchst ist wird niemand das Teil knacken, schätze ich... xD
 
Werbung:
Zurück
Oben