fix(security): consolidation & securite phase 1 (#84, BUG-021 a BUG-034)
- sanitizer XSS serveur (markdown + page de partage) [BUG-021/022] - rate-limit/lockout MFA [BUG-023] - isolation vaults par segments [BUG-024] - caps regex ReDoS [BUG-025] - SSRF webhooks + secrets externalises [BUG-026] - rotation/revocation des jetons [BUG-027] - politique de mot de passe + invalidation sessions [BUG-028] - verrous users.json [BUG-029] - IP reelle dans les audits [BUG-030] - rate-limit par compte [BUG-031] - symlinks hors vault ignores [BUG-032] - recherche simple via inverted index [BUG-033] - token en memoire + cookie HttpOnly, CSP durcie [BUG-034] Tests: pytest 961 passed / 6 skipped, ruff 0, mypy 0, frontend vert.
This commit is contained in:
@@ -12,6 +12,46 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Sécurité
|
||||
|
||||
- **#84 Consolidation & sécurité — phase 1 (BUG-021 → BUG-034)** — traitement des
|
||||
vulnérabilités de la revue statique du 2026-09-13 :
|
||||
- **BUG-021/022 — XSS stocké** : nouveau sanitizer serveur en liste blanche
|
||||
(`backend/services/sanitizer.py`, stdlib) appliqué au rendu markdown ; échappement
|
||||
systématique du `title`, du frontmatter et du JSON de la page publique `/s/{token}`
|
||||
(`</script>` neutralisé). Tests : `tests/test_security_hardening.py` (9).
|
||||
- **BUG-023 — brute-force MFA** : rate-limit IP + compte et verrouillage de compte sur
|
||||
`mfa/totp/verify`, `mfa/recovery` et `mfa/webauthn/verify` (`_enforce_mfa_rate_limit`).
|
||||
- **BUG-024 — traversal inter-vaults** : `resolve_safe_path` compare désormais les chemins
|
||||
par **segment** (`Path.relative_to` + repli casse-insensible), plus par préfixe de chaîne :
|
||||
`vault` ne peut plus lire `vault-evil`.
|
||||
- **BUG-025 — ReDoS** : validation des regex utilisateur (longueur max, rejet des
|
||||
quantificateurs imbriqués/backrefs), contenu tronqué et nombre de matchs plafonné
|
||||
(`backend/services/regex_safety.py`), appliqué à la recherche avancée et au find/replace.
|
||||
- **BUG-026 — SSRF webhooks** : validation d'URL (HTTPS par défaut, IP privées/boucle
|
||||
interdites, résolution DNS vérifiée au dispatch, redirections non suivies) et
|
||||
**externalisation du secret** dans `data/webhook_secrets.json` (0600) ou variable
|
||||
`OBSIGATE_WEBHOOK_SECRET_<ID>` (plus de secret en clair dans `webhooks.json`).
|
||||
- **BUG-027 — sessions** : rotation du refresh token à chaque usage, révocation du JTI de
|
||||
l'access token au logout, et vérification de la révocation dans le middleware.
|
||||
- **BUG-028 — politique de mot de passe** : validation centralisée (8–128 caractères) à la
|
||||
création, à la modification admin et au changement ; `password_changed_at` invalide tous
|
||||
les jetons émis avant un changement de mot de passe.
|
||||
- **BUG-029 — race `users.json`** : verrou `threading.RLock` autour des cycles
|
||||
lecture-modification-écriture.
|
||||
- **BUG-030 — audits** : l'adresse IP réelle du client (`X-Forwarded-For` si
|
||||
`OBSIGATE_TRUST_PROXY=true`) est injectée dans `current_user` et consignée dans les audits.
|
||||
- **BUG-031 — rate-limiter** : budget **par compte** en plus du budget par IP (rotation d'IP
|
||||
neutralisée) ; limite mono-process documentée.
|
||||
- **BUG-032 — indexation** : `_scan_vault` utilise `os.walk(followlinks=False)` et refuse
|
||||
tout symlink sortant de la racine du vault.
|
||||
- **BUG-033 — recherche O(N)** : la recherche simple et l'outil IA `search_fulltext`
|
||||
utilisent l'inverted index (repli sur le scan pendant la construction).
|
||||
- **BUG-034 — CSP & jetons** : le token d'accès n'est plus persisté dans `sessionStorage`
|
||||
(mémoire + cookie `HttpOnly`) ; directives CSP durcies (`object-src`, `base-uri`,
|
||||
`form-action`, `frame-ancestors`). *Reste : migration CSP par nonce (exige la conversion
|
||||
des gestionnaires d'événements inline).*
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **#82 Assistant IA — menu `@` instantané** — nouvel endpoint `GET /api/vault/{vault}/paths`
|
||||
|
||||
Reference in New Issue
Block a user