Sie befinden sich hier im Forenarchiv von phpforum.de wenn Sie direkt ins Forum möchten, klicken Sie bitte hier. Zur Startseite kommen Sie hier.

Login-Script sicher? Session login

Hallo zusammen,

habe für ein neues Projekt ein Login-Script erstellt und frage mich ob es
angemessen und einigermaßen sicher ist oder eventuell total überdimensioniert.?!
Eine weitere Frage ist noch, wie das ganze weiter abgesichert werden soll.
Zertrifikat auf dem Server, htaccess oder ähnliches, damit eventueller Web-zugriff sicher ist.

Vielleicht kann mir ja jmd ein Feedback und/oder Anregungen geben!!
Danke!!

Ein paar Dinge, die ich einfließen habe:
- ID der Session wird geprüft.
- Login besteht aus "mandant","user","password"
- Bei Fehlern im Loginprozess wird Session zerstört.
- Sessions werden gelogged, so dass arbeiten an der Datenbank später nachvollzogen werden können.
- Auf jeder Seite des Projektes soll geprüft werden, ob der zugreifende bereichtigt ist (session etc.)
- dabei sollen mandant, user und password so selten wie möglich (1x mal) übertragen, damit ein mithörer keine relevanten Logindaten erhält.

Code:                   In Zwischenablage kopieren (nur IE)
1">

Hier gehts zum Orginal Eintrag "Login-Script sicher? Session login" im Forum

Antworten

Code:                   In Zwischenablage kopieren (nur IE)
2">

Und damit bleiben alle AOL User draussen, weil die über einen Proxy surfen!
Da wechsel die IPs dauernd!


2.

Werde das berücksichtigen, auch wenn in der Regel von Firmennetzwerken und nicht von AOL zugegriffen werden soll.
Gibts denn eine alternative zur IP? Irgendetwas was ich mit dem Computer des zugreifenden Verbinden kann?

Danke schonmal.


3.

Zitat:
Irgendetwas was ich mit dem Computer des zugreifenden Verbinden kann?
Nein! Nur die SessionID!


4.

Feedback:
1) Der hier wird nie false:

Code:                   In Zwischenablage kopieren (nur IE)
3">

PHP läd anhand der Session-ID die Daten. In diesen Daten steht bei einem Aufbau wie du ihn machst dann immer auch die selbe Session-ID. Den Sport, die Session-ID in der Session abzulegen, kannst Du Dir also schenken.

2) Dein Skript funktioniert nicht, wenn session.use_trans_sid und session.use_cookies aus sind.

3) Dein Skript produzier Notices, sollte das error_reporting auf E_ALL stehen. Im Hinblick zukünftiger Pflege und Debugging würd ich das abstellen.

4) Dein Skript ist je nach magic_quote-Einstellung anfällig für SQL-Injections.

5) Location-Header verlangen einen absoluten URI.

Gruß Jens


5.

Besten Dank Jens für das umfassende Feedback:

zu 1) Das mit der Session-ID habe ich dann nicht so ganz verstanden. Ich dachte damit geht man einigermaßen sicher, dass da nicht jmd versucht meine Session zu nutzen um sich zugriff auf das system zu verschaffen, da jedes browserfenster eine andere id erzeugen würde!?!
zu 2) Ist session.use_tran_sid nicht eine server-einstellung? oder kann der client da was verfuschen?

zu 3) habe den code, der die notices erzeugt hat, verbessert und die zeile für error_reporting(0) eingefügt.

zu 4) habe auch das verbessert. das habe ich doch richtig verstanden, dass ich das nur für den login nutzen muss. bei späteren datenaustausch zwischen code und db, muss ich das nicht jedesmal ins mysql_query einbauen!? oder ist das empfehlenswert?

zu 5) Wird bei zeiten geändert, beim testen funktioniert es noch mit dem relativen pfad

habe den code noch ein wenig in der logik optimiert. Die _POST-Variablen für Mandant, Benutzer, Password werden nicht mehr in die Session eingetragen, da sie ja nicht jedes mal übertragen werden soll, sondern nur das eine mal, beim verifiziern.

Das ganze sieht jetzt so aus.

Code:                   In Zwischenablage kopieren (nur IE)
4">

Für weitere Kritik bin ich dankbar!!


6.

$_SESSION["s_id"] = session_id(); <<-- das halte ich für überflüssig!!!(alle zugehörigen vergleiche auch)
Die Sessionvariablen werden doch sowieso nur in die Session mit DER ID geschrieben!
Das kann doch NIE anders sein!!!

session _destroy(); naja....
$_SESSION= array(); Reicht da auch
Oder wenn, dann auch richtig alles zerstören,
dort ist ein Beispiel wie man es richtig abhandelt!
Siehe: http://de2.php.net/manual/de/function.session-destroy.php



Warum verwendest du nicht: error_reporting(E_ALL);
Oder willst du gar nicht alle Fehler sehen :)

Zitat:
$sql_login = "SELECT id, loginname FROM login WHERE mandant_id = '$_POST[mandant]' && loginname = '$_POST[benutzer]' && loginpasswort = '$_POST[password]'";
Weiterhin ein Sicherheitsloch...
[doc=phpfaq]sql-injection[/doc]

require("include/db_connection.inc.php"); <-- kommt in deinem script doppelt vor
------------------------------------------------
Jetzt zu den Schönheitsfehlern...

1. Das ganze Loginformular mit echo rauszukloppen, ist wenig performant und auch unschön anzusehen...
2. Header("Location:index.php"); <<-- machs doch sofort richtig
Hier ein universal Beispiel: http://www.php3.de/header

3. require("include/db_connection.inc.php"); sowas gehört(meines Erachtens) an den Anfang des Scriptes
Du suchst dich sonst nach 2 Jahren dull, nach solchen Dingern..


------------
Ich hoffe das war jetzt nicht zu viel auf einmal....:)


7.

Zitat:
sirchris postete
zu 1) Das mit der Session-ID habe ich dann nicht so ganz verstanden. Ich dachte damit geht man einigermaßen sicher, dass da nicht jmd versucht meine Session zu nutzen um sich zugriff auf das system zu verschaffen, da jedes browserfenster eine andere id erzeugen würde!?!

In der Annahme irrst Du. Es kann zwar Fälle geben, wo mehrere Browserfenster auch unterschiedliche SIDs haben, daß ist aber erstens nicht der Normalfall, und zweitens hat das mit dem monierten Problem nichts zu tun.

Normalerweise wird PHP bei Deinem Skript folgendes machen:
- Session-ID $S generieren
- $S in $_SESSION['var'] packen
- der Inhalt von $_SESSION wandert nun in eine Datei mit dem Namen "prefix_$S".

Beim Folgeaufruf passiert dann das hier:
- PHP ermittelt aus GET, POST oder COOKIE $S
- Der Inhalt der Datei "prefix_$S" wird ausgelesen und in $_SESSION geschrieben
- Es wird geprüft ob $_SESSION['var']==$S ist.

Und nun erzähl mir bitte mal, wie das bei Deinem Skript jemals nicht der Fall sein könnte...
Zitat:
sirchris postete
zu 2) Ist session.use_tran_sid nicht eine server-einstellung? oder kann der client da was verfuschen?

Richtig. Das ist eine Server-Einstellung. Insbesondere ist es eine, auf die Du nicht bei allen Hostern freien Zugriff hast (in PHP-Version 4.2.3 bis 4.3.4 war session.use_trans_sid PHP_INI_SYSTEM|PHP_INI_PER_DIR und konnte nur per Trick 17 deaktiviert, nicht aber wieder aktiviert werden). Willst Du also, daß Dein Skript überall läuft, so musst Du berücksichtigen, daß die automatische SID-Übergabe deaktiviert sein könnte.
Zitat:
sirchris postete
zu 4) habe auch das verbessert. das habe ich doch richtig verstanden, dass ich das nur für den login nutzen muss. bei späteren datenaustausch zwischen code und db, muss ich das nicht jedesmal ins mysql_query einbauen!? oder ist das empfehlenswert?

Den musst Du nochmal übersetzen. Da hab ich jetzt nicht verstanden, was Du möchtest.

Den Rest hat Combie ja schon abgefrühstückt...

Gruß Jens


8.

Ich kann garnicht so oft einen neuen release posten, wie ihr mir änderungen entgegenschmeist ;)
Damit wir nicht durcheinanderkommen, werde ich jetzt erstmal die Punkte von combie abfrühstücken und dann von Jens
1.
Zitat:
$_SESSION["s_id"] = session_id();
Sehe ein, dass es die Prüfungen dazu keinen Sinn machen, benutze das hier allerdings um zu sehen, ob jmd frisch auf der Seite ist oder vom Formular oder durch andere Links wieder auf diese Seite verwiesen wird.
Sonst haben wir ja immer die Login-Maske da stehen.
Die Prüfungen ob die aktuelles $_SESSION("s_id") mit der session_id() zusammenpasst spare ich mir jetzt aber

2.
Zitat:
session _destroy(); naja....
$_SESSION= array(); Reicht da auch
so rein interesse halber, gibt es perfomante gründe die gegen eine sesssion_destroy() sprechen? zB tatsächlicher aufwand beim Server?
Da mein Browserfenster beim nächsten mal eh die gleiche SID bekommt, würde mir sicherlich auch ein array() reichen.

3.
Zitat:
error_reporting(E_ALL);
glaub mir, am liebsten würde ich im blindflug programmieren ;) aber du hast recht. keine Ahnung, warum ich das nicht direkt umgestellt habe.

4.
Zitat:
$sql_login = "SELECT id, loginname FROM login WHERE mandant_id = '$_POST[mandant]' && loginname = '$_POST[benutzer]' && loginpasswort = '$_POST[password]'";
habe diese und alle noch übrigen sql_queries jetzt abgesichert. Ich hoffe mein "quote_smart"-funktion berücksichtig alle eventualitäten!?


Jetzt zu den Schönheitsfehlern...

1. Das ganze Loginformular mit echo rauszukloppen, ist wenig performant und auch unschön anzusehen...
-> habe ich verbessert. Allerdings ging es mir hier momentan um die technik dahinter, daher habe ich so ein simples gebilde für den login gebastelt. Der Style kommt dann später dazu ;-)
2. Header("Location:index.php"); <<-- machs doch sofort richtig
--> Richtig!

3. require("include/db_connection.inc.php"); sowas gehört (meines Erachtens) an den Anfang des Scriptes
Du suchst dich sonst nach 2 Jahren dull, nach solchen Dingern..
und auch meines Erachtens, daher korregiert

require("include/db_connection.inc.php");
das und alles was eh nacher in ein include verschwindet, habe ich mal nach oben gepackt.

Vielen Dank an dieser Stelle
-------------
Jens

1.
Zitat:
Beim Folgeaufruf passiert dann das hier:
- PHP ermittelt aus GET, POST oder COOKIE $S
- Der Inhalt der Datei "prefix_$S" wird ausgelesen und in $_SESSION geschrieben
- Es wird geprüft ob $_SESSION['var']==$S ist.

Und nun erzähl mir bitte mal, wie das bei Deinem Skript jemals nicht der Fall sein könnte...

FALLS mir dazu noch eine Situation findet, melde ich mich, ansonsten gebe ich mich geschlagen ;)

2.
Zitat:
Willst Du also, daß Dein Skript überall läuft, so musst Du berücksichtigen, daß die automatische SID-Übergabe deaktiviert sein könnte.
wenn session.use_tran_sid deaktiviert ist, würde ich daraus verstehen, dass der server überhaupt keine session-daten speichert, ergo bringt es mir auch nicht, dass ich die sid über ein post/get übergebe.
ODER bezieht sich dies wirklich nur auf die übergabe der ID?
dann würde ich in meine formulare ja sowas einfügen wie:
Code:                   In Zwischenablage kopieren (nur IE)
5">

3.
Zitat:
sirchris postete:
zu 4) habe auch das verbessert. das habe ich doch richtig verstanden, dass ich das nur für den login nutzen muss. bei späteren datenaustausch zwischen code und db, muss ich das nicht jedesmal ins mysql_query einbauen!? oder ist das empfehlenswert?

also wir hatten uns ja darauf geeignet, dass ich im login-bereich, die variablen vor SQL-Injections schützen muss.
Die Frage ist jetzt, was ist mit SQL-Anweisungen, die später im Programm auftauchen. Muss ich bei jeder Abfrage, wo vom benutzer eingegebene Daten einfließen, die sicherheitsmaßnahmen gegen Injections einbauen!?
oder besser gefragt, würdest du das empfehlen!
Was ist mit SQLs die vom Anwender unabhängig sind, muss ich das da trotzdem machen?

Auch dir nochmal einen Herzlichen Danke für die unterstützung.

also "Belohnung" gibt es für euch beide jetzt auch noch mal einen neuen Release meines einmaligen Login-Scripts :P

Code:                   In Zwischenablage kopieren (nur IE)
6">




9.

Das entwickelt sich ja so langsam zu einem richtigen "Sessionbasiertem Login Kurs" :D

Und Ja, dein Script sieht jetzt viel aufgeräumter aus! :)

Zitat:
Die Frage ist jetzt, was ist mit SQL-Anweisungen, die später im Programm auftauchen. Muss ich bei jeder Abfrage, wo vom benutzer eingegebene Daten einfließen, die sicherheitsmaßnahmen gegen Injections einbauen!?
oder besser gefragt, würdest du das empfehlen!
JA!
Daten, welche vom Browser kommen, darf GRUNDSÄTZLICH nicht vertraut werden!!
Weil:
1. es könnte ein absichtlicher Angriff dahinterstecken
2. die versehentliche Eingabe von Sonderzeichen des Benutzers kann Fehlfunktionen verursachen
Es muß also nicht mal böse Absicht dahinterstecken

Zitat:
Was ist mit SQLs die vom Anwender unabhängig sind, muss ich das da trotzdem machen?
Tja.... da würde ich mal sagen: Nicht unbedingt!
Wenn diese Daten Anführungszeichen enthalten, dann ist mysql_real_escape_string sowieso Pflicht.
Magic_Quotes können da allerdings nicht auftreten...

Zitat:
so rein interesse halber, gibt es perfomante gründe die gegen eine sesssion_destroy() sprechen? zB tatsächlicher aufwand beim Server?
Da mein Browserfenster beim nächsten mal eh die gleiche SID bekommt, würde mir sicherlich auch ein array() reichen.
Hat mit Performance nix zu tun! Sicherheit geht vor Performance!
http://de2.php.net/manual/de/function.session-destroy.php
Wenn du dem dort verewigten Codebeispiel folgst, ändert sich auch die SessionID!


Zitat:
$_SESSION["s_id"] = session_id();
Weiterhin überflüssig!
Du machst ja irgendwan:
$_SESSION["login_id"] = $login_id;
$_SESSION["login_name"] = $loginname;
Das reicht doch als Loginkennung dicke aus!!!


PS:
Die header-location weiterleitungen, hättest du ruhig drin lassen können ;)
(nur überarbeiten)


10.

Damit das hier echt nicht zum Tutorium auswächst ;) habe ich jetzt hoffentlich alles abgedeckt.
Zitat:
$_SESSION["s_id"] = session_id();
konnte ich jetzt erfolgreich entfernen ;)

Den Injection-Schutz werde ich dann zukünftig bei allen SQL-Abfragen nutzen.
Das einzige was jetzt noch offen ist, ist die Möglichkeit das die sid nicht übergeben wird.
Zitat:
session.use_tran_sid
Wie ist das jetzt mit den Sessions? Geht es wirklich nur um die übergabe der ID?

Auch auf die Gefahr hin, den absoluten Overkill erzeugt zu haben, habe ich das ganze mal ein wenig "modularisiert" (ich weiss, dass es keine richtigen module sind, aber welches wort wäre da passender??!!) damit für die index.php nur noch das Gerüst stehen bleibt, dass ich bei jeder Seite des Projekts einfügen kann.

ich werde hier nochmal alle relevanten teile aufführen.

Code:                   In Zwischenablage kopieren (nur IE)
7">

Code:                   In Zwischenablage kopieren (nur IE)
8">

Code:                   In Zwischenablage kopieren (nur IE)
9">

Code:                   In Zwischenablage kopieren (nur IE)
10">

Code:                   In Zwischenablage kopieren (nur IE)
11">

Code:                   In Zwischenablage kopieren (nur IE)
12">




11.

Ich habe jetzt leider nicht alle Posts durchgelesen, deswegen wurde das womöglich bereits erwähnt:

Du sagst, du willst benutzername und Passwort nur einmal überprüfen, da diese sonst abgefangen werden können. Diese Daten liegen aber in der Session und die Session liegt auf dem Server. Das einzige was sowieso immer übertragen wird ist die Session-ID. Wieso also nicht auf jeder Seite nochmals prüfen? Falls ich das falsch sehe: "ups" ;-)

Gruss
Mendragol


12.

Zitat:
Wieso also nicht auf jeder Seite nochmals prüfen?
Weil es schon geprüft wurde.....
Jede weitere Prüfung kann doch nur TRUE ergeben.

Oder, was soll das bringen?
:( Wenn der Server gehackt wurde, hilft das alles sowieso nix :(


13.

Ja es würde nur dann etwas bewirken, wenn in der Zeit in der man eingeloggt ist, das Passwort geändert wird. Dabei kommt es auch darauf an, wielange die Session am Leben bleibt. Aber wenn z.B. ein globaler Account für mehrere Kunden besteht und man für diesen täglich per cronjob das Passwort ändern muss, dann könnte dies ganz nützlich sein ;-). Aber ok, ich gebe zu, es wäre etwas spezifisch.


14.

Zitat:
Mendragol postete
Aber wenn z.B. ein globaler Account für mehrere Kunden besteht ...
... dann ist bei der Konzeption der Softwarelösung was schief gelaufen.

Gruß Jens


15.

Zitat:
Jens Clasen postete
... dann ist bei der Konzeption der Softwarelösung was schief gelaufen.

Das wäre ja bei vielen Projekten, wie man so mitbekommt, keine Ausnahme. Es geht auch eher um den Fall der Fälle.


Hier gehts zum Orginal Eintrag "Login-Script sicher? Session login" im Forum
 
phpforum.de | Impressum | Handy Bundles