auth: security audit fixes, rate limits on every route
Two separate reviews of the SSO branch and all 207 API routes (spec 12 §8.6). Every route was guarded as meant. Fixed, each with a test: - login: a directory 503 counts as a failed sign-in; a locked directory account is a refused password, not "unavailable" - open redirect after OpenID sign-in (a tab in next) - directory email matching only for non-admins without their own password; others connect on My settings (POST /api/me/identities/ldap); only admins disconnect a directory account - OpenID session check reads the refreshed ID token's claims too - connect is POST /api/auth/oidc/connect (CSRF header) - stored bind password, client secret and SMTP password tied to their server - 409 role_managed when a provider sets the role; empty Contrack PATCH is a 400 - @fastify/rate-limit on every route (RATE_LIMIT_PER_MINUTE), 10/min on Test buttons; a password asked again shares the login limiter Live tests pass against lldap 0.6.3, Samba 4 AD and Keycloak 26.8.1.
This commit is contained in:
1 parent
19610777a4
commit
97e67e347d
39 files changed
+1059
-186
No files matched your search
@@ -33,7 +33,12 @@
|
||||
- **CSRF:** every non-GET `/api/*` request with cookie auth must carry the header
|
||||
`X-Requested-With: selfphoneng`. The web client always sends it. Browsers can't send
|
||||
it cross-site without CORS, and CORS is off.
|
||||
- Login rate limit: 5 failures per IP per 15 min and 10 per email per hour → HTTP 429.
|
||||
- Login rate limit: 5 failures per IP per 15 min and 10 per email per hour → HTTP 429. A signed-in
|
||||
person's password asked again (change password, two-step on/off, recovery codes) counts the same.
|
||||
- Every route: `@fastify/rate-limit`, `RATE_LIMIT_PER_MINUTE` (default 600) per client IP → 429
|
||||
`rate_limited`. Test buttons, diagnostics and the source download: 10 a minute (`SLOW` in
|
||||
`auth/guards.ts`). `/prov` (its own limits, 07 §2) and the caller-name route (Asterisk on this
|
||||
machine) are outside it (`NO_LIMIT`).
|
||||
Write `login_failed` to the audit log with the IP.
|
||||
- If `must_change_password`, every route except `/api/auth/*` returns 403 `{code:'password_change_required'}`.
|
||||
- Single sign-on (spec 12, as built in S1): the body is `{login, password, totp?}` (`login`: email, or a
|
||||
|
||||
Reference in new issue
Block a user