xpeditis2.0/audit_security/sessions-apres-reset-mot-de-passe/sessions-apres-reset-mot-de-passe.md

63 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SEC-08 — Le changement de mot de passe conserve les anciennes sessions
**Gravité historique : Moyenne.** Classification : CWE-613.
**État au 14 septembre 2026 :** Corrigé dans le code suivi. Access et refresh portent une `credentialVersion` calculée par HMAC sur l'identifiant et le hash courant du mot de passe, sous JWT_SECRET. `validateUser` recalcule cette valeur ; un changement de hash invalide les anciennes sessions. Le hash du mot de passe n'est pas publié dans le JWT. Les anciens tokens sans ce champ nécessitent une nouvelle connexion.
## Executive Summary
Un attaquant possède déjà un refresh token volé avant que la victime réinitialise son mot de passe. Le problème concerne la sortie d'un incident de session compromise, pas la robustesse du générateur de token de réinitialisation.
Cette fiche repose sur la relecture du code historique accessible et du correctif courant, ainsi que des preuves documentées lors des passes précédentes. Elle ne constate aucun incident réel. La plus ancienne version ici vérifiée est le snapshot `8446f87` ; les corrections historiques figurent dans `c09b8be`. Aucun tag local ni version déployée n'a permis d'établir une première release vulnérable ou corrigée. Voir [METHODOLOGIE.md](../METHODOLOGIE.md).
## Background
La récupération du compte remplace le credential de connexion. Les sessions déjà émises doivent être évaluées par rapport à cette nouvelle version, sans confondre ce contrôle avec la validation du lien de récupération.
## Vulnerability Details
`resetPassword` vérifie le token de récupération, son hash, sa date d'expiration et son usage, puis remplace le hash du mot de passe. `refreshAccessToken` vérifiait seulement signature, type refresh, blacklist de déconnexion et utilisateur actif. Aucun lien n'existait entre le jeton précédent et le nouveau credential. Un refresh antérieur encore valide pouvait donc produire de nouveaux tokens après récupération du compte. Les contrôles sur le lien de réinitialisation ne répondent pas à cette révocation de session.
Extrait historique vérifié, `apps/backend/src/application/auth/auth.service.ts`, lignes 386–392 du snapshot préaudit :
```typescript
// Update password (mutates in place)
user.updatePassword(passwordHash);
await this.userRepository.save(user);
// Mark token as used
await this.passwordResetTokenRepository.update({ id: resetToken.id }, { usedAt: new Date() });
```
Les numéros ci-dessus décrivent le snapshot ancien ; les liens suivants ouvrent les fichiers courants, où les lignes peuvent avoir changé.
Sources à examiner ensemble :
- [apps/backend/src/application/auth/auth.service.ts](../../apps/backend/src/application/auth/auth.service.ts)
- [apps/backend/src/domain/entities/user.entity.ts](../../apps/backend/src/domain/entities/user.entity.ts)
## Exploitability Analysis
Maintien de l'accès déjà compromis malgré un changement de mot de passe réussi ; le renouvellement peut prolonger cet accès. Cela ne démontre pas comment le premier token a été volé, ni un contournement des contrôles du lien de reset. L'impact dépend de la durée de validité et de l'absence d'une révocation distincte.
Le code applicatif établit le chemin décrit, mais ne renseigne pas les protections effectives d'un déploiement donné, sa version en ligne ou les accès déjà exercés par un attaquant. La gravité ci-dessus est celle du mécanisme vulnérable avant correction ; elle n'est pas un score de risque résiduel calculé pour la production.
## Proof of Concept
Tests de non-régression existants, inspectables dans le dépôt :
- [apps/backend/src/application/auth/auth-session.spec.ts](../../apps/backend/src/application/auth/auth-session.spec.ts)
Ils testent les refus et les usages autorisés avec des données locales. Ils ne prouvent pas qu'une ancienne exploitation a eu lieu en production. Les commandes et résultats consolidés sont dans [VALIDATION.md](../VALIDATION.md) ; aucun nouvel exploit n'a été exécuté pendant la rédaction.
## Remediation
Corrigé dans le code suivi. Access et refresh portent une `credentialVersion` calculée par HMAC sur l'identifiant et le hash courant du mot de passe, sous JWT_SECRET. `validateUser` recalcule cette valeur ; un changement de hash invalide les anciennes sessions. Le hash du mot de passe n'est pas publié dans le JWT. Les anciens tokens sans ce champ nécessitent une nouvelle connexion.
Pour solder le constat en exploitation, vérifier le comportement sur la version effectivement déployée et conserver les contrôles légitimes décrits. La présente passe ajoute uniquement de la documentation ; les correctifs mentionnés existaient avant sa rédaction.
## Summary
Le changement de mot de passe conserve les anciennes sessions est un constat historique de l'audit, à lire avec son état courant ci-dessus. La preuve porte sur le mécanisme et les contrôles cités ; elle ne constitue ni une attestation d'exploitation réelle ni une certification exhaustive du projet.