Hi Sabine,
Ach ja - da sind wir ja schon - eigenen also.
Hineinspringen wird schwieriger je mehr Infos ich
vom User hineinpacken und kontrollieren kann - sehe
ich das richtig nach deinen Ausführungen?
Ja, auch - aber vor allem auch dann, wenn der Benutzer diese Informationen nicht so ohne weiteres fälschen kann (deshalb die HTTP-Header).
Wenn er "nur" eine Session-ID erraten muß, kann er einen normalen Browser nehmen - muß er auch noch konsistente Informationen erzeugen, dann muß er dafür ein Programm schreiben (oder installieren, falls irgend ein WebWasher so etwas bereits passend kann), welches den HTTP-Header explizit manipuliert.
Außerdem muß er, wenn er mehrere Hindernisse einzeln überwinden muß, erst mal von deren Existenz wissen ... wenn er beispielsweise die URLs auf Netz-Ebene oder durch einen Proxy-Server mit belauscht, wird er noch lange nicht in die Transaktion hinein springen können, falls diese URLs alleine über ihre eigene Konsistenz gar nicht genug aussagen.
Wenn dieses Programm dann auch noch mit Deinen womöglich JavaScript enthaltenden Seiten fertig werden muß, hast Du eine nette zusätzliche Hürde aufgebaut, die nicht mit brute force, sondern nur mit eigener Arbeit zu überwinden ist.
Jede Art der "Versicherung" lebt davon, sich den "Schadensfall" detailliert vorstellen zu können.
Das ist in Deinem Fall nicht anders: Je genauer Du weißt, wie ein Angreifer ungefähr arbeiten würde (und welche Information ihm dabei zur Verfügung steht), desto effektiver kannst Du ihm das Leben schwer machen.
Vielleicht brauchst Du wirklich in der Datenbank
ein vollständiges Protokoll aller HTTP-Requests
des Benutzers, welche Du über die Session-ID
exakt erkennen kannst - dann kannst Du beim
Eintreffen eines Requests mit einer "alten"
Session-ID alle Datenbankeinträge mit "neueren"
Session-IDs verwerfen und an der entsprechenden
Stelle weiter machen.
Mhh.... und was, wenn er dann wieder auf den Button
Vorwärts klickt?
Solange er noch nichts tut, was von dem bereits gespeicherten "Transaktions-Film" explizit abweicht, kannst Du seinen Timestamp als eine Art "Cursor" innerhalb dieses Films verwenden.
"Vor" und "Zurück" innerhalb der History verwenden jeweils nur Timestamps, die Du schon kennst.
Erst wenn er etwas tut, was einen neuen "Ereignis-Ast" aufmacht, wirst Du wohl oder übel den alten Ast absägen müssen ... es sei denn, Dein Transaktionslog ist ein Baum statt einer Liste ... dann müßte jeder Eintrag auch noch einen expliziten Vorgänger und Nachfolger haben, während bei einer Liste die sortierbaren Timestamps ausreichen. (Das wäre aber mehr, als der Browser selbst sinnvoll unterstützen würde - der kennt nur einen einzigen "Vorwärts"-Weg.)
Im Wesentlichen würdest Du also die Browser-History durch Navigation innerhalb Deines Transaktions-Logs serverseitig nachbilden - wobei Du dem Benutzer erlauben würdest, via URL mit timestamp an beliebige Stellen dieser History zu springen. (Er könnte ja auch eine bookmark verwendet haben oder was auch immer.)
Die Idee mit dem (nicht md5())-kodierten Timestamp
hat mich ein ordentliches Stück weitergebracht,
danke.
Nun drängt sich bei mir aber eine neue Frage auf
und ich würde mich sehr über deine Meinung dazu
freuen:
Ist es besser
a) Den User über SID + Timestamp durchzuführen
(mit Abfrage <= bei Timestamp), in ID noch
userspezifische Daten hinzuzufügen und das
verbleibende Restrisiko zu schlucken (IP ist ja
nicht sicher, kann also nur Daten einbinden, die
auch ein anderer haben könnte)
Je mehr Prüfsumme Du in die Session-ID mit einfügst, desto kleiner wird das Restrisiko.
Ich habe so etwas mal gebaut und den Timestamp selbst innerhalb der (decodierbaren) Session-ID gehalten ... da ich den Timestamp wieder extrahieren konnte, war ich beispielsweise auch in der Lage, diesen "veralten" zu lassen, also einen Zugriff nach mehr als <n> Sekunden nach Vergabe dieses time stamp abzuweisen (mit einer Meldung "sie haben mehr als <n> Sekunden keine Eingabe mehr vorgenommen - aus Sicherheitsgründen brechen wir Ihre Transaktion ab und führen Sie zurück zur Login-Seite" oder so ähnlich).
Je nachdem, welche Randbedingungen Deine Transaktion hat, wirst Du noch andere mehr oder weniger geeignete Konsistenz-Eigenschaften finden können.
b) Die einzelnen "abgelaufenen" Timestamps
zusätzlich in der Datenbank zu speichern und so
zusätzlich Abfragen/Erhöhung der Datenbankeinträge
zu akzeptieren (Ladezeit, Performance?)
Wenn Du den kompletten "Transaktionsfilm" speichern muß, damit Du an beliebigen Stellen aufsetzen kannst, brauchst Du ohnehin alle Timestamps - denn mit diesen erkennst Du ja die Position innerhalb des "Films" wieder.
Ist die Transaktion dagegen abgeschlossen (egal ob erfolgreich oder nicht), dann kannst Du Deine Infrastruktur (d. h. alle "Film-Einträge" mit dieser Session-ID) wieder abbauen, um die Tabelle aufzuräumen - für eine dauerhafte Archivierung brauchst Du zwar den Endzustand der Session, nicht aber deren Entstehungs-Historie.
Wobei Du den "Transaktionsfilm" möglicherweise in einer anderen Tabelle halten willst als das schlußendliche Protokoll der abgeschlossenen Transaktion - quasi in einem Cache innerhalb Deiner Datenbank, der nur die Einträge der laufenden Transaktionen enthält (so wie ein Rollback-Segment).
Viele Grüße
Michael