Eine einfachere Variante wäre wohl auch noch:
login.php
- Prüfen von Benutzernamen und Passwort (salted Password)
- Setze Session -> Session-Cookie: HTTP Only
- Speichere aktuellen Timestamp in $ts
- Schreibe $uid = uniqid() in Datenbank: user_session_salt
- Schreibe md5($ts . $uid) in Datenbank: user_session_uniqid
- Schreibe Cookie mit inhalt $ts (Cookie-Name: "data")
index.php
- Prüfe Session und hole Benutzerdaten
- Prüfe ob: md5( $_COOKIE['data'] . user_session_salt ) == user_session_uniqid
- Wenn nein: Sessions zerstören, alles löschen
- Wenn ja: Dann setze neue neuen Timestamp in Cookie und generiere neue user_session_uniqid mit diesem Timestamp
- Zeige Seite im eingeloggten Zustand
logout.php
- Zerstöre Session
- Lösche Salt und Code aus DB
Ich glaub diese Routine ist sinnvoller, da das Problem mit setcookie gelöst ist und XSS trotzdem sinnlos ist, da man ohne den Salt, der nur beim Loginmechanismus generiert wird auch mit dem Cookie nicht weiter kommt, zumindest wenn der Benutzer nicht eingeloggt ist... - und wenn er eingeloggt ist wird sowieso bei jedem Seitenaufruf ein neuner TS generiert
EDIT:
Man könnte am Seitenende Javascript den aktuellsten TS ($ts_new) der PHP Datei übergeben, JS einen neuen Cookie setzen lassen, und am Ende der PHP Datei den Timestamp so in die Datenbank schreiben - das würde (dank der Tatsache, dass JS alles nach der Reihe abarbeitet) verhindern, dass man per XSS den neuen Timestamp auslesen kann, sofern nach dem letzten Javascript keine GET oder POST ausgegeben werden - dann hat man aber wieder das Problem, dass HTTP only im Weg steht - ist die Frage, was sicherer ist...
EDIT 2:
Ok, ein Timestamp wäre eig idiotisch, denn wenn man die Sessid "gehijacked" hat muss man nur mehr auf gut Glück alle Timestamps durchrennen - Uniqid würde in dem Fall auch salt ersparen