Keine Ahnung: LogIn mit Daten aus MySQL DB sicher?

Hallo,

ich habe inzwischen einige Loginsachen gemacht und mit die Zugangsdaten immer aus einer MySQL Datenbank geholt. Also ein Formularseite und dann geprüft ob die Angaben mit den Daten aus der SQL DB übereinstimmen. Also so:
$sql = mysql_query("SELECT Passwort, Login FROM zugang WHERE Login = '$Login'") OR die(mysql_error());
In Login steht das was vom Formular via post gekommen ist. Danach kommt halt dann noch eine if Abfrage ob das Passwort übereinstimmt.

Jetzt frage ich mich gerade ob das überhaupt sicher ist. Ist es sehr leicht sowas zu knacken?

Und wenn ja wie macht man einen sicheren Login mit PHP und MySQL.

Besten Dank

  1. Grüße,
    na ja - man empfiehl be sowas md5 oder andere kodierungsmethoden zu verwenden , aber glaub mir - kein mensch wird deine HP hacken wolen (solange es nicht kommerziell oder populär ist) - der aufwand wäre idiotisch unproportinal zum nutzen
     Wenn überhaupt dann ist der ganze hoster-server hin (da kannst du so oder so nix gegen machen) oder du fängst dir eine trojaner ein und dann sind gar alle passwörter "im freien".

    Aber wie gesagt - warum sich jemand die mühe machen könnte (seien es auch 10minuten) deine HPkaputt zu machen wäre mir ein rätzel

    - denn die die es können haben meist etwas .. "saftigere" Ziele im visier denke ich^^.
    MFG
    bleicher

    --
    __________________________-
    Menschen an sich , sind nicht schlecht - es sind nur ihre Taten (c).
    Lieber bereuen gesündigt zu haben, als nicht sündigen und es später trotzdem bereuen.
    Boccaccio
    1. na ja - man empfiehl be sowas md5 oder andere kodierungsmethoden zu verwenden

      Die Passwörter sind natürlich verschlüsselt.

      Dumm wäre es dennoch wenn jemand auf die Idee kommen würde weil halt doch private Adresse, Telefonnummern und sowas in der DB stehen.
      Ein paar Leute die die Seite kennen haben schon Ahnung und darum wäre es mir sehr peinlich wenn man mit zwei drei klicks die Seite gehackt hätte...

  2. Verwende eine Passwortverschlüsselung, prüfe die Eingaben gleich in SQL (nicht erst in PHP), verwende Superglobals und ganz wichtig: http://de2.php.net/mysql_real_escape_string

    Das würde ich mal auf die Schnelle als absolute Basics ansehen...

    Gruß, Samoht

    --
    fl:| br:> va:) ls:< n4:( ss:) de:] js:| mo:}
    "Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
    (Kristian Wilson, Nintendo, 1989)
    1. Danke für die Tipps habe es jetzt mal so gemacht wie du es vorgeschlagen hast.

  3. Übernimmst du $Login ohne vorherige Behandlung mit mysql_real_escape_string()?
    Dann hast du eine potenzielle SQL-Injection-Lücke, bei der der Angreifer beliebige SQL-Statements gegen deine Datenbank absetzen kann.
    Außerdem gäbe es noch eine weitere Möglichkeit, das Skript sicherer zu machen: Frag direkt die Datenbank, ob es einen User mit dem Login $Login und dem Passwort $Password gibt, damit kommt das Passwort nichtmal bis zum PHP-Skript.

    1. [...] damit kommt das Passwort nichtmal bis zum PHP-Skript.

      Das ist nicht korrekt. Würde das Passwort nicht ankommen, könnte man keine Abfrage starten. Lediglich das SQL-Statement liefert kein Ergebnis.

      Gruß, Samoht

      --
      fl:| br:> va:) ls:< n4:( ss:) de:] js:| mo:}
      "Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
      (Kristian Wilson, Nintendo, 1989)
      1. Das ist nicht korrekt. Würde das Passwort nicht ankommen, könnte man keine Abfrage starten. Lediglich das SQL-Statement liefert kein Ergebnis.

        Ich gehe natürlich davon aus, dass es sich um einen Loginversuch handelt, der fehlschlagen wird.

    2. echo $begrüßung;

      Übernimmst du $Login ohne vorherige Behandlung mit mysql_real_escape_string()?
      Dann hast du eine potenzielle SQL-Injection-Lücke, bei der der Angreifer beliebige SQL-Statements gegen deine Datenbank absetzen kann.

      Kann er nicht. Er kann maximal das vorhandene Statement ab der Stelle, ab der die SQL-Injection möglich ist, verändern. Damit kann man oftmals auch schon eine Menge Daten abfragen, die der Seitenbetreiber doch lieber gern geheim gehalten hätte. Um mehrere Statement in einem Query abarbeiten zu können, muss man bei MySQL MULTI_STATEMENTS aktivieren. Von PHP aus kann man das nicht, da muss man explizit mysqli_multi_query() nutzen.

      echo "$verabschiedung $name";

  4. Hello,

    $sql = mysql_query("SELECT Passwort, Login FROM zugang WHERE Login = '$Login'") OR die(mysql_error());

    ich würde das anders abfragen:

    $sql = "update $logintable ".
             "set login = now(), ".
             "    lastclick = now() ".          "    session = '".session_id()."', ".
             "    logged = 1 ".
             "where password = '".mysql_real_escape_sting($password, $con)."' ".
             "and loginname = '".mysql_real_escape_sting($loginname, $con)."' ".
             "and locked = 0;

    $ok = mysql_query($sql, $con);

    if($ok and mysql_affected_rows($con) == 1)
      {
        ## login ok, weitermachen
        #
        # ...
      }
      else
      {
        ## Fehlerbehandlung
        $_errormsg[] = 'Fehler beim Login';
        $_errormsg[] = mysql_error($con);
        # ...
      }

    Ich setze voraus, dass auf loginname ein Unique-Index liegt, um die Verwaltung zu vereinfachen.

    Nach obiger Methode hast Du gleich die Loginzeit und den letzten Request eingesetzt, geprüft, ob der Account gesperrt ist, und eine Gegenprüfung für die aktive Session vorbereitet.

    Eine "is_logged()"-Funktion kann man dann ähnlich aufbauen, ebenfalls mit Update.

    $sql = "update $logintable ".
             "set lastclick = now() ".          "where session = '".session_id()."' ".
             "and time_to_sec(timediff(now(), lastclick)) < $maxpause) ".
             "and locked = 0;

    Wenn man Trigger und storred Procedures nutzt, kann man das noch viel eleganter machen.

    Die Abfrage des Grundes, warum ein Login oder eine Loginbestätigung nicht geklappt haben, macht man erst dann mit einem ensprechenden SELECT, wenn es in Frage kommt. Wir gehen doch erstmal davon aus, dass die User "ordentlich" sind und daher seltener Fehler auftreten, als "anständige" Bestätigungen.

    lastclick       Spalte mit dem letzten Request des Users
    logged          Spalte mit einem Wert z.B. 0 für nicht logged, 1 für logged
    session         Spalte mit der aktuellen Sessionnummer des Users
    locked          Spalte mit einem Merker für gesperrte User, 0 = frei, >0 = Sperrgrund

    $maxpause       Dein Konfigurationswert in Sekunden, wie lange eine logische Session
                    gültig sein soll. Er muss KLEINER sein, als der Wert für die physische
                    Session, also der Wert des Garbage Collectors von PHP

    Außerdem ist das die() hier wieder vollkommen unangebracht.

    Ein harzliches Glückauf

    Tom vom Berg
    http://bergpost.annerschbarrich.de

    --
    Nur selber lernen macht schlau