fix(auth): leurre anti-enumeration sur la demande de reset #26

Merged
Corentin merged 1 commit from fix/reset-enumeration-decoy into dev 2026-06-16 14:21:00 +02:00
Owner

Finding LOW (audit 2026-06-16)

PasswordResetService::requestReset repondait instantanement et sans ecriture sur un email inconnu, alors que le chemin email-connu fait : random_bytes(32) + sha256 + UPDATE user + envoi de mail. -> oracle de timing + de profil d'ecritures revelant l'existence d'un compte. Le commit P2 (#11) annoncait une parite anti-enumeration "PR-wide (timing + profil d'ecritures identique)" : vraie sur le login, pas sur le reset.

Correctif

  • payEnumerationDecoy() : sur email inconnu, reproduit le cout CPU (token CSPRNG + SHA-256) et une ecriture du chemin connu, mais ciblant id = 0 (aucune ligne, rien persiste). Aucun mail. Meme pattern que le leurre du login (UPDATE ... WHERE id = 0).
  • Tests unknown-email (service + controleur) : assertent desormais 1 ecriture leurre sur id = 0 + aucun mail (au lieu de 0 ecriture).

Suite 188 verte (451 assertions), PHPStan L6 propre. Pas de label auto-merge.

## Finding LOW (audit 2026-06-16) `PasswordResetService::requestReset` repondait **instantanement et sans ecriture** sur un email inconnu, alors que le chemin email-connu fait : `random_bytes(32)` + `sha256` + `UPDATE user` + envoi de mail. -> oracle de **timing** + de **profil d'ecritures** revelant l'existence d'un compte. Le commit P2 (#11) annoncait une parite anti-enumeration "PR-wide (timing + profil d'ecritures identique)" : vraie sur le **login**, pas sur le **reset**. ## Correctif - `payEnumerationDecoy()` : sur email inconnu, reproduit le cout CPU (token CSPRNG + SHA-256) et **une** ecriture du chemin connu, mais ciblant `id = 0` (aucune ligne, rien persiste). Aucun mail. Meme pattern que le leurre du login (`UPDATE ... WHERE id = 0`). - Tests unknown-email (service + controleur) : assertent desormais 1 ecriture leurre sur `id = 0` + aucun mail (au lieu de 0 ecriture). Suite 188 verte (451 assertions), PHPStan L6 propre. Pas de label auto-merge.
Corentin added 1 commit 2026-06-16 14:02:20 +02:00
fix(auth): leurre anti-enumeration sur la demande de reset (parite timing/ecritures)
All checks were successful
CI / php-lint (push) Successful in 22s
CI / php-lint (pull_request) Successful in 22s
CI / static-tests (pull_request) Successful in 36s
CI / auto-merge (push) Has been skipped
CI / auto-merge (pull_request) Successful in 6s
CI / secret-scan (push) Successful in 11s
CI / static-tests (push) Successful in 35s
CI / secret-scan (pull_request) Successful in 8s
35ead030b1
PasswordResetService::requestReset repondait instantanement et sans ecriture sur
un email inconnu, alors que le chemin email-connu genere un token (random_bytes +
SHA-256), fait un UPDATE et envoie un mail : oracle de timing + de profil
d'ecritures revelant l'existence d'un compte. Le commit P2 #11 annoncait pourtant
une parite anti-enumeration PR-wide (vraie sur le login, pas sur le reset).

payEnumerationDecoy() reproduit le cout CPU et UNE ecriture du chemin connu, mais
sur id = 0 (aucune ligne, rien persiste) ; aucun mail. Meme pattern que le leurre
du login (UPDATE no-op sur id = 0). Tests unknown-email (service + controleur)
mis a jour : 1 ecriture leurre sur id=0, pas de mail. Suite 188 verte, PHPStan L6.
Corentin merged commit 6557dd9c6c into dev 2026-06-16 14:21:00 +02:00
Corentin deleted branch fix/reset-enumeration-decoy 2026-06-16 14:21:01 +02:00
Sign in to join this conversation.
No reviewers
No labels
auto-merge
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: AcadeNice/corentin_wakdo#26
No description provided.