Sicherste Methode: für Benutzer-Login gesucht

Hallo Forum,

ich bin dabei, eine neue Seite zu planen und mache mir auch Gedanken um die Sicherheit. Bisher habe ich immer alle Benutzerdaten in der Session gespeichert. Das ist bequem und verlässlich. Ist es aber wirklich sicher? Gibt es ggf. sicherere Methoden?

Es handelt sich konkret um einige Seiten in einem geschützten Bereich, den man nur als registrierter User nach vorherigem Login betreten dürfen soll und in dem persönliche Einstellungen vorgenommen werden können sollen, wohingegen alle übrigen Seiten für alle User frei sein sollen. Nachteil bei der Session ist, dass (sofern der Browser nicht zwischendurch geschlossen wird) ein history.back() bereits einem nicht autorisierten User Zugriff auf den geschützten Bereich gewähren könnte. Gibt es die Möglichkeit, die Session beim Verlassen des Framesets oder auf andere Art zu killen, z.B. sobald die Domain verlassen wird?

Habt ihr vielleicht noch andere Ideen? Wie handhabt ihr das denn so bzw. was wird so im Allgemeinen angewandt und als ausreichend sicher betrachtet? Anleitungen gibt es ja wie Sand am Meer, aber mich interessiert natürlich diejenige Alternative, bei der Sicherheit und Aufwand im günstigen Verhältnis zueinander stehen. Das zu beurteilen bin ich nicht in der Lage, da ich als relativer Neuling nicht gerade der godfather of PHP bin (dafür aber fleißig und gelehrig).

Ich würde mich über zahlreiche Meinungen sehr freuen. Falls mir etwas völlig fremd sein sollte, erlaube ich mir, ggf. dann nochmal genauer nachzufragen.

Gruß und Dank
Querkopf

Hallo,

ich an deiner stelle würde für nicht angemeldete User den Unsinn mit den Sessions und Cookies sein lassen. Die können das sowiso bei sich deaktivieren und können dann die Seite vielleicht nicht sehen und so vergällst du dir potenzielle „Kunden“.

Für die Geschlossene Usergruppe die sich anmelden kann würde ich vorschlagen das du ein sicheres Loginscript schreibst mit Passwortverschlüsselung „md5“. Ausserdem prüfst du anhank einer kleinen Klasse „PHP“ bei jedem Seitenaufbau ob der User angemeldet ist. Dies kann nicht umgangen werden da es Serverseitig läuft und bietet somit die höchste sicherheit. Darüberhinaus kannst du das Userverhalten mitloggen um Profile zu erstellen die wiederum auf die Content Darstellung einwirken können.

Pass nur auf das du auf dem Datenbank Servers deines Providers nicht zu viel traffik erzeugst. Das mögen die bei nicht betrieblicher Nutzung gar nicht gerne.

MFG hdj-lange

PS: Guten Rutsch und ein frohes, gesundes und erfolgreiches Neues Jahr.

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi!

ich bin dabei, eine neue Seite zu planen und mache mir auch
Gedanken um die Sicherheit. Bisher habe ich immer alle
Benutzerdaten in der Session gespeichert. Das ist bequem und
verlässlich. Ist es aber wirklich sicher? Gibt es ggf.
sicherere Methoden?

Das ist eigentlich ziemlich sicher, du solltest auf die Teile dann auch mit $_SESSION[„variable“] zugreifen statt mit $variable falls du das tust. Die default-php-Einstellung wurde aber vor längerem geändert so dass zweiteres nicht mehr geht normalerweise (weil man damit zu viel Sachen machen kann z.b. variablen per URL Parameter überschreiben usw.)

Es handelt sich konkret um einige Seiten in einem geschützten
Bereich, den man nur als registrierter User nach vorherigem
Login betreten dürfen soll und in dem persönliche
Einstellungen vorgenommen werden können sollen, wohingegen
alle übrigen Seiten für alle User frei sein sollen. Nachteil
bei der Session ist, dass (sofern der Browser nicht
zwischendurch geschlossen wird) ein history.back() bereits
einem nicht autorisierten User Zugriff auf den geschützten
Bereich gewähren könnte. Gibt es die Möglichkeit, die Session
beim Verlassen des Framesets oder auf andere Art zu killen,
z.B. sobald die Domain verlassen wird?

Das wirst du nicht verhindern können mit für dich vertretbarem Aufwand und dem User zuzumutbarer Belästigung. Eine Session timed ja irgendwann aus, bei php ist das glaub leider bis heute nicht so genau zeitmäßig festzuhalten. Was man auch nohc machen kann, per javascript onLeave oder wie das heisst beim rausgehen aus einer Seite schnell ein window aufpoppen was ne Seite aufruft die die session zerstört und dann sich selbst wieder schließt. Ist aber auch von jedem User abschaltbar und es gibt zig Möglichkeiten warum das nicht aufgerufen wird (Popup-Blocker ist nur eine). Also auch kein wirklicher Nutzen für den Aufwand

Habt ihr vielleicht noch andere Ideen? Wie handhabt ihr das
denn so bzw. was wird so im Allgemeinen angewandt und als
ausreichend sicher betrachtet? Anleitungen gibt es ja wie Sand
am Meer, aber mich interessiert natürlich diejenige
Alternative, bei der Sicherheit und Aufwand im günstigen
Verhältnis zueinander stehen. Das zu beurteilen bin ich nicht
in der Lage, da ich als relativer Neuling nicht gerade der
godfather of PHP bin (dafür aber fleißig und gelehrig).

Die Idee so einen Login über die Session zu realisieren ist prinzipiell gut und würde ich auch jederzeit so machen. Natürlich kenne ich deinen Code nicht wie das genau abläuft, es sind auch noch andere Sicherheitslücken möglich (Bei PHP besonders beliebt: SQL Injection)

Grüße
Bruno

Hallo Bruno,

Vielen Dank! Was meinst du mit „SQL Injection“? Wenn man den Mechanismus kennt, kann man doch sicher was dagegen machen, oder?

Gruß
Querkopf

Vielen Dank! Was meinst du mit „SQL Injection“? Wenn man den
Mechanismus kennt, kann man doch sicher was dagegen machen,
oder?

Hallo,

ja kann man. Lies dir mal folgendes durch http://www.securiteam.com/securityreviews/5DP0N1P76E…

Das Prinzip ist eigentlich recht einfach. Oftmals werden Eingaben in Eingabefelder ungeprüft in SQL Strings reingehauen, was dann je nach Eingabe einen unerwünschten Effekt haben kann :wink: Ich habe das erst neulich testweise mal bei einem vor längerer Zeit von mir selbst programmieren PHP skript ausprobiert.

Die Abfrage sah im Code so aus:

$sql = „SELECT * FROM users WHERE user = '“ . $_POST[‚login_user‘] . „’ and pass = PASSWORD(’“ . $_POST[‚login_pass‘] . „’)“);

Also wenn einer eingibt „admin“ und „123“ dann kommt folgendes raus:
SELECT * FROM users WHERE user = ‚admin‘ and pass = PASSWORD(‚123‘)

Der Trick besteht nun darin diese Nichtprüfung der Eingabe auszunutzen, mit dem Usernamen „admin’ or ‚a‘ == ‚a‘“ und einem beliebigen Passwort habe ich dann Adminzugriff erhalten, weil die Query zu folgendem wurde

SELECT * FROM users WHERE user = ‚admin‘ or ‚a‘ == ‚a‘ and pass = PASSWORD(‚123‘)

Dann ist der zweite Teil der Abfrage mit dem Passwort zwar falsch, aber durch das „or“ was ich eingesetzt habe liefert mir die Abfrage durch den ersten Teil dennoch den Admindatensatz.

Bei closed-source Projekten ist die Gefahr meiner Ansicht nach relativ gering, da normalerweise keiner weiss wie deine Query aussieht und es nur mit ein paar Standardversuchen probieren kann, anstatt direkt abzulesen wie es gehen könnte.

Die wichtigste Gegenmaßnahme ist sich vor Augen zu halten, dass jegliche Eingabe potentiell gefährlich ist. Das heisst übergebe nie Variablen ungeprüft in eine SQL Abfrage, verbiete kritische Zeichen wie insbesondere das ’ in solchen Feldern.

Auf manchen Servern hat mein eigener „Hackversuch“ übrigens nicht funktioniert, scheint wohl auch noch ne PHP-Konfiguration zu geben (ich vermute "magic quotes) die da abhilfe schaffen kann

Grüße
Bruno

das mit den Sessions ist ja soweit schon beantwortet…

Falls Du sehr viele Zugriffe von unterschiedlichen Leuten hast wirst Du wegen der Serverload irgendwann aber umsteigen müssen auf ein cookie-Konzept.
Ich mache das so, dass ich einen Zufallsstring generieren lasse und den auf dem Client als cookieinhalt abspeichere und auch in der Datenbank.
Dann gleiche ich noch die aufrufende IP Adresse ab und wenn die beiden bzw vier Werte übereinstimmen, dann ist der User verifiziert…

Jetzt zum zweiten Teil. Du kannst auf eine ähnliche Art und weise denke ich schon verhindern, dass jemand per zurück-Link auf Deine Seite kommt…
Allerdings würde die Methode, die ich Dir vorschlage jegliche verwendung von zurück-Links aushebeln. Du dürftest also nicht mit javascript:history.back() arbeiten…

Wie Du das regeln kannst ist denke ich relativ einfach. Beim Seitenaufruf definierst Du einen Zufallswert für Deine Session-Variable. Diese Variable wird nun an alle Links auf Deinen Seiten angehängt, die Deine eigenen Seiten aufrufen.
Wenn die Session-Variable und die GET (bzw POST) Variable gleich sind wird eine neue Variable erzeugt, die dann wieder an alle Links angehängt wird. Stimmen die Werte nicht überein, dann wurde ein Zurück-Link verwendet und Du kannst eine Fehlermeldung bringen und die Session zerstören.
Probleme dabei:

  1. Wird die Seite in einem anderen Fenster einmal aufgerufen, dann hast Du den gleichen Effekt. Sprich wenn jemand gerne die Funktion „Seite in neuem Fenster/Tab öffnen“ verwendet schmeisst es ihn immer wieder raus…
  2. Du kannst keine Frames verwenden andernfalls müsstest Du sicherstellen, dass alle Frames sich mitladen um alle die gleiche Variable zu erhalten.

Hi Bruno,

huiuiui, das ist ja ganz schön perfide! Da muss man schon hacken wollen. Aus Versehen macht das ja niemand, zumindest mit extrem geringer Wahrscheinlichkeit. Ich kann aber bezüglich dieses Punktes beruhigt sein.

Gruß
Querkopf

Hallo Hans-Dieter,

bitte entschuldige meine naive Fragerei. Ich hoffe, du warst auch mal dort, wo ich jetzt bin :wink:))

Unsinn mit den Sessions und Cookies sein lassen.

Wieso hälst du das für Unsinn? Die meisten Warenkörbe, Login-Scripts etc. laufen doch mit Cookies. Klar kann man sie abschalten. Aber wer sie nicht will, ist IMHO selbst schuld, dass er längst zum Standard gewordene Technik nicht zulässt und nur die statische Hälfte des Internets zu sehen bekommt. Wie kann es anders gehen, außer ständige reads und writes in die Datenbank oder in eine Datei? (Stichwort „traffic“)

Für die Geschlossene Usergruppe die sich anmelden kann würde
ich vorschlagen das du ein sicheres Loginscript schreibst mit
Passwortverschlüsselung „md5“.

Beschreibungen md5() für JS und PHP habe ich gefunden. Die Idee klingt zuerst vernünftig. Ich gehe davon aus, dass du meinst, dass die Codierung mit Javascript md5() clientseitig vorgenommen werden muss, bevor die Daten durchs löchrige Internetz geschickt werden. Alles Andere wäre ja sinnlos. Hier kommt aber auch schon wieder Javascript ins Spiel, das auch jeder ausschalten kann. Aber dazu stehe ich genauso wie zu Cookies und Sessions. Oder meinst du das doch irgendwie anders? Ich könnte mir noch vorstellen, dass ich z.B. Benutzername und Passwort bereits codiert in der DB habe und sie dann mit dem serverseitig md5-codierten Usereingaben vergleiche. Aber letztendlich sind die abgesendeten Daten maßgeblich und die können doch auf dem langen Weg vom Client zum Server abgegrast werden. Damit ist die Codierung letztendlich hinfällig. Wenn ein Hacker die gleichen Daten an das Zielscript sendet, wird er Zugriff erlangen. Bitte bring Licht ins Dunkel meiner Gehirnwindungen!

Ausserdem prüfst du anhank
einer kleinen Klasse „PHP“ bei jedem Seitenaufbau ob der User
angemeldet ist.

Das habe ich leider auch gar nicht verstanden. Wie soll ich das ohne Cookie wissen? Oder muss ich dann an jede Verweisadresse noch einen individuellen Parameter anhängen? Damit könnte aber auch wieder jeder, der so einen Seitenwechsel (mit Parameter) abgrast, zumindest kurzfristig unbefugt „geschützte“ Seiten besuchen, oder sehe ich das jetzt ganz falsch? Die History ist doch auch voll von solchen Adressen.

Ich wünsche dir in jedem Fall auch einen tollen Rutsch und ein gutes Jahr 2005. Prosit!

Gruß
Querkopf