PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : php login "sicher" machen


Gast
2008-06-30, 23:12:34
Hallo zusammen

Ich mehr oder weniger Neuling auf dem Gebiet "PHP". Habe mir ein Tutorial durchgelesen und möchte nun ein kleines Programm schreiben, mit dem sich eine Seite verwalten lässst (News bearbeiten, Tabellen anlegen,..). Anfangen möchte ich erstmal damit, eine Admin-Umgebung zu schreiben. Jezt kommt auch shcon meine Frage:
Wie sichere ich dieses Admin-Panel ab? Also erstmal kommt ein Login wo benutzerdaten abgefragt werden. Aber was speichere ich damit 1.) der User eingeloggt bleibt (zumindest für eine Session) und 2.) kein anderer Benutzer zB einfach die Session des eingeloggten "klaut" o.ä.

Habe zB daran gedacht die IP des User der sich einloggt in einer Session/Cookie zu speichern und dann auf jeder Seite die gespeicherte mit der aktuellen abgleichen.Hätte nur das Problem das jeder im selben netzwerk die selbe IP hat. Wie würdet ihr an sowas ran gehn?

Freu mich über Antworten

Tommes
2008-07-01, 00:08:57
htaccess wäre eine Möglichkeit, mit der man sich viel Rumgewurschtel ersparen kann. Wenn das Programmieren eines PHP Logins jedoch aus Interesse und Lernzwecken erfolgen soll, macht es jedoch Sinn ;) Schau mal hier z.B.

http://pbeblog.wordpress.com/2008/03/02/creating-a-login-script-using-php-and-mysql/

Coda
2008-07-01, 00:19:45
Passwort nur als Hash auf dem Server ablegen und nur das Session-Cookie beim Benutzer ablegen. Alles andere auf dem Server halten.

Dann sollte nichts schief gehen.

mbee
2008-07-01, 01:53:13
Hätte nur das Problem das jeder im selben netzwerk die selbe IP hat.

Das ist schon mal grundsätzlich Blödsinn (Stichwort NAT) und Sessions/Cookies funktionieren deshalb auch in obigem Fall ;)
Sinnigerweise sollte so etwas aber bei einer Real-Life-Applikation dann auch über https laufen, sonst ist's mit der Sicherheit auch nicht weit her.

ezzemm
2008-07-01, 07:02:31
Schönes Tutorial für Login-Script:
http://tut.php-quake.net/login.html

BoneDaddy
2008-07-01, 09:52:09
Wenn du eine htaccess einsetzt, achte darauf, dass die Passwortdatei nicht in einem Verzeichnis liegt, auf das von außen zugegriffen werden kann.

(del)
2008-07-01, 10:36:40
ich habs so gelöst: in ner datenbank wird die vergebene session-id abgespeichert.
bei jedem websiteaufruf wird dann z.b. für den admin-bereich sowas gemacht:

if(user_sessid_matches($_SESSION['username'],$_SESSION['id']) AND userlevel($_SESSION['username'])==1){
//admin-bereich anzeigen
}
//ansonsten gar nix machen

Tommes
2008-07-01, 14:31:05
md5 ist mist, lieber sha1 mit salt, habe den Artikel nicht umsonst verlinkt ;)

rotalever
2008-07-01, 14:39:20
Für die Generierung der SessionID oder des Salts würde ich irgendwas mit uniqueid() + dem Passwort + Zeit zusammenhashen.

Session-Hijacking kann man nicht 100% verhindern, da das zusätzliche Indentifizieren mit IP oder Browser fehlerhaft sein kann.

Wichtig ist, das man NICHT auf das Verfallsdatum des Cookies vertraut, da Server und User unterschiedliche Uhren haben können. Den Cookie entweder als Session-Cookie speichern oder erst nach X(=große Zahl) Tagen löschen lassen. Auf dem Server immer speichern, wann die letzte Aktivität des Users war. Auch wenn Cookie Daten mit der DB übereinstimmen gucken, ob die letzte Aktivität des Users zuweit zurück liegt. Dann automatisch ausloggen oder nach Passwort fragen.

Bei jedem Einloggen muss ein anderer Schlüssel im Cookie gespeichert sein, damit es weniger Angriffsmöglichkeiten gibt.

Ich mache das so:

Cookie speichert USER_ID und USER_KEY.

Prüfen ob eingeloggt:
Datenbank-Zeile für USER_ID abrufen
Prüfen ob der in dieser Zeile gespeicherte KEY dem USER_KEY aus dem Cookie entspricht
Nein:
cookie löschen
return False
Ja:
Prüfen ob letzte Aktivität zuweit zurück liegt (in der Datenbank wird auch gespeichert,
ob der User eingeloggt bleiben möchte, oder ob der Login nach 20 Minuten verfällt,
das darf nicht im Cookie gespeichert werden!)
Letzte Aktivität liegt zuweit zurück:
ausloggen
return False
Nein:
letzte Aktivität in der Datenbank mit aktueller Zeit aktualisieren
return True


einloggen:
Prüfen ob Passwort richtig ist
Generieren von USER_KEY mittels uniqueid und passworthash und zeit etc. das ganze einmal hashen
USER_KEY und USER_ID im Cookie speichern
USER_KEY in der Datenbank für den User speichern
Letzte Aktivität in der Datenbank anpassen


ausloggen:
USER_KEY aus Datenbank löschen
Cookie löschen

Das ganze hat natürlich den Nachteil, dass ein User nicht gleichzeitig auf mehreren PCs angemeldet sein kann, aber für das meiste reicht es.

Gast
2008-07-01, 14:41:58
habe mal versucht jetzt ein grobes gerüst zu basteln:

http://nopaste.php-quake.net/36778
was haltet ihr davon? klar, fehlt noch einiges, zB muss das Passwort verschlüsselt werden usw..Später soll es so sein das ich die einzelnen Seiten dann include, dort wo jetzt "Willkommen im Adminbereich" steht. Aber wie schütze ich die includeten Seiten? In dem ich dort ne schnelle Abfrage mach ob $_SESSION['ID'] und $_SESSION['IP'] gesetzt sind und falls nicht auf die index.php weiterleite?

grüße

Coda
2008-07-01, 14:48:09
Für die Generierung der SessionID oder des Salts würde ich irgendwas mit uniqueid() + dem Passwort + Zeit zusammenhashen.
Man verwendet einfach die eingebauten PHP-Sessions.

rotalever
2008-07-01, 14:51:31
Man verwendet einfach die eingebauten PHP-Sessions.
Sind die denn sicher?

Coda
2008-07-01, 15:00:26
Natürlich sind die sicher.

Gast
2008-07-01, 15:03:45
Hat jemand meinen POst oben gesehn?:-)

rotalever
2008-07-01, 15:07:10
Natürlich sind die sicher.
Okay, ich hätte gedacht, das die möglicherweise einfach irgendwelche Zähler sind, die hochzählen oder das sie sehr leicht erratbar sind. Deshalb hab ich mir einfach selber was gebastelt ;)

Tommes
2008-07-01, 17:58:49
Ich habe mir neulich mal das Login/Session System des Simple Machines Forums angeschaut, die machen das wirklich gut. Für diejenigen, die es interessiert :) Arbeiten auch mit sha1 und salt.

Gast
2008-07-01, 18:12:21
Hallo

ich nochmal. was haltet ihr davon: http://nopaste.php-quake.net/36804
Kommentare erwünscht. Leider sind die Einrückungen irgendwie verloren gegangen nach dem copy&paste.

rotalever
2008-07-01, 19:56:58
Wo für ist Zeile 7-10 gut? Ich würde eher testen, beides überhaupt vorhanden ist. Also isset($_POST["benutzer"])...

Zu mysql nicht als root sondern als user connecten (eingeschränkte Rechte) und mit passwort am besten.

Niemals eingaben aus $_GET oder $_POST direkt in MySQL queries einbauen! Benutze am besten prepared Statements, das ist am sichersten, oder escape das mit der entsprechenden Funktion von PHP.
Am besten für prepared Statements gleich das mysqli-Interface benutzen, da gibts auch paar nette Tutorials (auf zend.com glaub ich), musst du mal bei google suchen.

Ich würde den Login-Test in eine Funktion reinpacken und als Rückgabe True/False. Das kannst du dann in einer globalen Variable speichern und während des Scriptablaufs bei Bedarf verwenden.

Wenn du dem Label ein for-Attribut gibst, so muss auch das Input-Feld eine ID haben.

Das Passwort muss unbedingt gesalzen werden und am Besten kein md5 verwenden. Also sowas:
$password_hash = sha1($password.$salt)
wobei $salt irgendein netter individuell generierter langer String ist, der dann zusammen mit dem hash in der DB gespeichert wird.


Ansonsten würde ich bei fehlgeschlagenem Login nicht einen Zurückbutton anbieten, sondern einfach das Login-Formular anzeigen.

Ob das mit den Session-Befehlen so wie es ist sicher ist, weiß ich nicht, ich mache das immer manuell mit Cookies. Da weiß ich dann was passiert ;)

Gast
2008-07-01, 20:27:09
hallo

Danke für deine Tipps, ich werd ma demnächst nochma nachbessern. Zeile 7-10 sind dazu da, um das Problem abzufangen, wenn ein Benutzer einfach ohne was einzugeben das Formular abschickt. mit isset() kann ich das ja nicht prüfen da die auf jedenfall gesetzt sind wenn das Formular abgeschickt wird, nur eben sind sie dann leer.

Das MIt dem Salt werde ich mir mal anschauen, was das genau ist.

Gibt es irgendwas was man bezüglich Sicherheit meckern kann? also das man zB eine if Abfrage umgehen kann in dem man irgend eine Variable in der Url übergibt oder was es da sonst noch so gibt..

danke

rotalever
2008-07-01, 20:52:59
hallo

Danke für deine Tipps, ich werd ma demnächst nochma nachbessern. Zeile 7-10 sind dazu da, um das Problem abzufangen, wenn ein Benutzer einfach ohne was einzugeben das Formular abschickt. mit isset() kann ich das ja nicht prüfen da die auf jedenfall gesetzt sind wenn das Formular abgeschickt wird, nur eben sind sie dann leer.


Gibt es irgendwas was man bezüglich Sicherheit meckern kann? also das man zB eine if Abfrage umgehen kann in dem man irgend eine Variable in der Url übergibt oder was es da sonst noch so gibt..

isset() solltest du aber zusätzlich prüfen.
Unbedingt das von mir angesprochene SQL-Statement ändern! Sonst hast du bald SQL-Injections.

Gast
2008-07-01, 21:38:34
ich machs jetzt erstmal mit mysql_real_escape_string();
Muss ich dem Query dann einfach mysql_real_escape_string($_POST[..]) übergeben?

rotalever
2008-07-01, 22:00:58
ich machs jetzt erstmal mit mysql_real_escape_string();
Muss ich dem Query dann einfach mysql_real_escape_string($_POST[..]) übergeben?
Ja das ist gut.