Application web d'inventaire réseau manuel avec FastAPI, Vue 3 et Docker. Inclut l'authentification JWT, la découverte ICMP, et la topologie en cards CSS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.0 KiB
Security Fixes Applied
Date: 2026-05-06
P0-001 — SEC-FIX-001 : Changement de mot de passe obligatoire au premier login
Problème
Le compte admin par défaut utilisait admin/admin. N'importe qui ayant accès au port 8080 pouvait se connecter.
Changements
backend/models.py
- Colonne
must_change_password BOOLEAN NOT NULL DEFAULT 0ajoutée surUser.
backend/main.py
- Nouvelle migration idempotente
_migrate_users_must_change_password()—ALTER TABLE users ADD COLUMN must_change_password BOOLEAN NOT NULL DEFAULT 0si absente. _migrate_users(): support de la variable d'environnementINITIAL_ADMIN_PASSWORD.- Si définie → mot de passe fourni,
must_change_password = 0. - Sinon → mot de passe
admin,must_change_password = 1(changement forcé au premier login).
- Si définie → mot de passe fourni,
- Routeurs
vlans,devices,links,discoveryprotégés parrequire_password_changedau lieu deget_current_user.
backend/routers/auth.py
- Dépendance
require_password_changed: retourne 403"Password change required"simust_change_password = 1. TokenOutenrichi du champmust_change_password: bool.login()retournemust_change_password.update_account()passemust_change_passwordàFalseaprès changement de mot de passe réussi.GET /meretournemust_change_password.
frontend/src/auth.js
- Ref
_mustChangepersistée danslocalStorage('auth_mustchange'). mustChangePasswordcomputed exporté.setAuth(token, username, mustChange)/clearAuth()mis à jour.
frontend/src/App.vue
- Branche
v-else-if="mustChangePassword": affiche<AccountModal :forced="true">avant l'application. onLoginetonAccountUpdatedpropagent le flag ;loadAlln'est appelé que simustChangePasswordest faux.onMountedconditionnel sur!mustChangePassword.value.
frontend/src/components/AccountModal.vue
- Prop
forced(Boolean, défautfalse) :- Masque le bouton ✕ et le bouton Annuler.
- Empêche la fermeture par clic sur l'overlay.
- Affiche une bannière d'avertissement.
- Rend le champ "Nouveau mot de passe" obligatoire.
frontend/src/i18n.js
- Clés ajoutées (fr/en/es) :
mustChangePasswordWarning,newPasswordRequired.
Utilisation
# docker-compose.yml — optionnel
environment:
- INITIAL_ADMIN_PASSWORD=MonMotDePasseSecurisé
Sans cette variable, le premier login avec admin/admin force immédiatement le changement de mot de passe.
P1-001 — SEC-FIX-002 : Rate limiting sur POST /api/auth/login
Problème
Aucune limitation du nombre de tentatives de connexion — brute-force possible.
Changements
frontend/rate_limit.conf (nouveau)
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
frontend/Dockerfile
COPY rate_limit.conf /etc/nginx/conf.d/00_rate_limit.conf— chargé en premier (ordre alphabétique).
frontend/nginx.conf
- Location spécifique
= /api/auth/loginaveclimit_req zone=login burst=5 nodelayetlimit_req_status 429.
backend/routers/auth.py
- Rate limiting in-memory (sans dépendance externe) :
- Par IP : 20 tentatives / 60 s
- Par username : 10 tentatives / 900 s (15 min)
- Compteurs réinitialisés après login réussi.
login()extrait l'IP viaRequest.client.host.- Retourne HTTP 429
"Too many attempts, try again later".
frontend/src/components/LoginPage.vue
- Gère le status 429 → affiche
t('tooManyAttempts').
frontend/src/i18n.js
- Clé ajoutée :
tooManyAttempts.
P1-002 — SEC-FIX-003 : Validation serveur des entrées sur PUT /api/auth/account
Problème
Aucune validation sur new_username et new_password — mots de passe vides ou noms d'utilisateurs invalides acceptés.
Changements
backend/routers/auth.py
_validate_new_password(password): min 8 caractères, au moins une lettre et un chiffre. Lève 400 avec codepassword_too_shortoupassword_too_weak._validate_new_username(username):[a-zA-Z0-9._-]{1,64}. Lève 400 avec codeusername_invalid.update_account()appelle ces fonctions avant modification.
frontend/src/components/AccountModal.vue
- Validation client miroir (évite un aller-retour réseau pour les cas évidents).
- Mapping des codes d'erreur backend → clés i18n :
password_too_short,password_too_weak,username_invalid.
frontend/src/i18n.js
- Clés ajoutées (fr/en/es) :
passwordTooShort,passwordTooWeak,usernameInvalid.
Fichiers modifiés
| Fichier | Fixes |
|---|---|
backend/models.py |
P0-001 |
backend/main.py |
P0-001 |
backend/routers/auth.py |
P0-001, P1-001, P1-002 |
frontend/rate_limit.conf |
P1-001 (nouveau) |
frontend/Dockerfile |
P1-001 |
frontend/nginx.conf |
P1-001 |
frontend/src/auth.js |
P0-001 |
frontend/src/i18n.js |
P0-001, P1-001, P1-002 |
frontend/src/App.vue |
P0-001 |
frontend/src/components/LoginPage.vue |
P0-001, P1-001 |
frontend/src/components/AccountModal.vue |
P0-001, P1-002 |