SQL-Befehl zur Benutznamen/Passwortüberprüfung



  • Hi,
    Wie kann ich mit einem SQL - Befehl schauen ob sich jemand den richtigen Benutzernamen mit PW eingegeben hat?
    Also bisher habe ich das so gemacht, dass ich immer die ganze Tabelle per for-Schleife(PHP) und "mysql_result(Account_Tabelle, For_Schleifenvariable, Account_Name)" durchgegangen bin und dann einfach per if-Abfragen geschaut habe ob der User existiert und ob dieser dann das richtige Passwort eingegeben hat.
    Das klappt auch alles wunderbar, aber ich glaube da gibt es eine einfacher (und vllt. auch schnellere) Lösung mit SQL-Befehlen,die ich über PHP aufrufen kann.
    Suche/Probiere schon seid knapp 40min, aber irgendwie will das alles nicht so 🙂

    Frage 2:
    Wie sicher sind HiddenFields? Ich nutzt sie momentan um Variablen aufzubewahren (logisch ne^^), aber bin mir nicht sicher in wiefern (und einfach) man diese Daten lesen kann bzw. in wie weit sie verschlüsselt sind.

    Danke

    Edit: Hab geschafft 🙂
    Hier der Code:

    $SQL = "SELECT 
    	 				 *
    	 				 FROM 
    	 				 Tabelle 
    	 				 WHERE 
    	 				 Name = '".mysql_real_escape_string(strtoupper($_POST['Name']))."' 
    	 				 AND Passwort = '".mysql_real_escape_string($_POST['Passwort'])."';";
    	 $SQL_Query = mysql_query($SQL);
    
    	 if (mysql_num_rows($SQL_Query) != 1) //Wenn er nichts (oder warum auch immer) mehr gefunden hat
    	 {
    	 		header ("location: index.php?Error=1");
    	 		exit;
    	 }
    


  • Hallo,

    1. unterlasse lieber das strtoupper() bei deiner Query. Der code bedingte nämlich, dass du sämtliche Namen als Großbuchstaben in deiner Datenbank speicherst. Das heißt: Datenverlust, wenn der Benutzername ihn anders eingegeben hat! Abgesehen davon berücksichtigt der Stringvergleich in MySQL ohnehin keine Groß- und Kleinschreibung, es ist also auch schlicht überflüssig 😉 Willst du einen Vergleich - wie es z.B. beim Passwort der Fall ist - mit Berücksichtigung der Groß- und Kleinschreibung durchführen, dann caste einen der Beiden Strings zum BINARY-Typ:

    $SQL = 'SELECT * FROM Tabelle WHERE BINARY Name = '.mysql_real_escape_string($_POST['Name'])."' 
                          AND BINARY Passwort = '".mysql_real_escape_string($_POST['Passwort'])."'";
    

    2. Wenn du ein System wirklich einsetzen willst, wäre es grob Fahrlässig die Passwörter der Benutzer im Klartext zu speichern. I.a.R. solltest du nur Hashwerte der Passwörter speichern (im Moment gilt beispielsweise sha512 noch als sicher, nativ unterstützen tut PHP nur sha1; das reicht aber auch), und dann einen Hashvergleich durchführen:

    INSERT INTO Tabelle(Name, Passwort VALUES($Name, SHA1($Passwort))
    

    (Pseudocode!)

    3. Ich würde eine solche Abfrage zur Sicherheit mit Limit 1; abschließen. Sollte er - warum auch immer - mehr als einen Eintrag finden, ist das System ohnehin kontaminiert - oder zumindest in einem Zustand, in dem es nicht betrieben werden sollte. Dann kannst du ganz einfach mit

    if($sqlQuery) {}
    

    prüfen, ob du ein Ergebnis hattest. Ist nur eine Kleinigkeit und vlt. auch oft Geschmackssache - Aber ich bringe in jede Abfrage ein LIMIT rein, wo es nur geht 😉

    4. Zu den Hidden-Feldern: Die Sicherheit strebt gegen 0 (sofern man hierbei überhaupt das Wort "Sicherheit" in den Mund nehmen darf) 😉



  • Das mit der Groß- und Kleinschreibung hab ich auch gerade gefunden 🙂
    Die Passwörter werde ich später natürlich nicht im Klartextformat speichern, aber welche Verschlüsselung etc. ich benutze hab ich mir noch nicht genau überlegt, daher erstmal alles im Klarttext (Eine registrier-Funktion wird es eh nicht geben, da die Daten schon in einer SQL Datenbank vorhanden sind und ich diese daher nur kopieren brauche)
    Mit dem Limit schaue ich mal wie ich es mache - ich hab die Abfrage mit != 1 eingebaut um die SQL-Tabelle an sich noch einmal zu prüfen, da die meisten Daten (wie oben schon gesagt) schon vorhanden sind und der Mensch beim Eingeben der Daten in die Tabelle auch Fehler machen kann. So würde ich beim Testen solche Fehler schon finden.

    Das HiddenFields unsicher sind hab ich mir gedacht - schade eigentlich, naja dann muss ich alle Daten serverseitig speichern.

    Dazu nochmal eine Frage:
    Ich hatte mir das so gedacht (wenn auch leider nicht so sicher wie ich es gerne hätte), dass ich bei jedem Login den Namen/Uhrzeit/Passwort/generiertet LogIn-ID in einer SQL Datenbank auf dem Server speichere. Die LogIn-ID wird dann in einem Cookie auf dem Client gespeichert und nach dieser ID (die dann sowohl im Cookie und auf dem Server die gleiche ist) identifiziert sich der User.
    Dass diese Methode, wenn man denn an die SessionID im Cookie kommt (was ja relativ leicht, bei manipulierten Links geht) nicht 100% sicher ist, weiss ich.

    Daher Frage eins: Gibt es noch andere Möglichkeiten/ Verbesserungen an dieser Idee, sodass einem z.B. das Klauen der SessionID nichts nützt?

    Zum Zweiten: Die SessionID's in der SQL Tabelle (und der Cookie) verfallen nach z.B. 10min. Wenn ich nun viele Zugriff auf meine Seite in einem relativ kurzem Zeitraum habe, habe ich nun Angst, dass mir der Sever bei den ganzen SQL Anfragen einbricht. Kann das (wenn man mal von einer realistischen Zahl User in einer realistischen Zeit ausgeht, bei einem "normalen" webserver) wirklich passieren, sodass ich meine Idee nochmal überdenken muss oder brauch ich mir da keine Sorgen machen?
    Ich hab jetzt wenig Ahnung, welche Funktionen einen schnelleren Zugriff habe, bin erstmal soweit froh, dass alles funzt 🙂



  • Pille456 schrieb:

    Die Passwörter werde ich später natürlich nicht im Klartextformat speichern, aber welche Verschlüsselung etc. ich benutze hab ich mir noch nicht genau überlegt, daher erstmal alles im Klarttext

    Keine Verschlüsselung, sondern ein Hash 😉
    Denn eine Verschlüsselung arbeitet mit einem Key, mit dem die Passwörter entschlüsselt werden können. Hackt sich nun jemand in dein System ein, wird er - wenn er schon alle Daten aus der Datenbank auslesen kann - vermutlich auch an den Key kommen. I.d.R. nimmt man dafür MD5 oder SHA1 (beide werden nativ sowohl von PHP als auch MySQL unterstützt. Willst du wirklich sicher gehen, nimm einen Algorithmus mit längeren Hashes, z.B. SHA512 oder Whirlpool).

    Pille456 schrieb:

    Daher Frage eins: Gibt es noch andere Möglichkeiten/ Verbesserungen an dieser Idee, sodass einem z.B. das Klauen der SessionID nichts nützt?

    1. Cookiedaten verschlüsseln. So erschwerst du ein Faken der ID, da der Angreifer - wenn er sich selbst eine andere ID geben will - immer noch deinen Serverseitigen Key braucht, um sein Cookie "richtig" zu verschlüsseln.
    2. Du kannst ein Ticketsystem implementieren. Bei jedem Zugriff wird ein neuer Code aus einer Folge generiert und im Cookie und Server gespeichert. Beim nächsten Zugriff wird der Wert abgeglichen, und wenn er falsch ist, wird der Zugriff nicht autorisiert. Nachteile: Höhere Serverlast (durch ewiges Neusetzen, Ver- und Entschlüsseln der Cookies und durch das Generieren der Folge) und der "Zurück"-Button in vielen Browsern wird ausgehebelt.

    Zum letzten: SQL-Server werden meistens stark unterschätzt, habe ich das Gefühl. Eine Zugriffszahl im Tausenderbereich ist so gut wie nichts für einen MySQL-Server, selbst wenn er nicht auf einem High-End-PC läuft. Da solltest du dir vorerst keine Gedanken machen 😉


Anmelden zum Antworten