Moin!
Derzeit versuche ich, ein Kundenmenü sicherer zu bekommen als es derzeit ist.
Welche Angriffsmöglichkeiten hast du für den jetzigen Zustand herausgefunden? Nur wenn du weißt, wie man beim jetzigen Zustand angreifen kann, kannst du Methoden entwickeln, diese Lücken zu schließen.
Sicherheit würde ich gerne folgendermaßen herstellen:
****
User loggt sich ein,
es werden 2 Session-ID's erzeugt.
Zwei Session-IDs bringen genausoviel, wie eine Session-ID. Denn grundsätzlich gilt: Authentifizierung wird bei HTTP dadurch realisiert, dass der Client dem Browser mit jedem Request etwas mitsendet, was den Client authentifiziert. Das kann eine Username/Passwort-Kombi sein, oder eben die richtige (weil auf dem Server als "eingeloggt" registrierte) Session-ID.
Die einzige Angriffsmöglichkeit ist im Prinzip "Ausprobieren durch Raten". Du schaffst also mehr Sicherheit, indem du mehr Ratemöglichkeiten ermöglichst, so dass das Ausprobieren aller Kombinationen sehr lange dauert bzw. mit heutiger Hardware schlicht unmöglich in einem Menschenleben zu schaffen ist.
Wichtig ist dabei natürlich, dass das Raten wirklich in einem Raum passiert, in der keine Session-ID irgendwie häufiger vorkommt bzw. gar aufgrund von Analysen vorhergehender IDs abgeschätzt oder gar direkt berechnet werden kann.
Das größte Problem allerdings dürfte sein, dass du trotz aller Session-IDs (und dem ganzen restlichen Kram, den du noch realisieren willst), einen Punkt hast, der dir dein ganzes Konzept zum Einsturz bringen wird! Und zwar die zum Login benötigten Daten!
User sind faul. Sie wählen sich Passworte, die man leicht raten kann. Sie haben auch Usernamen, die nicht schwer herauszufinden sind. Wer also ein Login realisieren kann, indem er einen gültigen Usernamen und Passwort eingibt, der wird deine restliche Sicherheitsbarriere ganz einfach überwinden können, weil sie für den eingeloggten User eben keine Barriere ist.
Dagegen kannst du im Prinzip nur etwas tun, indem du die Usernamen und insbesondere die Passworte ziemlich lang machst, um sie gegen Rateversuche zu schützen. Aber du kannst nichts dagegen tun, dass die Benutzer das Passwort möglicherweise ungeschützt mit sich herumtragen oder es sogar fremden Personen verraten!
Aber im Detail noch ein paar Kommentare:
Die erste Session-ID wird im Cookie gespeichert,
die zweite im Query-String.
Das zwei Session-IDs nicht sicherer sind als eine, sondern im Prinzip nur als eine lange Session-ID betrachtet werden können, hatte ich erwähnt. Es ist für den Angreifer auch kein Problem, die eine lange Session-ID in zwei Teile zu teilen und den einen als URL-Parameter, den anderen als Cookie an deinen Server zu senden.
Weiters werden in der Datenbank die IP-Adresse gespeichert,
sowie Referrer und Browser des Users.
Referrer und Browser des Users sind ebenfalls Daten, die der Angreifer sich selbst aussuchen und manipulieren kann. Es ist im Prinzip eine Verlängerung der Session-ID, nur leider: Die IP kann sich ohne Zutun des Benutzers ändern. Deswegen ist deine Lösung in diesem Punkt schlecht.
Wenn sich der User dann weiter durchklicken will auf der Homepage,
und auch nur ein Wert passt nicht,
wird er sofort ausgeloggt!!
Und das wird die User ziemlich ärgern, wenn das häufiger passiert.
Bei jedem Mal, wo der User auf irgendeinen Link klickt,
wird - nachdem gecheckt wurde ob alle Daten passen -
sofort wieder eine neue Session-ID für den Cookie
und eine weitere für den Querystring erzeugt.
Das widerspricht dem System der Sessions. Eine Session-ID bleibt über die gesamte Dauer identisch, damit man den User wiedererkennen kann.
Weiters kommt SSL zum einsatz.
Das ist sehr positiv.
Viele Leute meinten bisher schon,
dass mich das vor "the man in the middle" auch nicht beschützt,
und generell nicht sicher sei.
Auf diese Leute solltest du dann einfach nicht hören.
Natürlich gibt es keine absolute Sicherheit. Aber nach meiner Meinung ist eine hinreichend lange Session-ID zusammen mit SSL vollkommen ausreichend.
Begründung: SSL selbst liefert dir eine gesicherte Verbindung zum Server. Diese Verbindung ist gegen Man-in-the-middle-Attacken gesichert! Niemand kann, ohne dem Benutzer aufzufallen (weil das Zertifikat seines Servers ein anderes ist als deins) unter _deinem_ Servernamen Dienste anbieten, die so aussehen wie deine, und damit Logindaten abgreifen. Mit SSL kannst du hinreichend sicher sein, dass niemand an diese Daten rankommt, außer der Benutzer und du.
Zweitens: Die übliche Session-ID-Länge beträgt 128 Bit (jedenfalls bei PHP). Verwendet wird (hoffentlich) ein Zufallswert. Das bedeutet: Die Login-Daten werden eingetauscht gegen eine Session-ID, die danach als Authentifizierungsmittel dient. Wer die ID kennt, gilt als eingeloggt.
Man muß also entweder Username und Passwort richtig raten, oder die Session-ID. Gehen wir mal davon aus, dass die Session-ID geraten werden soll. Ich hatte eine Überschlagrechnung unter anderem mal in </archiv/2002/6/13365/#m75077> gemacht - die sollte dich doch eigentlich überzeugen, dass 128 Bit Session-ID-Länge ausreichend sein dürften, oder?
Als absolute Alternativ-Methode stünde noch
das CPAN-Modul "CGI::Session" zur verfügung.
Das ist sicher eine gute Idee. Denn das Modul generiert mindestens so gute Session-IDs wie du, wahrscheinlich aber bessere, weil zufälligere.
- Sven Rautenberg
--
ss:) zu:) ls:[ fo:} de:] va:) ch:] sh:) n4:# rl:| br:< js:| ie:( fl:( mo:|