PD-81 -- Revue Securite¶
Resume¶
| Critere | Statut |
|---|---|
| Forbidden patterns | RESERVES (identites metier trustees depuis le body, authz incomplete) |
| Injection SQL | CONFORME (pas d'injection SQL/NoSQL evidente dans les extraits) |
| Auth/Authz | NON CONFORME (bypass d'autorisation + BOLA/IDOR) |
| Fuite donnees | NON CONFORME (kfrags stockes sans chiffrement explicite) |
| Validation | RESERVES (QES non strictement imposee, bornes TTL partielles) |
Verdict : NON_CONFORME
Vulnerabilites identifiees¶
| ID | Description | Gravite | Fichier |
|---|---|---|---|
| S-01 | Bypass authz sur preuve d'audit: getLegalAuditProof() ne refuse jamais explicitement l'acces si non delegate/non owner (log uniquement, puis generation de preuve). | CRITIQUE | services/legal-pre-orchestrator.service.ts |
| S-02 | Identity spoofing / audit forgery: actorIdentity, validatorIdentity, requesterId proviennent du DTO (body) au lieu d'etre lies a request.user. Permet usurpation d'identite applicative et traces probatoires falsifiables. | CRITIQUE | controllers/legal-pre.controller.ts, services/legal-pre-orchestrator.service.ts, services/legal-validation-adapter.service.ts |
| S-03 | BOLA/IDOR sur ressources sensibles: operations sur legalCaseId/legalReKeyId (activate/close/consult/proof) sans verification de propriete/autorisation contextuelle forte par rapport au principal authentifie. | MAJEUR | services/legal-pre-orchestrator.service.ts, services/legal-rekey-manager.service.ts |
| S-04 | kfrags non chiffres au repos (apparent): encryptedKfrags est alimente par Buffer.from(JSON.stringify(artefact.kfrags)) sans chiffrement explicite avant persistance. | CRITIQUE | services/legal-rekey-manager.service.ts |
| S-05 | Invariant QES non enforce: la validation accepte un signatureProfile arbitraire et default QES sans controle strict "must be QES". | MAJEUR | services/mandate-validator.service.ts |
| S-06 | Endpoint GET avec effet de bord: GET /access/:id/status appelle consultDocument() (emission event "document accessed"), pas de guard de rate-limit, et peut servir d'oracle et polluer la piste d'audit. | MAJEUR | controllers/legal-pre.controller.ts |
Verification des invariants securite (cibles)¶
- INV-81-01 (mandat non signe refuse): Partiellement OK (fail si
valid=false, hors stub exclu). - INV-81-02 (QES obligatoire): KO (pas de controle strict QES).
- INV-81-03 (dual validation identites distinctes): Partiel (check present, mais spoofing identite possible via body).
- INV-81-04 (scope strict): OK (check
scopeDocumentIds.includes(documentId)). - INV-81-05 (TTL borne): Partiel (borne max enforcee, borne min pas enforcee au niveau service).
- INV-81-06 (write-block PUT/PATCH/DELETE): OK (guard present).
- INV-81-07 (destruction verifiable): OK avec reserve (zeroization + event, mais voir authz globale).
- INV-81-11 (fail-closed TSP): OK sur les flux montres.
Vecteurs demandes (attendu vs code)¶
- Bypass write-block (
PUT /legal-pre/mandates): Bloque 403 attendu/obtenu. - Scope escape (
documentIdhors scope): Bloque viaERR_DOCUMENT_OUT_OF_SCOPE. - Expired mandate use: Bloque sur activation (
validUntil). - Same validator twice: Bloque via
ERR-81-08(mais contournable par spoofing identity). - Empty mandate: Bloque via
ERR-81-01. - ACTIVE key destruction: Bloque (status non terminal -> exception).
Recommandations prioritaires¶
- 1) Bloquer immediatement S-01/S-02/S-03: binder toutes les identites au JWT (
request.user), supprimer les IDs sensibles du body quand possible, ajouter verification d'appartenance/autorisation sur chaquemandateId/legalCaseId/legalReKeyId. - 2) Corriger S-04: chiffrer les kfrags avant stockage (envelope encryption KMS/HSM), preuve de non-exportabilite, rotation/zeroization testee.
- 3) Corriger S-05: enforcement explicite
signatureProfile === 'QES'(ou liste autorisee stricte selon spec eIDAS). - 4) Corriger S-06: transformer
GET statusen lecture pure de statut (pas deconsultDocument, pas d'event d'acces, rate-limit dedie si necessaire).