Aller au contenu

Analyse 2FA — gestionFichePaie

Date : 2026-06-20
Projet : /home/kanmaber/projets/gestionFichePaie


Ce qui est implémenté

Backend — complet et bien structuré

  • Service2FA : TOTP via speakeasy (génération secret, QR code, validation), code email (crypto.randomInt), backup codes générés et hashés via bcrypt
  • Use cases :
  • Generer2FASecretUseCase — génère le secret TOTP + QR code, stocke 10 backup codes en base
  • Activer2FAUseCase — active le 2FA (méthode EMAIL ou APPLICATION/TOTP), vérifie le code, sauvegarde backup codes
  • Verifier2FAUseCase — vérifie le code pendant la connexion (EMAIL ou TOTP), convertit session temporaire → session définitive + JWT
  • Desactiver2FAUseCase — désactive le 2FA
  • EnvoyerCode2FAUseCase — envoie le code par email
  • VerifierBackupCodeUseCase — vérifie un code de récupération (bcrypt compare)
  • GenererBackupCodesUseCase — régénère de nouveaux codes de secours
  • Routes protégées avec rate limiting sur /verify et /send-code
  • Compteur de tentatives : max 5, invalidation session au dépassement
  • Session temporaire → session définitive + JWT à la vérification réussie
  • Audit systématique de toutes les vérifications (règle #7 Caritas)
  • Type2FA enum : EMAIL, TOTP, SMS (shared-kernel)
  • MethodeDeuxFacteurs Prisma : EMAIL, APPLICATION

Frontend — flux complet

  • Store Zustand : requires2FA, requires2FAConfiguration, twoFactorSessionData
  • TwoFactorPage : page de saisie du code lors de la connexion
  • TwoFactorSetupPage : choix EMAIL ou TOTP au premier login — bouton "Configurer plus tard" qui redirige vers /dashboard sans configurer
  • TwoFactorForm : 6 inputs séparés, mode backup code, renvoi de code EMAIL avec cooldown 60s et appel API réel (twoFactorApi.sendCode())
  • TwoFactorSettingsPage : page de paramétrage dans les préférences

Ce qui manque ou est cassé

1. 🔴 CRITIQUE — Le backup code ne complète pas la connexion

VerifierBackupCodeUseCase retourne { succes: boolean, codeValide: boolean }sans JWT. Dans le store frontend, verifyBackupCode retourne un boolean sans setter isAuthenticated: true ni stocker les tokens. Un utilisateur qui saisit un backup code valide valide le code mais reste déconnecté et ne peut pas accéder à l'application.

2. 🔴 CRITIQUE — Le "Configurer plus tard" bypass le 2FA obligatoire

TwoFactorSetupPage.tsx:81 : handleSkip → navigate('/dashboard'). Si le backend signale requires2FAConfiguration: true, le frontend redirige vers /auth/2fa-setup, mais rien n'empêche de cliquer "Configurer plus tard" et accéder au dashboard sans jamais configurer le 2FA. Aucun garde côté backend pour bloquer l'accès aux routes protégées en l'absence de 2FA configuré.

3. 🟠 Backup codes créés avant activation (orphelins)

Dans Generer2FASecretUseCase (étape 7, lignes 89-98), les backup codes sont hashés et sauvegardés en base au moment de la génération du secret TOTP — avant même que l'utilisateur scanne et confirme. Si l'utilisateur abandonne la configuration, des backup codes orphelins restent en base.

De plus, Activer2FAUseCase crée un second jeu de 10 backup codes pour la méthode EMAIL. Un même utilisateur peut accumuler plusieurs jeux de backup codes actifs en base.

4. 🟠 Logs de debug en code de production

  • Activer2FAUseCase.ts:122-131 : console.log('[ACTIVER 2FA - DEBUG CODE]', { codeDB, codeSaisi }) — logue le code de vérification en clair
  • Activer2FAUseCase.ts:178-183 : logue le préfixe du secret TOTP
  • Verifier2FAUseCase.ts:451-456 : logue codeValue (le code TOTP saisi par l'utilisateur) dans les logs serveur

5. 🟡 Secret TOTP stocké en clair en base

deuxFacteursSecret String? dans le schéma Prisma — le secret TOTP n'est pas chiffré au repos. Si la base de données est compromise, tous les secrets TOTP sont exposés en clair.

6. 🟡 SMS déclaré mais non implémenté

Type2FA.SMS = 'SMS' existe dans shared-kernel/src/domain/enums/Type2FA.ts, mais : - L'enum Prisma MethodeDeuxFacteurs n'a que EMAIL et APPLICATION - Aucun ServiceSMS, aucune logique d'envoi dans aucun use case - Enum mort / trompeur

7. ⚪ "Se souvenir de cet appareil" absent

2FA exigé à chaque connexion sans exception. deviceId apparaît dans quelques schémas Zod mais n'est pas exploité.


Résumé des priorités

Priorité Problème
🔴 Bloquant Backup code ne connecte pas l'utilisateur
🔴 Bloquant Setup 2FA contournable avec "Configurer plus tard"
🟠 Important Backup codes dupliqués / orphelins en base
🟠 Important Logs de debug exposent codes et secrets en prod
🟡 Secondaire Secret TOTP non chiffré en base
🟡 Secondaire SMS déclaré mais non implémenté (à retirer ou implémenter)
⚪ Amélioration "Se souvenir de cet appareil"