mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-09-25 01:53:03 +02:00
feat: enforce idle + absolute timeouts on admin session
This commit is contained in:
@@ -16,10 +16,52 @@ Current security posture for XAMXAM.
|
||||
- `AdminAuth::requireLogin()` guards every admin action/route.
|
||||
- Session cookies hardened: `HttpOnly`, `SameSite=Strict`, `Secure`,
|
||||
`Path=/admin`; regenerated on login.
|
||||
- **Session timeouts** (server-side, enforced by `AdminAuth::enforceSessionTimeout()`
|
||||
on every gated request):
|
||||
- **Idle timeout** — 30 min without activity → session destroyed, redirected
|
||||
to login.
|
||||
- **Absolute timeout** — 12 h since login → forced re-login, regardless of
|
||||
activity.
|
||||
- Session ID rotated periodically (every 30 min) to limit fixation/replay.
|
||||
- The session *cookie* `lifetime` is 7 days, but that is only an upper bound
|
||||
on browser retention — the actual session is bounded by the two timeouts above.
|
||||
- **PHP-FPM session GC tuning** — see below. The app enforces its own timeouts,
|
||||
so `session.gc_maxlifetime` must be ≥ the 12 h absolute timeout or PHP would
|
||||
reap active sessions early.
|
||||
- nginx `auth_basic` layer has been removed; the PHP session layer is the only
|
||||
gate. (LDAP-based login is a proposed future enhancement — see
|
||||
[`ldap.md`](ldap.md). It is **not** implemented.)
|
||||
|
||||
### PHP-FPM session GC configuration
|
||||
|
||||
The admin session's lifetime is enforced *by the app* (the timeouts above), so
|
||||
PHP's own session garbage collector must not reap active sessions before the
|
||||
12 h absolute timeout. The following is provisioned by
|
||||
`scripts/deploy-server.sh` (run via `just deploy-nginx`):
|
||||
|
||||
**File:** `/etc/php/8.4/fpm/conf.d/zz-xamxam-session.ini`
|
||||
|
||||
```ini
|
||||
; XAMXAM session tuning.
|
||||
; AdminAuth enforces its own idle/absolute timeouts (30 min / 12 h), so
|
||||
; gc_maxlifetime must be >= the absolute timeout or PHP would reap active
|
||||
; sessions from under the app.
|
||||
session.gc_maxlifetime = 43200
|
||||
session.gc_probability = 1
|
||||
session.gc_divisor = 100
|
||||
```
|
||||
|
||||
- `gc_maxlifetime = 43200` (12 h) — matches `ABSOLUTE_TIMEOUT_SECONDS`;
|
||||
**must stay ≥ the app's absolute timeout**.
|
||||
- `gc_probability = 1` / `gc_divisor = 100` — re-enables the GC (default was
|
||||
`gc_probability = 0`, i.e. disabled, so stale session files were never reaped).
|
||||
- Applied on FPM reload (`systemctl reload php8.4-fpm`), done by the deploy script.
|
||||
|
||||
> ⚠️ Keep these three knobs in sync with the constants in
|
||||
> `app/src/AdminAuth.php` (`IDLE_TIMEOUT_SECONDS`, `ABSOLUTE_TIMEOUT_SECONDS`,
|
||||
> `COOKIE_LIFETIME_SECONDS`). If you raise the app's absolute timeout beyond
|
||||
> 12 h, raise `gc_maxlifetime` to match.
|
||||
|
||||
## Transport & headers
|
||||
|
||||
Enforced in `nginx/xamxam.conf` (see `nginx/docs/SECURITY_HEADERS.md`):
|
||||
|
||||
Reference in New Issue
Block a user