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 :
- Le suffixe n'ajoute aucune sécurité : il est constant et assemblé côté navigateur (le changement de PIN se fait via
supabase.auth.updateUserdans le client), donc public. - 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 :
- nouvel endpoint
POST /api/change-pin(danslib/authBackend.js+server.js+netlify/functions/change-pin.js), vérifiant le jeton de session ; - bascule de
authService.changePin/ChangePinModalvers cet endpoint ; - remplacement de l'implémentation de
pinToPassworddans le seul fichierlib/pinPassword.js; - migration des comptes via
npm run reset:pins; - durcissement du rate limiting en compteur persistant (table
login_attemptsou colonnes surmember) 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.
