diff --git a/CODE_AUDIT.md b/CODE_AUDIT.md index edf2c0d..67c2826 100644 --- a/CODE_AUDIT.md +++ b/CODE_AUDIT.md @@ -615,6 +615,13 @@ sous newKey*. C'est le filet qui aurait attrapé ça. ### 6c-2. 🟠 Expiry de session écrite en local, lue en UTC (corrige §2.2) +> ✅ **RÉSOLU 2026-07-16.** `CreateSession` écrit `IncHour(NowUTC, 24)` et +> `Authenticate` compare `LExpires < NowUTC` ([PM.Session.pas](delphi-backend/Source/PM.Session.pas)). +> Les 3 lecteurs (Authenticate, RequireCSRF, CleanupExpired) sont désormais tous +> sur UTC. `NowUTC` + `System.DateUtils` déjà dans les uses → aucun uses touché. +> §2.2 est maintenant réellement clos (c'était le dernier `FormatDateTime(..., +> Now)` du backend). Sessions existantes : expirent sous 24 h, purgées au boot. + [`CreateSession`](delphi-backend/Source/PM.Session.pas:155) écrit `FormatDateTime('yyyy-mm-dd hh:nn:ss', IncHour(Now, 24))` — heure **locale**. C'est le dernier `FormatDateTime(..., Now)` du backend et il contredit la règle diff --git a/delphi-backend/Source/PM.Session.pas b/delphi-backend/Source/PM.Session.pas index 8ea2f7c..57549ad 100644 --- a/delphi-backend/Source/PM.Session.pas +++ b/delphi-backend/Source/PM.Session.pas @@ -86,7 +86,8 @@ begin LQ.Free; end; - if (LExpires <> 0) and (LExpires < Now) then + // expires_at is now UTC (see CreateSession) — compare against UTC too. + if (LExpires <> 0) and (LExpires < NowUTC) then begin DeleteSessionByTokenHash(LTokenHash); TJSONHelper.SendError(AResponse, 401, 'Session expired'); @@ -152,7 +153,11 @@ begin ACSRFToken := RandomHex(32); LTokenHash := SHA256Hex(AToken); // YYYY-MM-DD HH:NN:SS, +24h, server local time (api.php uses date() = local) - LExpires := FormatDateTime('yyyy-mm-dd hh:nn:ss', IncHour(Now, 24)); + // UTC like everywhere else — RequireCSRF + CleanupExpired compare against + // SQLite datetime('now') which IS UTC. Writing local here made the CSRF + // window fall short on negative-offset zones (§6c-2): "Invalid CSRF token" + // on writes while GETs still authed. + LExpires := FormatDateTime('yyyy-mm-dd hh:nn:ss', IncHour(NowUTC, 24)); DB.Lock; try