Sicherheitsbedenken/Warenkorb/Frameset
Sabine
- php
Hallo und guten Morgen!
Ich überlege nun schon ein paar Tage an einem Problem herum bzw. frage mich ob ich in meinem Gedanken mir zu viele Sorgen um die Sicherheit mache (falls das überhaupt möglich sit) und würde mich freuen eure Meinung dazu zu hören.
Es geht um folgendes: Ich habe eine Website mit Online-Shop und Warenkorb-Funktion. Website ist als Frameset realisiert. (das ganze läuft mit MySQL-Datenbank und PHP)
Nun sind mir 2 Dinge wichtig: Nr.1 die "eindeutige" (soweit möglich) Erkennung des Benutzers damit Warenkörbe sich nicht überschneiden etc. Nr. 2 das Nachladen des Framesets (Suchmaschinen-Problem).
Mein Problem ist eigentlich keines wenn ich Session-Cookies verwenden darf, denn dann speicher ich einfach die PHPSESSID und frage auf den Seiten ab ob das Cookie gesetzt ist, wenn nein, wird
1. Das Frameset nachgeladen und
2. Eine PHPSESSID vergeben.
Meine Problem beginnt wenn ich keine Cookies verwenden darf, da der Besucher diese deaktiviert hat.
Dafür habe ich nun eine Tabelle in meiner Datenbank in der ich die SessionID eintrage + Timestamp, die Sessionid gebe ich mit den Links weiter. Steigt nun ein Besucher über irgendeine Seite ein und ist die PHPSESSID nicht drangehängt beim Aufruf einer einzelnen Seite aus meinem Frameset wird nachgeladen + PHPSESSID vergeben. Soweit auch alles klar.
Und nun beginnt mein Problem - wenn nun jemand versucht über irgendeine Seite (ohne das Frameset geladen zu haben) einzusteigen und hängt an diese eine PHPSESSID dran (aus welchen Gründen auch immer, aber ich denke mir, dass so etwas sicherlich vorkommt, habe ich bereits auch in einigen Postings im Forum gelesen), weiß ich nicht was ich mit dem tun soll, wenn es die PHPSESSID gibt.
Grundsätzlich würde er auf dieser Seite bleiben, ist quasi in der Datenbank registriert. Abgesehen davon, dass ich dann das Frameset nicht nachladen kann, habe ich das Problem dass dann zwei mit der gleichen PHPSESSID zugreifen.
Ich hoffe das war halbwegs verständlich wo mein Problem liegt. Es geht mir einfach um folgendes - ein Benutzer ist online und hat nun an jeden Link drangehängt PHPSESSID=xy - geht er z.B. auf die Startseite hat er die $REQUEST_URI ....start.php?PHPSESSID=xy. Was aber nun wenn einer versucht direkt start.php?PHPSESSID=xy in die Adresszeile direkt einzugeben - ich kann ihn dann ja nicht umleiten, da ich ja nur die $REQUEST_URI und nicht den Inhalt der Adresszeile abfragen kann. Ich erkenne also nicht den Unterschied ob der Benutzer nun über das Frameset kommt und "eindeutig" identifiziert bzw. verfolgt werden kann oder sich "reinschmuggeln" will.
So das war die lange Vorgeschichte, nun noch dazu meine Überlegungen wie ich mir denke bzw. gedacht habe das lösen zu können und ein paar Fragen.
Nr 1: Zuerst habe ich in meiner Tabelle in der ich die SIDs eintrage eine Spalte dazugemacht, in der ich einen Eintrag gemacht habe, wenn das Frameset geladen wurde (denn auf der Index wird ihm eigentlich die SID vergeben). Für meinen Fall bringt mir das aber auch nicht viel, denn wenn nun ein Besucher drinnen ist in dem das Nachladen als Ok definiert ist und ein 2. mit der gleichen PHPSESSID einsteigen will, bin ich ja wieder beim gleichen Problem.
Nr. 2: IP-Adresse. Ich habe mir gedacht, zusätzlich zur PHPSESSID die IP-Adresse in der Tabelle zu speichern und abzufragen auf den Seiten ob die PHPSESSID mit der übergebenen und die IP-Adresse mit der IP-Adresse meines Besuchers übereinstimmt. Wenn ja, darf er normal weiter, wenn nein wird er auf die index umgeleitet und bekommt eine neue SID. Dabei gibt es aber auch ein Problem (denke ich zumindest). Ich arbeite z.B. selbst so, dass sich meine Internetverbindung bei kurzer Zeit Leerlauf (ca. 20 sec) abbricht und erst bei Klick auf den nächsten Link wiederherstellt. Da bekomme ich dann aber wieder eine neue IP oder? Und obwohl ich berechtigt die Seite aufgerufen habe, bekomme ich wieder eine neue SID nach meinem System. Stimmt das?
Nr. 3: Sobald der Kunde in den richtigen Bestellvorgang geht, habe ich das Problem nicht mehr in dem Ausmaß, denn dann bekommt er am Beginn z.B. Kundennummer/Passwort und sollte die Verbindung wirklich verloren sein und gespeichert + reale IP nicht mehr übereinstimmen, kann ich ihn ja nach Kundennummer/Passwort fragen.
Nr. 4. Sobald er etwas in den Warenkorb legt, habe ich mir überlegt, könnte ich ja zu meiner Tabelle mit der PHPSESSID die Warenkorbnummer dazuspeichern, da kann ich dann aber nichts abfragen ....
Ihr seht ich bin da ziemlich ratlos und wäre sehr froh über eure Meinung wie man bei einem Online-Shop Kunden die Cookies deaktiviert haben, möglichst sicher durchführen kann.
Über die Möglichkeiten z.B. eine möglichst lange ID zu vergeben weiß ich Bescheid, ist mir auch klar. Trotzdem bleibt für mich ja trotzdem das Problem bestehen, denn auch wenn ich eine ID mit 100 Zeichen vergebe / mitschicke kann theoretisch und praktisch doch der Missbrauch passieren.
Ich würde mich schon über ein Feedback von euch freuen nach dem Motto - Du hast Recht, hier gibt es Probleme oder deine Bedenken sind umsonst, noch mehr natürlich über Anregungen wie das Problem in Griff zu bekommen ist.
Ich weiß, dass zu diesem Thema schon einiges gepostet ist, hier bin ich aber über das was ich eigentlich schon weiß (Cookies am sichersten, SID an die Url dranhängen, SID nicht in Adresszeile etc) nicht hinausgekommen.
Danke im Voraus für Anregungen und Meinungen.
Sabine
Hallo Sabine!
Nr 1: [doppeltes Benutzen einer Sesion]
Das ist prinzipiell nicht vermeidbar.
Üblicherweise haben die Sessions deshalb eine begrenzte Lebensdauer.
Nr. 2: IP-Adresse.
Kurz gesagt: geht nicht. Einen Einwand hattest du ja schon selber (erneute Einwahl), es ist aber noch viel schlimmer: Benutzer (z.B.!) des T-Online Proxies können bei direkt aufeinananderfolgenden Zugriffen unterschiedliche IPs haben, dafür haben aber zwei unterschiedliche Benuzter die gleiche.
Nr. 3: Sobald der Kunde in den richtigen Bestellvorgang geht [...]
solltest du vor allem eine SSL-Verbindung benuzten. Inwiefern dir das bei der Useridentifizierung hilft weiss ich nicht. (Gibt es da 'sessions' oder ist das Protokol ebenso zustandslos wie http?)
(zumindest wären per Formular und "post" übertragenen Daten verschlüsselt.)
Nr. 4. Sobald er etwas in den Warenkorb legt, habe ich mir überlegt, könnte ich ja zu meiner Tabelle mit der PHPSESSID die Warenkorbnummer dazuspeichern, da kann ich dann aber nichts abfragen ....
Das Hilft bei der Authentifizierung kein Stück weiter als die Session ID.
Aber ein anderer Aspekt: Du hast was ganz tolles gefunden und möchtest das jemandem zeigen. Also flugs die URL kopiert, in eine Mail damit und an denjenigen verschickt. Wäre doch klasse wenn das geht! Dazu müsste in der URL allerding (immer!) die Artikelbezeichnung extra stehen.
Über die Möglichkeiten z.B. eine möglichst lange ID zu vergeben weiß ich Bescheid ...
Benutze doch die in PHP vorhandenen bzw in der PHP-Lib vorhandenen Session Funktionen. Da haben andere Leute lange drüber nachgedacht...
So, der Freizeitstress ruft... hoffe das hilft dir zumindest ein wenig weiter.
Gruss,
Carsten
Hallo Carsten!
Hallo Sabine!
Nr 1: [doppeltes Benutzen einer Sesion]
Das ist prinzipiell nicht vermeidbar.
Ich weiß und deshalb habe ich schon graue Haare :)
Üblicherweise haben die Sessions deshalb eine begrenzte Lebensdauer.
Nr. 2: IP-Adresse.
Kurz gesagt: geht nicht. Einen Einwand hattest du ja schon selber (erneute Einwahl), es ist aber noch viel schlimmer: Benutzer (z.B.!) des T-Online Proxies können bei direkt aufeinananderfolgenden Zugriffen unterschiedliche IPs haben, dafür haben aber zwei unterschiedliche Benuzter die gleiche.
Ach wie toll! Noch ein graues Haar mehr ...
Nr. 3: Sobald der Kunde in den richtigen Bestellvorgang geht [...]
solltest du vor allem eine SSL-Verbindung benuzten. Inwiefern dir das bei der Useridentifizierung hilft weiss ich nicht. (Gibt es da 'sessions' oder ist das Protokol ebenso zustandslos wie http?)
(zumindest wären per Formular und "post" übertragenen Daten verschlüsselt.)
Ja, ist klar bzgl. SSL. Hilft mir aber (so denke ich) bei meinem Problem mit der Useridentifizierung auch nicht wirklich - wenn ich schon mal an den Warenkorb denke.
Nr. 4. Sobald er etwas in den Warenkorb legt, habe ich mir überlegt, könnte ich ja zu meiner Tabelle mit der PHPSESSID die Warenkorbnummer dazuspeichern, da kann ich dann aber nichts abfragen ....
Das Hilft bei der Authentifizierung kein Stück weiter als die Session ID.
Eben, das habe ich mir auch gedacht - ist ja nur eine Zahl mehr die mir dann aber im Prinzip auch nichts sagt, nur dass der Warenkorb zu einer bestimmten ID gehört - ob der mit der ID jetzt aber wirklich auch der ist, der die Waren reingelegt hat, weiß ich deshalb auch nicht wirklich ...
Aber ein anderer Aspekt: Du hast was ganz tolles gefunden und möchtest das jemandem zeigen. Also flugs die URL kopiert, in eine Mail damit und an denjenigen verschickt. Wäre doch klasse wenn das geht! Dazu müsste in der URL allerding (immer!) die Artikelbezeichnung extra stehen.
Da hast du Recht. Da könnte ich dann eigentlich nur das Frameset immer neu laden also target=_parent die ganze Seite aufrufen, damit ich die entsprechenden Angaben in der Adresszeile habe. Wenn ich hier die ID im normales Ablauf versteckt (also nicht in der Adresszeile) an die Index-Datei übergeben könnte, wäre dies vielleicht sogar ein Ansatz für die Useridentifizierung. (Denn dann könnte ich sagen, wenn die ID in der Adresszeile steht ist das ein User der sich zwischendrinnen mit irgendeiner ID einloggen will und ich vergebe ihm auf der Index-Seite eine neue ID.) Wie aber bekomme ich die ID in die Index-Datei ohne diese in der Adresszeile anzuzeigen ... Mit Post ist klar, aber wie kann ich den ein hidden-Field irgendwie bei einem meta-refresh oder header ("Location...") verwenden ? ...
Über die Möglichkeiten z.B. eine möglichst lange ID zu vergeben weiß ich Bescheid ...
Benutze doch die in PHP vorhandenen bzw in der PHP-Lib vorhandenen Session Funktionen. Da haben andere Leute lange drüber nachgedacht...
Ja, ganz klar. Will ich auch.
So, der Freizeitstress ruft... hoffe das hilft dir zumindest ein wenig weiter.
Ja, danke für deine Antwort. Mein Gehirn hat wieder Futter. Schönen Tag wünsche ich dir!
Schöne Grüße
Sabine
Gruss,
Carsten
Guten Morgen
Und nun beginnt mein Problem - wenn nun jemand versucht über irgendeine Seite (ohne das Frameset geladen zu haben) einzusteigen und hängt an diese eine PHPSESSID dran (aus welchen Gründen auch immer, aber ich denke mir, dass so etwas sicherlich vorkommt, habe ich bereits auch in einigen Postings im Forum gelesen), weiß ich nicht was ich mit dem tun soll, wenn es die PHPSESSID gibt.
Grundsätzlich würde er auf dieser Seite bleiben, ist quasi in der Datenbank registriert. Abgesehen davon, dass ich dann das Frameset nicht nachladen kann, habe ich das Problem dass dann zwei mit der gleichen PHPSESSID zugreifen.
Du könntest die Navigation auf deinen Seiten über post-Formulare machen und die PHPSESSID nur akzeptieren, wenn sie in den $HTTP_POST_VARS[] steht. Das würde dann schon einigen Aufwand bedeuten, dies zu "hacken". Wobei noch die Frage bleibt, was die Gründe für das von dir beschriebene Verhalten eines Users sein könnte:
1. Zufall: Sehr unwahrscheinlich, daß er eine gerade gültige PHPSESSID erwischt, ich denke, daß man diesen Fall eigentlich ausschließen kann, das ist aber mit Sicherheit durch oben beschriebene Methode zu verhindern.
2. Bosheit: Möglich und auch durch nichts zu verhindern, wobei es schwierig sein dürfte, eine gültige PHPSESSID herauszubekommen, wenn man keinen Zugriff auf einen Rechner hat, der eine vom Server bekommen hat; die PHPSESSID ist auch aus einem Cookie auslesbar, und es ist auch möglich, Cookies zu "simulieren", so daß du vor dem gleichen Problem stehst. Die Frage ist hier aber, was es für einen Hacker bringen kann, sich als ein Kunde auszugeben, der gerade etwas bestellen will. Bei Abschluß einer Bestellung sollte doch ohnehin nach Name / Passwort gefragt werden, und auch nocheinmal alle Artikel aufgelistet werden.
3. Browserwechsel: Ich komme z.b. mit Opera immer wieder auf seiten, die nicht richtig angezeigt werden, da bin ich dann sehr froh, wenn alle angaben in der URL stehen, dann kann ich mit einem anderen Browser direkt da weitersurfen. Scheidet aber bei Framesets sowieso aus (leider, leider, leider, vielleicht sollte man doch darüber nachdenken, ob man das nicht ohne Frames machen könnte, auch wenn ich das gar nicht schreiben möchte, weil ich die Antworten a la "ich habe ein Problem mit Frames" - "Dann nimm keine Frames" nicht sehr schätze...)
Heizer
Guten Morgen Heizer!
Guten Morgen
Du könntest die Navigation auf deinen Seiten über post-Formulare machen und die PHPSESSID nur akzeptieren, wenn sie in den $HTTP_POST_VARS[] steht. Das würde dann schon einigen Aufwand bedeuten, dies zu "hacken".
Das habe ich mir bereits überlegt, dann schließe ich aber wahrscheinlich wieder eine Zielgruppe aus. Habe z.b Bilder als Links, die ich dann entweder mit javascript:....submit() verschicken müsste oder aber als submit-Button mit Background-Image, was aber wieder nicht von allen Browsern bzw. Versionen angezeigt wird.
Wobei noch die Frage bleibt, was die Gründe für das von dir beschriebene Verhalten eines Users sein könnte:
- Zufall: Sehr unwahrscheinlich, daß er eine gerade gültige PHPSESSID erwischt, ich denke, daß man diesen Fall eigentlich ausschließen kann, das ist aber mit Sicherheit durch oben beschriebene Methode zu verhindern.
Da hast du Recht, dieses Problem wäre damit gelöst. Wenns Zufall war habe ich den Nutzer damit im Griff
- Bosheit: Möglich und auch durch nichts zu verhindern, wobei es schwierig sein dürfte, eine gültige PHPSESSID herauszubekommen, wenn man keinen Zugriff auf einen Rechner hat, der eine vom Server bekommen hat; die PHPSESSID ist auch aus einem Cookie auslesbar, und es ist auch möglich, Cookies zu "simulieren", so daß du vor dem gleichen Problem stehst. Die Frage ist hier aber, was es für einen Hacker bringen kann, sich als ein Kunde auszugeben, der gerade etwas bestellen will. Bei Abschluß einer Bestellung sollte doch ohnehin nach Name / Passwort gefragt werden, und auch nocheinmal alle Artikel aufgelistet werden.
Tja, diese Nutzer sind schon eher mein Problem, auch wenn ich über hidden-fields die PHPSESSID weiter gebe ist es doch kein Problem diese Werte über den Quelltext zu sehen ... Zu Name und Passwort - ja, sobald der Besucher bestellt (also im Warenkorb auf Bestellen klickt), gibt er Name/Passwort ein bzw. registriert sich wenn er ein neuer ist und bekommt Name und Passwort.
- Browserwechsel: Ich komme z.b. mit Opera immer wieder auf seiten, die nicht richtig angezeigt werden, da bin ich dann sehr froh, wenn alle angaben in der URL stehen, dann kann ich mit einem anderen Browser direkt da weitersurfen. Scheidet aber bei Framesets sowieso aus (leider, leider, leider, vielleicht sollte man doch darüber nachdenken, ob man das nicht ohne Frames machen könnte, auch wenn ich das gar nicht schreiben möchte, weil ich die Antworten a la "ich habe ein Problem mit Frames" - "Dann nimm keine Frames" nicht sehr schätze...)
Ja, mir wäre es auch lieber ohne Frames aus allen hinreichend bekannten Gründen. Ich überlege aber wirklich ob es nicht sinnvoll wäre, jedesmal das gesamte Frameset neu zu laden. Der Besucher ruft dann z.B. die start.php auf, das Frameset wird entweder geladen und z.B. der Seitenname in einer Variable gespeichert und so in <frame src="$variable"... eingesetzt oder direkt das Frameset dynamisch erzeugt ... Darin sehe ich eigentlich nicht so das Problem, aber wie bekomme ich meine Nutzer in Griff ... Über Post wäre sicher gut, wenn es da nicht die Möglichkeit gäbe Javascript zu deaktivieren ...
Danke für deine Anregungen Heizer!
Schöne Grüße
Sabine
Heizer
Hallo nochmals!
Ob beruhigend oder erschreckend - dafür habe ich mich noch nicht entschieden. Zumindest ist es so, dass auch andere das Problem nicht in den Griff bekommen, z.B. Amazon.de - mit Cookies alles wunderbar - ohne kann ich mit etwas Glück im Warenkorb eines anderen schnüffeln.
... Grübel grübel ... mach ich mir da wirklich zu viele Sorgen und ist das für die Besucher gar nicht so schlimm wenn Sie Cookies deaktivert haben? Also ich möchte das nicht, dass jemand anders sehen kann was ich gerade einkaufe ...
Schöne Grüße
Sabine
Hallo,
Ich würde mich schon über ein Feedback von euch freuen nach dem Motto - Du hast Recht, hier gibt es Probleme oder deine Bedenken sind umsonst, noch mehr natürlich über Anregungen wie das Problem in Griff zu bekommen ist.
Ich weiß, dass zu diesem Thema schon einiges gepostet ist, hier bin ich aber über das was ich eigentlich schon weiß (Cookies am sichersten, SID an die Url dranhängen, SID nicht in Adresszeile etc) nicht hinausgekommen.
Wie waere es denn z.B. mit einem Referer-Check? (gut - kann auch gefaked werden, aber da muss sich jemand schon viel Mühe machen) Daraus kommt wieder das Problem mit dem Browserwechsel (was hier im Thread schon beschrieben worden ist), aber ich denke, da der User sowieso das ganze Frameset nachladen muss, wenn er den Browser wechsel, dann ist das nicht so dramatisch. (Wenn man ohne oder mit anderem Referer auf die Seite kommt, sollte nicht der Zugriff verweigert werden, sondern nur noch mal nach Benutzernamen und Passwort gefragt werden)
Grüsse,
Christian
Hallo Christian!
Ich würde mich schon über ein Feedback von euch freuen nach dem Motto - Du hast Recht, hier gibt es Probleme oder deine Bedenken sind umsonst, noch mehr natürlich über Anregungen wie das Problem in Griff zu bekommen ist.
Ich weiß, dass zu diesem Thema schon einiges gepostet ist, hier bin ich aber über das was ich eigentlich schon weiß (Cookies am sichersten, SID an die Url dranhängen, SID nicht in Adresszeile etc) nicht hinausgekommen.
Wie waere es denn z.B. mit einem Referer-Check? (gut - kann auch gefaked werden, aber da muss sich jemand schon viel Mühe machen) Daraus kommt wieder das Problem mit dem Browserwechsel (was hier im Thread schon beschrieben worden ist), aber ich denke, da der User sowieso das ganze Frameset nachladen muss, wenn er den Browser wechsel, dann ist das nicht so dramatisch. (Wenn man ohne oder mit anderem Referer auf die Seite kommt, sollte nicht der Zugriff verweigert werden, sondern nur noch mal nach Benutzernamen und Passwort gefragt werden)
Ja, daran habe ich auch gedacht, aber auch gelesen, dass von einigen Browsern die REFER-Angabe nicht bzw. nicht richtig übertragen wird. Ist dies eher die Ausnahme oder eher Regelfall?
Schöne Grüße
Sabine
Grüsse,
Christian
Hallo,
Ja, daran habe ich auch gedacht, aber auch gelesen, dass von einigen Browsern die REFER-Angabe nicht bzw. nicht richtig übertragen wird. Ist dies eher die Ausnahme oder eher Regelfall?
Von Opera weiß ich's nicht, Mozilla machts auf jeden Fall korrekt, IE und NN4 AFAIK auch (da kann ich mich aber auch irren). Du kannst ja eine Session-Variable setzen, die beim Login auf true gesetzt wird (z.B. $referer_check) und beim Aufruf danach auf false. Wenn die Variable auf true gesetzt ist, dann ein falscher Referer gesendet wird, dann wird eine andere Session-Variable (z.B. $supports_referer) auf false gesetzt und die Session läuft im "weniger sicheren Modus" ab, wenn der Referer passt, dann wird $supports_referer auf true gesetzt und die Session läuft im sichereren Modus.
Bsp-Code:
-------- login.php o.ä. -------------
function login (...) {
...
$_SESSION["referer_check"] = true;
$_SESSION["supports_referer"] = false; // damit er nicht gleich wieder zum Login-Bildschirm kommt, wenn die Seite nach dem Login gesendet wird
}
-------------------------------------
-------- prepend.php o.ä. -----------
...
// falls im Safe-Mode - extracte den Session-array
// alternative: du verwendest immer $_SESSION
extract ($_SESSION);
...
if ($supports_referer && !(...referer-check per regexp o.ä....)) {
display_login_form (); // o.ä.
}
if ($referer_check && !(...referer-check per regexp o.ä....)) {
// achtung, zur Erinnerung: damit ein Variablenwert in der Session
// registriert wird, muss er in den $_SESSION-Array geschrieben
// werden und NICHT in die entspr. globale Variable
$_SESSION["supports_referer"] = false;
} else {
$_SESSION["supports_referer"] = true;
}
// referer_check IMMER auf false setzen
$_SESSION["referer_check"] = false;
...
-------------------------------------
Aber noch etwas:
Eine Session-ID ist ein MD5-Hash. Selbst wenn man alle durchprobiert, hat man 36^32 (= ca. 6,33*10^49) verschiedene Möglichkeiten (wenn bei einem MD5-Hash Zahlen und Buchstaben beliebig verteilt sind und er nur Zahlen und Buchstaben enthalten darf - so genau hab' ich mich da noch nicht mit auseinandergesetzt) - das ist mit heutigen Rechnern so gut wie unknackbar. Und falls so was knackbar wird, kann man immer noch 2 Hashes aneinanderhängen (dann sind's 36^64 versch. Möglichkeiten). Ich denke, ein Username und ein Passwort ist einfacher geknackt als eine Session-ID.
Grüße,
Christian