Login mit Cookies - wie sicher machen?
membran
- perl
Hallo,
ich programmiere schon (ein wenig unprofessionell :) in Perl, nur mit dem Thema Sicherheit hab ich mich noch nicht befasst (befassen müssen). Nun mache ich ein Projekt, bei dem ein Login erforderlich ist. Dies wollte ich über Cookies lösen - was bislang auch ganz gut klappt.
Ich habe <a href="http://web.zdnet.de/internet/artikel/java/200202/perlcookies_03-wc.html
" target="_blank">diesen Codeschnipsel hier (neues Fenster) verwendet.
Die Idee ist folgende (ich habe kein SSL!):
Meine Fragen, da ich nicht weiss, wie man Daten übers Internet "abfischen" kann:
An welchen Stellen ist dieses System verwundbar, und wie hoch ist die wirkliche Gefahr?
Kann man das Cookie fälschen? Im Endeffekt steht ja nur der Username drin. Wenn man es fälschen kann, kann ich mich ja leicht für einen bestimmten User ausgeben - das Passwort brauch ich dann ja nicht...
Wie sähe ein "besseres" Cookie aus? Laut Codeschnipsel wird nur Username reingeschrieben. Im Cookie selbst sieht man noch ein paar Zahlen, woher kommen die denn?
Wie siehts mit der SQL-Datenbank und Passwort im Klarnamen aus? Was wäre die Alternative?
Ich lese immer von Session-Ids, was müsste ich denn damit machen? Da hatte jede Seite eine andere Meinung.
Danke für eure Hilfe.
- Der User gibt auf einem Formular Name und Passwort ein.
- Aus einer mySQL-Datenbank wird geprüft, ob die beiden Werte zusammenpassen.
- (Passwort ist in der DB im Klarnamen geschrieben! Ein Fehler?)
Jein, genau genommen kommt es darauf an, wie sicher die Datenbank ist. Grundsätzlich solltest Du aber doch lieber eine Verschlüsselung oder noch besser Prüfsumme statt des Passworts benutzen. MySQL bietet dafür unter anderem die eingebaute SQL-Funktion MD5(), der Programmieraufwand beschränkt sich deshalb auf das Austauschen von "passwort=[eingabe]" durch "passwort=md5([eingabe])" bei insert und select. Gemessen an der zusätzlichen Sicherheit ist es eigentlich schon sträflicher Leichtsinn, diese fünf zusätzlichen Zeichen pro SQL-Befehl nicht einzutippen.
- Wenn richtig, wird ein Cookie anhand oberen Codes gesetzt, mit dem Usernamen als Value. Das Cookie verliert die Gültigkeit beim Schließen des Browsers.
Das ist Mist.
- Kann man das Cookie fälschen? Im Endeffekt steht ja nur der Username drin. Wenn man es fälschen kann, kann ich mich ja leicht für einen bestimmten User ausgeben - das Passwort brauch ich dann ja nicht...
Überlege doch mal: Was hindert Dich als furchtbar böser Wicht[tm] daran, in Deinem Browser einen Cookie mit einem beliebigen Usernamen zu erzeugen, wo Cookies von Browsern doch als Klartextdateien gespeichert werden? Gar nichts.
- Wie sähe ein "besseres" Cookie aus? Laut Codeschnipsel wird nur Username reingeschrieben. Im Cookie selbst sieht man noch ein paar Zahlen, woher kommen die denn?
Eventuell siehe unten, ansonsten können es auch andere interne Daten sein (meinetwegen die letzte aufgerufene Seite oder sonstwas).
- Wie siehts mit der SQL-Datenbank und Passwort im Klarnamen aus? Was wäre die Alternative?
Siehe oben.
- Ich lese immer von Session-Ids, was müsste ich denn damit machen? Da hatte jede Seite eine andere Meinung.
Diese IDs sind eindeutige Nummern, die pro Sitzung vergeben werden. Da sie von einem Zufallsgenerator erzeugt werden und ellenlang sind, lassen sie sich nicht erraten.
Beim Anmelden erzeugst Du nach Prüfung von Name und Passwort eine solche ID, speicherst sie auf dem Server (mit Verweis auf den Benutzernamen) und als Cookie im Browser. Beim nächsten Seitenaufruf bekommt der Server diese ID wieder zurückgeliefert und kann anhand der bei ihm gespeicherten IDs herausfinden, welcher Benutzer da gerade am Werk ist.
Achte darauf, dass der Server zusammen mit der ID auch eine Verfallszeit von vielleicht 10 Minuten speichert, so dass niemand nach drei Tagen mit einer zufällig aufgeschnappten ID eine Sitzung kapern kann.
Ausser der Session-ID müssen keine weiteren Daten im Cookie gespeichert werden, auch der Benutzername kann über die ID aus der internen Datenbank geholt werden.
Unter http://search.cpan.org/search?query=Session&mode=all findest Du passende Unterstützung.
»»Gemessen an der zusätzlichen Sicherheit ist es eigentlich schon sträflicher Leichtsinn, diese fünf zusätzlichen Zeichen pro SQL-Befehl nicht einzutippen.
Okay, werde ich machen.
- Wenn richtig, wird ein Cookie anhand oberen Codes gesetzt, mit dem Usernamen als Value. Das Cookie verliert die Gültigkeit beim Schließen des Browsers.
Das ist Mist.
Wieso?
Okay, wenn ich es über eine SID mache, brauch das Cookie nicht zu verfallen, weil die DB eh dann aussagt, daß die halbe Stunde (oder so) vorbei ist.
Überlege doch mal: Was hindert Dich als furchtbar böser Wicht[tm] daran, in Deinem Browser einen Cookie mit einem beliebigen Usernamen zu erzeugen, wo Cookies von Browsern doch als Klartextdateien gespeichert werden? Gar nichts.
Hmm. Genau DAS hatte ich befürchtet.
Dann geht das ja schonmal gar nicht.
Beim Anmelden erzeugst Du nach Prüfung von Name und Passwort eine solche ID, speicherst sie auf dem Server (mit Verweis auf den Benutzernamen) und als Cookie im Browser. Beim nächsten Seitenaufruf bekommt der Server diese ID wieder zurückgeliefert und kann anhand der bei ihm gespeicherten IDs herausfinden, welcher Benutzer da gerade am Werk ist.
Hört sich gut an.
Achte darauf, dass der Server zusammen mit der ID auch eine Verfallszeit von vielleicht 10 Minuten speichert, so dass niemand nach drei Tagen mit einer zufällig aufgeschnappten ID eine Sitzung kapern kann.
Zum Glück ist Date::Calc intalliert :)
Aber was mache ich mit den "toten" Sitzungen? Wenn das einige Zeit läuft, hab ich ja tausende Einträge im "Session"-Table (kann doch ein Table sein, oder muss es eine abgetrennte DB sein?), die nicht mehr gebraucht werden.
Dann langt es ja wohl, wenn ich bei jedem SID-Check auch gleichzeitig alle SIDs lösche, die älter als n Tage sind, oder?
Ausser der Session-ID müssen keine weiteren Daten im Cookie gespeichert werden, auch der Benutzername kann über die ID aus der internen Datenbank geholt werden.
Leuchtet ein.
Was ist, wenn der User keine Cookies akzeptiert?
(Frage: Wie häufig kommt das vor?)
Ich nehme an, dann schleppt man die SID im Querystring ständig mit?
Unter http://search.cpan.org/search?query=Session&mode=all findest Du passende Unterstützung.
Ich hab laut sysinfo.cgi meines Serverbetreibers nur folgende CGI-Module installiert:
CGI 2.81
CGI::Carp 1.23
CGI::Cookie 1.20
CGI::Fast 1.04
CGI::Pretty 1.05
CGI::Push 1.04
CGI::Util 1.3
ODer ist Session in CGI.pm mit eingebettet (bin auch bei Modulen noch recht noobig drauf...)
Erstmal danke für deine Hilfe.
- Wenn richtig, wird ein Cookie anhand oberen Codes gesetzt, mit dem Usernamen als Value. Das Cookie verliert die Gültigkeit beim Schließen des Browsers.
Das ist Mist.
Wieso?
Ich meinte die Sache mit dem Namen, nicht die Gültigkeit, die ist in Ordnung.
Aber was mache ich mit den "toten" Sitzungen? Wenn das einige Zeit läuft, hab ich ja tausende Einträge im "Session"-Table (kann doch ein Table sein, oder muss es eine abgetrennte DB sein?), die nicht mehr gebraucht werden.
Sofern Du ein Sessionmodul bei Dir findest, wird das auch die Aufräumarbeiten erledigen.
Dann langt es ja wohl, wenn ich bei jedem SID-Check auch gleichzeitig alle SIDs lösche, die älter als n Tage sind, oder?
Entweder dies oder Du speicherst die ID (und ihren Ablaufzeitpunkt) einfach als weitere Spalte bei den Benutzerdaten. Ist zwar etwas unkonventionell, aber auch praktisch, falls jemand sein Passwort vergessen hat: Du machst auf Anfrage einfach für zwei Minuten eine neue Session auf und schickst dem Glücklosen die Session-ID in einer Mail als anklickbaren Link ("login.pl?sid=123121213"). Damit kann er dann die Session übernehmen und selbst ein neues Passwort eintippen.
So kann man übrigens auch komplett passwortlose Zugänge einrichten.
Was ist, wenn der User keine Cookies akzeptiert?
Ich nehme an, dann schleppt man die SID im Querystring ständig mit?
Richtig.
(Frage: Wie häufig kommt das vor?)
Wenn Du mit den Cookies nicht (wie leider viele Sites) sinnlos rumsaust, sondern sie stattdessen nur bei tatsächlichem und für den Benutzer erkennbaren Bedarf einsetzt, werden Deine Benutzer Cookies sicher gerne zulassen. Je sparsamer Du mit Cookies umgehst, desto weniger Leute werden ein Problem damit haben.
Ich hab laut sysinfo.cgi meines Serverbetreibers nur folgende CGI-Module installiert:
Frage am besten Deinen Serverbetreiber nach einem Sessionmodul für Perl. Er kennt den Server und sollte Dir gerne Auskunft geben.
Danke für deine Hilfe, es klappt jetzt wunderbar (sicher) :)