feat(admin): throttle du PIN d action sensible par acteur (RG-T22) #18

Merged
Corentin merged 1 commit from feat/p3-pin-throttle into dev 2026-06-16 00:06:34 +02:00
Owner

Throttle du PIN d action sensible (RG-T22)

Ferme le finding HIGH de la revue Produits (#17) : PIN sans limitation de tentatives.

Decision (design panel multi-agents + passe adversariale, holds=true)

Dimension du throttle = utilisateur AGISSANT (session, RG-T02), pas l email cible (contournable par rotation) ni l IP (collateral poste partage). Table dediee pin_throttle (entite 22) STRICTEMENT SEPAREE des compteurs de login -> un echec de PIN n incremente aucun compteur de connexion (pas d escalade DoS).

Contenu

  • migration 0002 pin_throttle (FK actor_user_id -> user ON DELETE CASCADE)
  • ThrottlePolicy dimension pin (PIN_THROTTLE_*, 30s..300s)
  • PinThrottle (isLocked/recordFailure/reset), PinVerifier::payTimingDecoy
  • cablage ProductController update/destroy : gate avant verification, pas de pin.failed sous verrou (anti-flood), reset sur l acteur de session
  • docs Merise 21 -> 22 entites (RG-T22), journal RNCP

Must-fix adversaire integres

  • anti-flood audit (pas de nouveau pin.failed sous verrou actif)
  • parite de timing (decoy argon2id sur le chemin verrouille)

Tests : 188 verts (525 assertions), PHPStan L6 propre. Revue de l implementation : holds=true.

## Throttle du PIN d action sensible (RG-T22) Ferme le finding HIGH de la revue Produits (#17) : PIN sans limitation de tentatives. ### Decision (design panel multi-agents + passe adversariale, holds=true) Dimension du throttle = **utilisateur AGISSANT** (session, RG-T02), pas l email cible (contournable par rotation) ni l IP (collateral poste partage). Table dediee `pin_throttle` (entite 22) STRICTEMENT SEPAREE des compteurs de login -> un echec de PIN n incremente aucun compteur de connexion (pas d escalade DoS). ### Contenu - migration 0002 `pin_throttle` (FK actor_user_id -> user ON DELETE CASCADE) - `ThrottlePolicy` dimension `pin` (PIN_THROTTLE_*, 30s..300s) - `PinThrottle` (isLocked/recordFailure/reset), `PinVerifier::payTimingDecoy` - cablage `ProductController` update/destroy : gate avant verification, pas de pin.failed sous verrou (anti-flood), reset sur l acteur de session - docs Merise 21 -> 22 entites (RG-T22), journal RNCP ### Must-fix adversaire integres - anti-flood audit (pas de nouveau pin.failed sous verrou actif) - parite de timing (decoy argon2id sur le chemin verrouille) Tests : 188 verts (525 assertions), PHPStan L6 propre. Revue de l implementation : holds=true.
Corentin added 1 commit 2026-06-16 00:03:26 +02:00
feat(admin): throttle du PIN d'action sensible par acteur (RG-T22)
Some checks failed
CI / php-lint (push) Successful in 19s
CI / secret-scan (pull_request) Successful in 8s
CI / secret-scan (push) Successful in 10s
CI / static-tests (push) Successful in 30s
CI / php-lint (pull_request) Successful in 19s
CI / auto-merge (push) Has been skipped
CI / static-tests (pull_request) Successful in 30s
CI / auto-merge (pull_request) Failing after 4s
5a4897921e
Ferme le finding HIGH de la revue Produits (#17) : le PIN d'action sensible
etait verifie sans limitation de tentatives. Conception via panel multi-agents
(3 lentilles + synthese + passe adversariale, holds=true) puis revue de
l'implementation (holds=true).

Dimension du throttle = UTILISATEUR AGISSANT (identite de session, RG-T02), pas
l'email cible (contournable par rotation) ni l'IP (collateral sur poste partage).
Table dediee pin_throttle (entite 22) STRICTEMENT SEPAREE des compteurs de login
(user.failed_login_attempts / login_throttle) : un echec de PIN n'incremente aucun
compteur de connexion (pas d'escalade DoS vers le login).

- db/migrations/0002_pin_throttle.sql : table cle sur actor_user_id (UNIQUE, FK
  -> user ON DELETE CASCADE), separee du login. Appliquee a la base dev.
- ThrottlePolicy : dimension 'pin' (bornes propres PIN_THROTTLE_*, 30s..300s, plus
  permissives que le login : controle de dissuasion, residuel Faible).
- PinThrottle (nouveau) : isLocked / recordFailure (upsert atomique + backoff, une
  transaction, miroir d'AuthService) / reset (UPDATE simple). N'ecrit jamais
  user/login_throttle/audit_log.
- PinVerifier::payTimingDecoy : parite de timing du chemin verrouille.
- ProductController update/destroy : gate AVANT verification (leurre + 422
  generique, pas de pin.failed sous verrou actif = borne anti-flood de l'audit) ;
  recordFailure sur PIN faux ; reset sur succes, cle sur l'acteur de SESSION.
- Docs Merise 21 -> 22 entites : RG-T22 (mlt), entite 22 pin_throttle
  (mcd/mld/dictionary), couverture MCT 22/22 (mct).
- .env.example + docker-compose : PIN_THROTTLE_THRESHOLD/BASE/MAX/WINDOW.
- Journal RNCP : docs/journal/2026-06-15--p3-throttle-pin-rg-t22.md.

Tests : 188 verts (525 assertions), PHPStan L6 propre.
Corentin added the
auto-merge
label 2026-06-16 00:03:44 +02:00
Corentin merged commit ad5203d3fc into dev 2026-06-16 00:06:34 +02:00
Corentin deleted branch feat/p3-pin-throttle 2026-06-16 00:06:34 +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#18
No description provided.