Man geht davon aus, dass keine Cookies beim User möglich sind. ( Wenn das Gegenteil bewiesen ist, übergibt man die SID doch besser in einem Cookie und nicht im Request )
Die Session-ID braucht dringend ein Verfallsdatum. (z.B. 6 Stunden) (Bspl.: Die Kunden eines Shopsystems verlinken einzelne Produktseiten, samt ihrer ID...) Wenn eine ID verfallen ist vergibt man stillschweigend eine neue. Wenn eine falsche ID eingegeben wurde ( mit ner Regex das Schema prüfen ) vergibt man stillschweigend eine neue.
Auf keinen Fall, macht man für jede Session einen Datenbankeintrag. Diese Einträge braucht man erst, wenn der Warenkorb befüllt wird.
Warenkörbe haben einen extra Platz in so einer ID. Dieser Teil ist, wenn der Warenkorb befüllt wurde, immer gleich. Eigentlich ist das eine zweite ID innnerhalb der Session. Dieser Teil hat ein längeres Haltbarkeitsdatum (12 Wochen), wird aber, bei einer abgelaufenen Sid, nur akzeptiert, wenn er aus einen Cookie kommt.
Auf Suchmaschinen (Spider) muß man achten. Wenn die sich in so einen Shop verbeissen und Dank der ewig neuen Sid's, ewig neue Seiten finden kann das unschön enden. (Ich würde hier KFSW::SpiderDetect empfehlen, wenn ich es schon veröffentlicht hätte. SCNR) Ein erkannter Spider bekommt eine fixe ID, z.B. my_shop_name, dann findet er jede mögliche Seite nur einmal und gut ist. Da die Id nicht dem normalen Schema entspricht wird sie bei einem normalen User-Request ersetzt. (s.o) Dabei gibt es entweder eine neue ID oder, wenn der User schon einen Cookie haben sollte, die ID aus dem Cookie.
Alles Sicherheitsdenken, Kontrollierwünsche etc scheitern an der zu hohen Systemlast. Plane die Sids ohne irgendwelche sicherheitsrelevanten Features. (Für den Adminbereich mußt du natürlich was anderes machen.)
perl -e '$sid = time() . "XY" . rand(1) . "ZZ" . time() . "XY" . rand(1) . "ZZ" . time(); $sid =~ s/\./PT/g; print"$sid\n"' Ausgabe: 1050269667XY0PT917397911734046ZZ1050269667XY0PT0304125736906542ZZ1050269677
Wenn du das jetzt immer an ZZ zerlegst hast du drei Teile. Warenkorb, eigentliche Sid und Cachebrecher. Jeder Teil hat sein eigenes Startdatum.
Beim nächsten Aufruf wäre die Sid z.B.
1050269667XY0PT917397911734046ZZ1050269667XY0PT0304125736906542ZZ1050269700
Dieser String wird jetzt wie folgt geprüft: Erstmal eine RegEx drüber ob das Ding passen kann. Wenn das OK ist, geht es weiter:
Codebeispiel:
sub validate_session{ # ---- usage # if( validate_session( $sessionDataToValidate ) ){ print "Session Ok!\n"; } # requires: constant SESSION_TIME = 123; #ms # ---- # prüfen, ob gültige sid: a)muster b)haltbarkeit my $session = $_[0]; my $return = 0; if( $session =~ /\d{10}XY\d*PT\d{10}/ and (split /XY/, $session)[0] > time() - SESSION_TIME ){ $return = 1; } return $return; } # --------------------------------------------------------
a.) Wenn die Sid aus einem Cookie kommt, bleibt der erste Teil für z.B. sieben Wochen gültig. Der zweite Teil wird nach z.B. 6 Stunden erneuert. Der dritte Teil wird bei jedem Request durch time() ersetzt.
b.) Wenn die Sid nicht aus einem Cookie kommt, gibt es nach 6 Stunden eine komplett neue Sid. Der dritte Teil wird bei jedem Request durch time() ersetzt.
Code |
... use constant SESSION_TIME =&> &'60000&'; #ms ... # ---- CGI my &$cgi = CGI-&>new&(&); my &$query = &$cgi-&>Vars&(&); # ---- SETTINGS my %subs = &(&); &$subs{relative_url} = &$cgi-&>url&(-relative=&>1&); &$subs{full_url} = &$cgi-&>url&(-full=&>1&); ... print &$cgi-&>header&(-charset=&>&'ISO-8859-1&', -expires=&>&'+1s&', -type=&>&'text/html&', &); if&( &(exists &$query-&>{sid}&) # wenn session existiert and validate_session&( &$query-&>{sid} &) &){ # und gültig ist #session verlängern &$query-&>{sid} = time&(&) . &"XY&" . &(split /XY/, &$query-&>{sid}&)&[1&]; #settings &$subs{self} = &$subs{relative_url} . &'?sid=&' . &$query-&>{sid} . &'&file=&' . &$query-&>{file}; &$subs{query} = &'?sid=&' . &$query-&>{sid} . &'&file=&' . &$query-&>{file}; &$subs{domain} = &"http&://&" . DOMAIN; &$subs{sid} = &$query-&>{sid}; &$subs{file} = &$query-&>{file}; ... }else{ #wenn keine session existiert / session nicht gültig ist if&( exists &$query-&>{action} and &$query-&>{action} eq &"login&" and main&:&:validate_login&(&$query-&>{usn}, &$query-&>{pwd}&) &){ &$query-&>{sid} = time&(&) . &"XY&" . rand&(1&); &$query-&>{sid} =~ s/&\./PT/g; #settings &$subs{self} = &$subs{relative_url} . &'?sid=&' . &$query-&>{sid} . &'&file=&' . &$query-&>{file}; &$subs{query} = &'?sid=&' . &$query-&>{sid} . &'&file=&' . &$query-&>{file}; &$subs{domain} = &"http&://&" . DOMAIN; # erstes einloggen =&> INDEX print qq~& Login korrekt&!&~;print qq~&~; print qq~& SID&: &$query-&>{sid}& ~;print qq~& file&: &$query-&>{file}& ~;}else{ print &$loginForm; } } exit&( 1 &); ... # -------------------------------------------------------- # SUBS # -------------------------------------------------------- sub validate_login{ # ---- usage # if&( validate_login&( &$query-&>{usn}, &$query-&>{pwd} &) &){ print &"Login ok&!&\n&"; } # ---- requirements # modul&: Crypt&:&:PasswdMD5 # &$passfile -&> File mit USN&|PWD&(cryptedBy&: Crypt&:&:PasswdMD5&)&\n my &(&$usn, &$pwd&) = @_; my &$return = 0; open&(DAT, &$passfile&) &|&| die &"&$&! &(&$passfile&)&"; flock DAT, 1 if UNIX; my @passfile = & close&(DAT&); foreach &( @passfile &){ chomp &$_; if&( &$usn eq &(split /&\&|/,&$_&)&[0&] &){ if &(unix_md5_crypt&(&$pwd, &(split /&\&|/,&$_&)&[1&]&) eq &(split /&\&|/,&$_&)&[1&] &) { # Passwort in Ordnung &$return = 1; }else{ &$return = 0; } }else{ &$return = 0; } } return &$return; } # -------------------------------------------------------- sub validate_session{ # ---- usage # if&( validate_session&( &$sessionDataToValidate &) &){ print &"Session Ok&!&\n&"; } # ---- # prüfen, ob gültige sid&: a&)muster b&)haltbarkeit my &$session = &$_&[0&]; my &$return = 0; if&( &$session =~ /&\d{10}XY&\d*PT&\d{10}/ and &(split /XY/, &$session&)&[0&] &> time&(&) - SESSION_TIME &){ &$return = 1; } return &$return; } # -------------------------------------------------------- |
Sessions für Shopsysteme | Quelle: Threat auf perlunity.de |
---|
Hi! Zurück zur Frage, wo steht nochmal drin, ob der User AOL oder sonstwas benutzt? Dann noch was zum Session-Teil. Hatte eigentlich vor, auf Kekse soweit es geht zu verzichten. Jetzt steht allerdings Leistungsfähigkeit & Sicherheit gegen Kekse. Wieso sollte man nochmal auf den Einsatz von Keksen verzichten? (außer, dass manche Leute Kekse aus verständlichen Gründen deaktivieren) Was würdet ihr machen? --> Kurze Anmerkung, wie ich mir das vorstelle (in schmuckem pseudo-perl): if( AOL-User ){ Keks mit SessionID setzen Eintrag in Session-DB, mit SessionID & "AOL" }else{ Eintrag in Session-DB mit SessionID & IP #optional: Keks setzen } mfg pktm |
Hallo! Gruß |
Das mit den 1000 Dateien kann ich glaube ich verstehen. Die Session wollte ich in mein Shopsystem einbauen. Einmal für den Admin-Bereich und einmal für den Warenkorb. Das mit AOL ist irgendwie was spezielles, weil die Leute jedesmal über eine anderen Proxy geschickt werden, mehr dazu gabs mal hier: http://perl.black-cube.net/bin/ultraboard/UltraBoard.cgi?action=Read&BID=13&TID=20114&P=1&SID=99#ID24aber der Link geht nicht mehr;-( Mit den anderen Proxys hab ich eigentlich doch kein Problem, bleibt doch immer der selbe - oder? Dann gibts da ja noch die Möglichkeit mit mod_rewrite, den hab ich aber bei meinem Provider nicht. Hm, also - Vorschläge? :-) |
Hallo! Erstmal geht man davon aus, daß keine Cookies beim User möglich sind. ( Wenn das Gegenteil bewiesen ist, übergibt man die SID in einem Cookie und nicht im Request ) Die Session-ID braucht dringend ein Verfallsdatum. (z.B. 6 Stunden) (Die Kunden verlinken einzelne Produktseiten, samt ihrer ID...) Wenn eine ID verfallen ist vergibt man stillschweigend eine neue. Wenn eine falsche ID eingegeben wurde ( mit ner Regex das Schema prüfen ) vergibt man stillschweigend eine neue. In der Session-ID "bricht" man, bei Bedarf, den Browsercache, indem man time() mit einbaut. Auf keinen Fall, macht man für jede Session einen Datenbankeintrag. Diese Einträge braucht man erst, wenn der Warenkorb befüllt wird. Warenkörbe haben einen extra Platz in so einer ID. Dieser Teil ist, wenn der Warenkorb befüllt wurde, immer gleich. Eigentlich ist das eine zweite ID innnerhalb der Session. Dieser Teil hat ein längeres Haltbarkeitsdatum (12 Wochen), wird aber, bei einer abgelaufenen Sid, nur akzeptiert, wenn er aus einen Cookie kommt. Auf Suchmaschinen (Spider) muß man achten. Wenn die sich in so einen Shop verbeissen und Dank der ewig neuen Sid's, ewig neue Seiten finden kann das unschön enden. (Ich würde hier KFSW::SpiderDetect empfehlen, wenn ich es schon veröffentlicht hätte. SCNR) Ein erkannter Spider bekommt eine fixe ID, z.B. my_shop_name, dann findet er jede mögliche Seite nur einmal und gut ist. Da die Id nicht dem normalen Schema entspricht wird sie bei einem normalen User-Request ersetzt. (s.o) Dabei gibt es entweder eine neue ID oder, wenn der User schon einen Cookie haben sollte, die ID aus dem Cookie. Alles Sicherheitsdenken, Kontrollierwünsche etc scheitern an der zu hohen Systemlast. Plane die Sids ohne irgendwelche sicherheitsrelevanten Features. (Für den Adminbereich mußt du natürlich was anderes machen.) So, da hast du ein paar Anregungen, die auf drei Jahren (Shopbetrieb)Erfahrung beruhen, ich hoffe sie helfen dir. Gruß |
Hi! mfg pktm |
Hallo Beispiel Sid: perl -e '$sid = time() . "XY" . rand(1) . "ZZ" . time() . "XY" . rand(1) . "ZZ" . time(); $sid =~ s/\./PT/g; print"$sid\n"' Ausgabe: 1050269667XY0PT917397911734046ZZ1050269667XY0PT0304125736906542ZZ1050269677 Wenn du das jetzt immer an ZZ zerlegst hast du drei Teile. Warenkorb, eigentliche Sid und Cachebrecher. Jeder Teil hat sein eigenes Startdatum. Beim nächsten Aufruf wäre die Sid z.B. 1050269667XY0PT917397911734046ZZ1050269667XY0PT0304125736906542ZZ1050269700 Dieser String wird jetzt wie folgt geprüft: Erstmal ne regex drüber ob das Ding passen kann. Wenn das OK ist, geht es weiter: a.) Wenn die Sid aus einem Cookie kommt, bleibt der erste Teil für z.B. sieben
Wochen gültig. b.) Wenn die Sid nicht aus einem Cookie kommt, gibt es nach 6 Stunden eine
komplett neue Sid. Damit funktionieren Warenkörbe zwar nur mit Cookie richtig gut, aber ein Kunde, der in den Shop kommt und keine Cookies hat, kann dort in Ruhe einkaufen. (Er muß natürlich in 6 Stunden durch sein) Anders geht es leider nicht, denn wenn man die Warenkorbinformation aus dem Query-String länger als X Stunden akzeptiert, hat man wieder das Problem mit den Kunden, die Shopseiten verlinken und Ihre Sid im Link lassen. Gleiches gilt für versehentlich nicht erkannte WebSpider. Sind damit alle Klarheiten restlos beseitigt?;-) Gruß Kristian PS: 6 Stunden / 7 Wochen kann man natürlich durch andere Werte ersetzen |
Hi, >>dial-213-168-xx-xxx.netcologne.de<< so kommst du an den hostnamen ran: #!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Host-Ausgabe der REMOTE-Adresse</title></head><body><pre>\n"; use Socket; my $remote=$ENV{'REMOTE_ADDR'}; my $addr = inet_aton($remote); my $Wert = gethostbyaddr($addr, AF_INET); print "$Wert\n"; print "</pre></body></html>\n"; gruß klaus |
Ende |