PD-55 — Revue Sécurité (v2)
Résumé
| Critère | Statut |
| Forbidden patterns | ⚠️ |
| Injection SQL | ✅ |
| Auth/Authz | ✅ |
| Fuite données | ⚠️ |
| Validation | ⚠️ |
| Race conditions | ⚠️ |
| Immutabilité | ✅ |
Verdict : ⚠️ RÉSERVES
Audit des forbidden patterns
| Pattern interdit | Recherché | Trouvé |
| SQL dynamique concaténée | entityManager.query + QueryBuilder | ❌ (requêtes paramétrées) |
| Endpoint sans garde auth | AnchorController | ❌ (@UseGuards classe) |
| Mutation lot FINALIZED | service + DB | ❌ (triggers update/delete) |
| Unicité uniquement applicative | migrations/index | ❌ (UNIQUE event_id DB) |
| Fail-open sur invariant | alerting/continuity | ✅ (detectWindowGap fail-open) |
Tentatives de bypass
| Attaque | Résultat | Commentaire |
| Injection SQL windowStart | ✅ Bloquée | Paramètres $1..$4 |
| UUID malformé | ✅ Bloquée | ParseUUIDPipe 400 |
| Double finalization | ✅ Bloquée | pessimistic_write |
| Double ancrage event | ✅ Bloquée | UNIQUE event_id |
| Bypass auth sans JWT | ✅ Bloquée | JwtAuthGuard |
| Modification FINALIZED | ✅ Bloquée | Triggers PostgreSQL |
Vulnérabilités identifiées
| ID | Description | Gravité | Fichier |
| VULN-55-01 | Orphelin batch si échec audit post-commit dans createBatch | ÉLEVÉE | anchor-batch.service.ts |
| VULN-55-02 | Collecte événements incohérente (status=PENDING vs non-FINALIZED) | ÉLEVÉE | proof-event.service.ts |
| VULN-55-03 | Fail-open sur continuité temporelle | MOYENNE | anchor-alert.service.ts |
| VULN-55-04 | ParseUUIDPipe sans version explicite v4 | FAIBLE | anchor.controller.ts |
| VULN-55-05 | markEventsAnchored sans contrôle affectedRows | MOYENNE | proof-event.service.ts |
Recommandations
- Rendre createBatch atomique avec audit (outbox pattern)
- Corriger collectEligibleEvents pour exclure événements déjà FINALIZED
- Passer detectWindowGap en fail-closed configurable
- Forcer ParseUUIDPipe({ version: '4' })
- Vérifier affectedRows dans markEventsAnchored
Date : 2026-02-22 Revieweur : ChatGPT (gpt-5.3-codex) Mode : Review sécurité adversariale (Step 7 v2)