DOC
Accueil/ Projets/ MJY Task Platform/ ADR 0007 : Pepper serveur pour dériver les mots de passe PIN (v2)

ADR 0007 : Pepper serveur pour dériver les mots de passe PIN (v2)

  • Statut : Proposé (planifié pour une v2 - sprint ultérieur)
  • Décideurs : Marco (Commanditaire), Julien (Commanditaire), Seer (Développeur)
  • Date : 8 juillet 2026

Contexte et Problème

L'ADR 0006 a livré la sécurité de connexion de la v1 : suffixe de remplissage centralisé (lib/pinPassword.js) + rate limiting. Deux limites subsistent :

  1. Le suffixe n'ajoute aucune sécurité : il est constant et assemblé côté navigateur (le changement de PIN se fait via supabase.auth.updateUser dans le client), donc public.
  2. En cas de fuite de la base d'authentification, les hachages bcrypt d'un PIN à 4 chiffres restent cassables hors-ligne (10 000 combinaisons), sans limite d'essais possible.

On veut protéger les hachages même dans ce scénario de fuite, ce que ni le suffixe ni le rate limiting (qui n'agit qu'en ligne) ne permettent.

Facteurs de Décision

  • Résistance à une fuite de base : les hachages ne doivent pas être exploitables sans un secret serveur.
  • Secret réellement caché : le facteur secret ne doit jamais être livré au navigateur.
  • Migration maîtrisée : conversion des comptes existants sans casser les connexions.

Options Envisagées

Option A : Statu quo (suffixe + rate limiting seuls)

  • Avantage : rien à faire.
  • Inconvénient : hachages cassables hors-ligne en cas de fuite de base.

Option B : Pepper côté client

Mélanger le PIN à un secret embarqué dans le front.

  • Avantage : pas de backend supplémentaire pour le changement de PIN.
  • Inconvénient : rejeté - tout ce qui est dans le bundle est public ; équivaut au suffixe actuel.

Option C : Pepper serveur (HMAC) + opérations mot de passe côté serveur (Recommandée)

Mot de passe stocké = HMAC_SHA256(pin, PIN_PEPPER), où PIN_PEPPER est une variable d'environnement serveur uniquement (jamais préfixée VITE_). Implique de déplacer toutes les opérations mot de passe côté serveur :

  1. nouvel endpoint POST /api/change-pin (dans lib/authBackend.js + server.js + netlify/functions/change-pin.js), vérifiant le jeton de session ;
  2. bascule de authService.changePin / ChangePinModal vers cet endpoint ;
  3. remplacement de l'implémentation de pinToPassword dans le seul fichier lib/pinPassword.js ;
  4. migration des comptes via npm run reset:pins ;
  5. durcissement du rate limiting en compteur persistant (table login_attempts ou colonnes sur member) pour couvrir le serverless.
  • Avantage : en cas de fuite de base, hachages inexploitables sans le pepper ; centralisation déjà en place facilite le point 3.
  • Inconvénient : nécessite un endpoint serveur de changement de PIN et une migration ; le changement de PIN dépend désormais du backend.

Décision Retenue

L'Option C : pepper serveur (HMAC) est retenue pour une v2 (statut Proposé, non implémentée en v1).

Justification

C'est la seule option qui protège les hachages contre une fuite de base. Elle n'a de sens que si le changement de PIN passe côté serveur (sinon le pepper fuite dans le bundle, comme le suffixe). La v1 a volontairement centralisé pinToPassword pour que ce basculement soit un changement localisé.

Conséquences

Positives

  • Hachages résistants à une fuite de la base d'authentification.
  • Le secret (PIN_PEPPER) reste strictement serveur.
  • Occasion de rendre le rate limiting persistant (robuste en serverless).

Négatives

  • Développement d'un endpoint /api/change-pin + refonte du flux client de changement de PIN.
  • Migration obligatoire de tous les mots de passe (rejouer reset:pins) ; sans elle, plus aucune connexion.
  • Dépendance accrue au backend pour les opérations d'authentification.