php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2004

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 27.09.2004, 00:08  
Gast
 
Beiträge: n/a
Standard Zähler für Login

Hallo,

ich habe ein einfaches Login Skript den ich erweitern möchte.
bei falsches Passwort bekommt man eine meldung. Ich hätte es gerne das beim 3.Versuch der Benutzer gesperrtt wird.
Wie kann man so etwas erstellen??

Vielen Dank

PHP-Code:
<?php
session_start
();
$sid session_id();

mysql_connect($db_host$db_user$db_password) or die ("Es konnte keine Verbindung zur MySql hergestellt werden.");
mysql_select_db($db) or die ("Es konnte keine Verbindung zur Datenbank hergestellt werden.");

$password $_POST['pass'];
$user $_POST['name'];

$query "SELECT * FROM login WHERE Passwort = '$password' AND Name='$user'";
$result mysql_query($query) or die(mysql_error());

while(
$row mysql_fetch_array($result)){
  
$checkuser $row['Name'];
  
$checkpassword $row['Passwort'];}


  if(
$user == $checkuser && $password ==  $checkpassword) {

     
session_register("user","pass");

    echo 
"Du wurdest erfolgreich eingeloggt !!";
    } else {
    echo 
"Daten sind fehlerhaft !";
  }
?>
 
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 27.09.2004, 00:20  
Gast
 
Beiträge: n/a
Standard

<input type="hidden" name="tries" value="0">

value setzt du nach jeden erfolglosem Versuch neu.
Bei 3 Versuchen schreibst du die IP Adresse samt der Uhrzeit in eine DB.

IMO sind die paar Zeilen schon zuviel aufwand dafür..
 
Alt 27.09.2004, 00:21  
Gast
 
Beiträge: n/a
Standard

ganz einfach:
erweitere deine Tabelle um eine Spalte und zähle dort hoch, wenn zu einem existierenden Benutzer ein falsches Passwort eingegeben wurde
(du kannst dann einfach ein @ vor den Befehl machen, dann bekommst du keine Fehlermeldung wenn der User nicht existiert, sprich du musst dich nciht erst von der Existenz überzeugen.
Wenn sich jemand dann einloggt, stellst du den Zähler auf Null,
außer wenn die zahl darin 3 ist, dann darf er sich nciht anmelden.

zu meinem Vorredner:
Das kann man leicht umgehen, indem man selbst das Formular erstellt und dann zur Seite schickt!
 
Alt 27.09.2004, 00:31  
Gast
 
Beiträge: n/a
Standard

Vielen Dank erstmal..

Wie mache ich das mit dem Hochzählen ??
mit einer for Schleife ??

ich kenne mich mit php (gar) nicht gut aus.


PHP-Code:
if($user == $checkuser && $password ==  $checkpassword) { 

     
session_register("user","pass"); 

    echo 
"Du wurdest erfolgreich eingeloggt !!"
    } else { 
    echo 
"Daten sind fehlerhaft !"

  } 
 
Alt 27.09.2004, 02:52  
Erfahrener Benutzer
 
Registriert seit: 18.07.2004
Beiträge: 2.162
PHP-Kenntnisse:
Fortgeschritten
Basti
Standard

Hi.

Deine Frage entspricht in etwa der hier:

Wie kann ich eine schummelsichere Abstimmung codieren?
http://www.dclp-faq.de/q/q-scripte-abstimmung.html

Dein Login-Skript ist übrigends nur sicher, wenn der PHP-Konfigurations-Parameter 'magic_quotes_gpc' auf on steht. Andernfalls kan sich jeder ganz easy ohne Passwort als jeder beliebigie Benutzer anmelden. Lass dir mal auf deinem Live-Server den Rückgabewert von init_get('magic_quotes_gpc') ausgeben, um sicher zu gehen, dass diese Option auch an ist und stelle ggf. sicher, dass diese auch an bleibt.

Basti
Basti ist offline  
Alt 27.09.2004, 08:51  
Gast
 
Beiträge: n/a
Standard

Netter Logincode würde ich sagen, aber scheint wohl nicht ganz optimal zu sein...
Gibt es irgendwo ne Anleitung oder habt ihr schon Codes für einen wircklich sicheren und guten Login?
Ich hab noch so meine Probleme damit und suche immer nach ner schöneren Lösung als ich schon jetzt habe!

Gruss Lukas
 
Alt 27.09.2004, 15:12  
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von Jojo
ganz einfach:
erweitere deine Tabelle um eine Spalte und zähle dort hoch, wenn zu einem existierenden Benutzer ein falsches Passwort eingegeben wurde
kannst du das bitte detallierter erklären ?
ich bekomme das nicht hin !!
Ich habe folgendes versucht:

PHP-Code:
  if($user == $checkuser && $password ==  $checkpassword) {

     
session_register("user","pass");

    echo 
"Du wurdest erfolgreich eingeloggt !!";

    } else {
$bad  "INSERT INTO login ";
$bad .= "(`Fehlversuche`)";
$bad .= " VALUES ('$_POST[Passwort]')";
mysql_query$bad );
  } 
 
Alt 27.09.2004, 17:35  
Gast
 
Beiträge: n/a
Standard

Okay, lass mal sehen.
Angenommen, du hast eine Tabelle mit drei Spalten:
____________________________
| ID | Name | Passwort |
----------------------------------------
| 1 | Jojo | Karotte |
...

So das erweiterst du nun um eine Spalte (in phpmyadmin):
_______________________________________
| ID | Name | Passwort | fehler |
...

beim Einloggen wirst du wahrscheinlich den Benutzer auslesen und dann das passwort vergleichen. also musst du nur den Befehl ein wenig verändern.
PHP-Code:
$user $_POST['Benutzer'];
$pass $_POST['Passwort'];

$user mysql_query("select * from users where Benutzer='$user' and fehler < 3");
$user_daten mysql_fetch_array($user); 
es gibt zwei Möglichkeiten:
1) Im Passwortfeld steht nix
2) Das Passwort ist falsch.

Weneden wir uns 1) zu:
Wenn nix drinne steht, gibt es entweder den Benutzer nicht, oder er hat sich bereits 3 Mal falsch eingeloggt. gebe einfach entsprechendes aus!

Wenn das Passwort falsch ist, musst du die zahl auslesen, die in der Spalte "fehler" steht und um eins erhöhen:

PHP-Code:
$fehler $user_daten['fehler'];
$fehler_neu $fehler 1;

mysql_query("update users set fehler='$fehler_neu' where Benutzer='$user'"); 
 
Alt 27.09.2004, 17:44  
Erfahrener Benutzer
 
Registriert seit: 18.07.2004
Beiträge: 2.162
PHP-Kenntnisse:
Fortgeschritten
Basti
Standard

Hi.

Bring doch erstmal deinen Anmeldevorgang bzw. den Code dazu in Ordnung.

Code:
$password = $_POST['pass'];
$user = $_POST['name'];
Bevor du auf externe Variablen zugreifst, solltest du deren Existenz überprüfen. Offensichtlich unterdrückst du die Ausgabe von Meldungen des PHP-Prozessors, die zum Programmieren wichtige Infos liefern. Du solltest also in deiner php.ini die Option error_reporting auf E_ALL oder, falls du PHP5 benutzt auf E_STRICT setzen, dann siehst du, was ich meine - du bekommst eine Meldung, falls die beiden Werte nicht geposted wurden.

Dann schreibst du die Zeilen oben folgendermaßen um:
Code:
if (isset($_POST['pass'])) {
 
    $password = $_POST['pass'];
 
} else {
 
    $password = false;
}
// und das gleiche fuer den Benutzernamen
Kompakter:
Code:
$password = false;
if (isset($_POST['pass'])) $password = $_POST['pass'];
Und noch kompakter mit dem ternären Operator:
Code:
$password = (isset($_POST['pass'])) ? $_POST['pass'] : false;
Als nächsten Schritt prüfst du, ob ein Datensatz mit dem übergebenen Benutzernamen und dem Passwort in der Datenbank existiert. Hier gibt es (von meiner Seite aus) dreierlei zu sagen:

1. solltest du keine Passwörter im Klartext in der Datenbank speichern, sondern lediglich Prüfsummen. Die Wahrscheinlichkeit ist groß, dass man mit der E-Mail-Adresse, ggf. auch dem Namen und eben dem Passwort eines deiner Kunden/Benutzer so einige Dummheiten anstellen kann - auch über deine Applikation hinaus, denn die Passwörter, die Surfer verwenden sind oft die gleichen und die muss man ja nicht so einfach dem Praktikanten deines Providers anvertrauen. Außerdem hält sich der Schaden in Grenzen, wenn es einem Angreifer gelingt, deine Benutzerdaten offenzulegen.

Konkret:
Jag ein Passwort, bevor du es in die Datenbank schreibst durch md5(), das ist Standard. Und genauso schreibst du dann zum Auslesen:

Code:
$password = (isset($_POST['pass'])) ? md5($_POST['pass']) : false;
2. Brich deine Datenbankabfrage nach dem ersten gefundenen Ergebnis ab. Dazu setzt du ein LIMIT 1 in deine Query. Wenn die Benutzernamen-Spalte als UNIQUE gekennzeichnet ist (was zu Empfehlen ist), sollte MySQL eigentlich nach dem ersten Ergebnis automatisch abbrechen, denn es kann ja dann keine weitere Übereinstimmung geben. Ob das allerdings tatsächlich so ist, weiß ich nicht.

Also:
Code:
$query = "SELECT * FROM login WHERE Passwort = '$password' AND Name='$user' LIMIT 1";
3. Darf keine der beiden Variablen $password und $user jetzt einen (nicht entschärften) Apostroph (') enthalten, denn sonst könnte jemand als Passwort einfach

x' OR Name='Admin

Und als Benutzername

Admin

übergeben.

Das Ergebnis wäre, nachdem diese Werte eingesetzt wurden, folgende Query:

Code:
$query = "SELECT * FROM login WHERE Passwort = 'x' OR Name='Admin' AND Name='Admin' LIMIT 1";
Diese Abfrage würde dir den Datensatz des Benutzers 'Admin' liefern - ganz ohne Passwort. Natürlich würde der Angreifer an der zweiten Überprüfung, die du eingabaut hast scheitern, aber es ist ja quatsch, einem Angreifer erstmal eine Tür aufzumachen, um ihn dann wieder rauszuschmeißen - solche doppelten Böden fallen allzu gern bei einer Überarbeitung wieder raus und dann ist das Tor offen.

Besser also: Schütze die Query vor einer solchen Manipulation (Injection), dann brauchst du dir um sowas keinen Kopf mehr zu machen.

Wenn du $passwort mit md5() behandelst, hast du hier schonmal nurnoch eine (32stellige) Hexadezimalzahl (Ziffern 0 bis f).

Wie in meiner ersten Antwort bereits angedeutet, gibt es eine PHP-Option, die automatisch alle eingehenden Variablen entschärft. Wenn magic_quotes_gpc (gps steht für get, post, cookie) an ist, wird allen ', " und \ ein Backslash vorangestellt. damit wären die Variablen für deine Datenbankabfrage entschäft, die Query würde lauten:

Code:
$query = "SELECT * FROM login WHERE Passwort = 'x\' OR Name=\'Admin' AND Name='Admin' LIMIT 1";
Und der Angreifer würde abgewiesen (es sei denn, der Benutzer 'Admin' hat als Passwort eben genau dieses 'x\' OR Name=\'Admin' gewählt *g).

Nun ist diese magic-quotes-Option ja eine ziemlich nervige Sache, denn jede eingehende (externe) Variable kommt ja jetzt verwurstet an und nicht, wie sie gemeint war. So sieht man ja auch immer wieder in irgendwelchen Gästebüchern, dass vergessen wurde, diese Backslashes korrekt zu behandeln. Das Ergebnis sind dann Grüße, wie dieser:

Code:
Mach\\\'s gut, Paul
However - du musst sicherstellen, dass magic_quotes_gpc an ist und bleibt, falls du die externen Variablen direkt in eine solche Query setzt! Sauber wäre folgende Lösung:

Code:
// strip slashes if maqic quotes are on
if (true == (bool) ini_get('magic_quotes_gpc')) $user = stripslashes($user);
 
// escape var for mysql query usage
$user = mysql_real_escape_string($user);
Okay, was noch?
mysql_fetch_array() ohne einen zweiten Parameter ist generell in den meisten Fällen zu vermeiden, denn der Datensatz wird ja doppelt abgespeichert (einmal mit den Spaltennamen als Index und einaml mit numerischem Index). Auch wenn es hier nicht ins Gewicht fällt, besser mysql_fetch_assoc() verwenden.

Die Schleife schreibst du in eine Abfrage um:

Code:
if (0 == mysql_num_rows($result)) {
 
    die ('permission denied');
 
} else {
 
    $user_data = mysql_fetch_assoc($result);
}
Die nochmalige Abfrage nach der Übereinstimmung von benutzername und Passwort kannst du dir jetzt eben sparen.

session_register() ist veraltet. Speichere Session-Daten folgendermaßen:
Code:
// anstatt session_register('userdata', $userdata);
$_SESSION['userdata'] = $userdata;
Das Passwort gehört nicht in die Session. Es reicht der Benutzername und sonstige Daten, mit denen Du arbeitest.

Jetzt hab ich mächtig an deiner eigentlichen Fragestellung vorbeigeredet. Aber wenn du die Login-Routine klar hast, kannst du auch besser weitermachen. Dazu schau dir eben mal meinen obigen Link auf der DCLP-FAQ an. Diese ist übrigends grad nicht erreichbar und auf http://php-faq.de/ zu finden.

Basti
Basti ist offline  
Alt 28.09.2004, 12:17  
Erfahrener Benutzer
 
Registriert seit: 18.07.2004
Beiträge: 2.162
PHP-Kenntnisse:
Fortgeschritten
Basti
Standard

Anmerkung zu Jojo's Beitrag:

Es ist halt die Frage, was erzielt werden soll. Einen Benutzer nach drei falschen Passwörtern zu sperren hat 'Babangida' zwar so als Ziel definiert, jedoch bezweifle ich das er das wirklich möchte. Stell dir vor, web.de hätte eine solche Funktion eingebaut. Es wäre ja ein feiner Spaß, mal eben ein paar E-Mail-Zugänge für ungeliebte Mitmenschen zu blockieren, indem ma einfach dreimal deren Mail-Adresse und irgendwas als Passwort eingibt. Tatsächlich soll sich die Sperre doch auf den Benutzer, der gerade vor dem Formular sitzt beziehen und nicht auf den Benutzer, als der sich der Angreifer identifizieren möchte. Wobei es natürlich schon Sinn macht, die Fehlversuche mitsamt IP und Zeitstempel mitzuloggen.

Als Anregung an den Fragesteller:
Definiere erstmal ganz ganau die Funktion, die du implementieren möchtest, bevor du dich ans Programmieren machst. In meinem letzten Beitrag wird ja deutlich, dass da schon beim Login-Vorgang eine heftige Diskrepanz zwischen dem gemeinten Algorithmus und dem nachher entstandenen Code besteht.

Die Idee war etwa:
Wenn Benutzername und Passwort an das Skript gesendet wurden, dann überprüfe, ob in der Benutzertabelle ein Datensatz mit dieser Benutzername-Passwort-Kombination besteht. Wenn dem so ist, dann mach was, wenn dem nicht so ist (oder garkeine Zugangsdaten übermittelt wurden), dann mach was anderes.

Der Code sagt aber etwa folgendes:
Lies aus der Benutzertabelle alle Datensätze mit der (vermeintlich) übergebenen Benutzername-Passwort-Kombination aus. Dann durchlaufe für jeden gefundenen Datensatz eine Schleife. In dieser Schleife überprüfe nochmal, ob der Benutzername aus der Datenbank mit dem übergebenen übereinstimmt und mach das gleiche auch für das Passwort. Wenn beide Tests hinhauen, dann mach was, andernfalls mach was anderes. Dann wiederhole den ganzen Klumbatsch für den nächsten gefundenen Datensatz.

Wenn du jetzt schreibst:
Sperre den Benutzer nach drei Fehlversuchen und du bekommst eben auch solchen Code geliefert. Gemeint wirst du das jedoch wohl kaum haben, da so ja eben jeder Angreifer beliebig Zugänge dicht machen kann. Vielleicht lieg ich auch falsch und das ist genau das, was du wolltest. In jedem Fall lese ich aus deinem Login-Code, dass du dort nicht sauber definiert hast, was dein Skript für dich machen soll und so liegt der Schluß nahe, dass du auch hier etwas anderes meinst, als du schreibst.

Das war das Wort zum ... Dienstag?

Basti
Basti ist offline  
 


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] Login erstellen coraplanet PHP Tipps 2008 33 21.04.2008 16:49
Forum Login per curl leb0rtran PHP Tipps 2008 1 19.03.2008 12:47
Etwas komplexerer Login --> Keine Angst, Suche benutzt dethlef14 PHP Tipps 2006 7 02.10.2006 00:35
.htaccess Login über HTML Login Felder gestalten php1 PHP-Fortgeschrittene 2 09.08.2006 13:53
Session Logout Login Navigation TailerD PHP Tipps 2006 10 24.06.2006 17:12
Frage zu Login Kein Genie PHP Tipps 2006 5 16.06.2006 12:34
PHP / MySQL | Login Script Problem PHP Tipps 2006 15 17.02.2006 12:26
phpBB Loginscript in eigenes Login Script einbinden 2wuck PHP Tipps 2007 4 19.12.2005 23:10
Problem mit Login Script PHP Tipps 2007 4 15.11.2005 17:29
wie speichere ich eine ip beim login? annaloga PHP Tipps 2005-2 23 14.10.2005 17:10
[Erledigt] Login, LogIn, Anmelden, Einloggen -&amp;amp;amp;amp;gt; ??? Off-Topic Diskussionen 20 14.07.2005 11:01
[Erledigt] Windows XP Login Namen verwenden? PHP-Fortgeschrittene 14 17.03.2005 15:37
login mit session id PHP Tipps 2005 10 26.01.2005 12:32
[Erledigt] Zurück-Button beim Login PHP Tipps 2005 7 25.01.2005 17:22
Probleme bei Login PHP Tipps 2004 5 18.07.2004 22:08

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
login.php mit drei fehlversuch, php login nach 3 fehlversuchen abbrechen, bei falschem login - zähler einbauen - php, php login nach erfolglosem versuch zeitsperre, login zähler, init_get proe

Alle Zeitangaben in WEZ +2. Es ist jetzt 04:07 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.