PD-103 — Rapport d'audit Spécification v3 ↔ Tests v3¶
Auditeur : PMO indépendant | Date : 2026-04-03 | Documents : PD-103-specification.md (v3), PD-103-tests.md (v3)
Synthèse¶
| Gravité | Nombre |
|---|---|
| Bloquant | 1 |
| Majeur | 4 |
| Mineur | 5 |
ECT-01 — upload_object_key non défini mais inclus dans le fingerprint canonique¶
Type : Ambiguïté + Incohérence Spec↔Tests Référence : Spec §5.12 (payload canonique JSON), §5.1 (modèle de données) Description : Le champ upload_object_key apparaît dans la définition normative du payload canonique d'idempotence (§5.12) mais : - N'est PAS défini dans le modèle de données §5.1 (aucune ligne dans le tableau) - N'a aucune validation (format, taille, jeu caractères) - N'est pas explicitement listé dans le corps requis du POST (§5.12 dit "références upload S3" sans nommer ce champ) - N'apparaît dans AUCUN test (TC-NOM-15, TC-INV-06 ne le mentionnent pas)
Impact : Le fingerprint canonique ne peut pas être calculé de manière déterministe sans ce champ. Toute implémentation devra deviner son format et sa provenance (mobile ou backend ?). De plus, si upload_object_key change entre un upload initial et un retry différé (nouvelle URL pré-signée = potentiellement nouveau S3 key), le fingerprint diverge et la reprise différée produit 409 Conflict au lieu de 200 idempotent — contradiction directe avec INV-103-24 et le flux §5.5 step 13.
Gravité : Bloquant
ECT-02 — Q-103-07 (rétention locale légale) silencieusement retiré sans résolution¶
Type : Risque sécu/conformité Référence : Tests v2 §9 (classé BLOQUANT), Spec v3 §10.2, Tests v3 §9 Description : Le point Q-103-07 ("Politique légale de conservation locale en mode différé au-delà du TTL") était classé Bloquant dans les tests v2 §9. En v3, il a été retiré de la liste §10.2 et de la liste §9 des règles non testables. La résolution invoquée (purge immédiate après UPLOADED, §5.3 postUploadLocalPurgeDelay) ne couvre que le cas post-upload. Le cas UPLOAD_DEFERRED conserve un payload chiffré localement jusqu'à 24h (§5.2 TTL 86400s) sans cadrage juridique formalisé.
Impact : Risque conformité RGPD/vie privée pour la rétention locale de données chiffrées sur device mobile pendant 24h sans politique légale validée.
Gravité : Majeur
ECT-03 — Pas d'annulation utilisateur depuis UPLOAD_DEFERRED¶
Type : Hypothèse dangereuse Référence : Spec §5.7 (machine à états), INV-103-38 Description : La machine à états v3 autorise depuis UPLOAD_DEFERRED uniquement : UPLOADING (reprise réseau) et CANCELLED (TTL expiré uniquement, INV-103-38). Il n'existe aucune transition d'annulation utilisateur explicite depuis UPLOAD_DEFERRED. Un utilisateur dont la capture est en différé doit attendre soit le retour réseau, soit l'expiration du TTL (jusqu'à 24h) sans pouvoir annuler manuellement. Aucun test ne couvre ce scénario car il n'est pas spécifié.
Impact : Expérience utilisateur dégradée. L'utilisateur ne peut pas supprimer une capture différée qu'il souhaite annuler. Incohérence avec la philosophie de contrôle utilisateur (INV-103-21 permet l'annulation depuis CAPTURED, INV-103-29 depuis UPLOADING).
Gravité : Majeur
ECT-04 — Idempotence fragile si upload_object_key varie entre retries¶
Type : Contradiction Référence : Spec §5.12 (canonical payload), §5.5 step 10 (redemande URL pré-signée), INV-103-24 Description : Le flux de reprise différée (§5.5 step 10) exige de redemander une nouvelle URL pré-signée S3 à chaque reprise. Si la nouvelle URL pointe vers un S3 object key différent (comportement courant avec les clés pré-signées horodatées ou UUID-based), alors le champ upload_object_key du payload canonique change, produisant un fingerprint SHA-256 différent. Le backend répondrait 409 Conflict au lieu de 200 idempotent, bloquant la reprise.
Impact : Contradiction entre le contrat d'idempotence (INV-103-37) et le contrat de reprise différée (INV-103-24). Aucun test ne couvre ce cas de figure.
Gravité : Majeur
ECT-05 — Champs timestamp_device, device_id, app_version exclus du canonique sans justification¶
Type : Hypothèse dangereuse Référence : Spec §5.12 (payload canonique), §5.1 Description : Le payload canonique d'idempotence (§5.12) exclut timestamp_device, device_id et app_version sans justification explicite. Un replay avec le même capture_id et content_hash mais un timestamp_device différent (ou un device_id différent) sera considéré 200 idempotent. Ceci pourrait masquer un scénario d'attaque où un attaquant ayant capturé un capture_id le rejoue depuis un autre device.
Impact : Risque d'usurpation si un capture_id est intercepté. L'exclusion peut être légitime (le capture_id étant UUID v4 aléatoire) mais la décision n'est pas documentée ni testée (aucun test adversarial couvrant replay cross-device).
Gravité : Majeur
DIV-01 — Diagramme de séquence ne montre pas la purge locale post-upload¶
Type : Incohérence Spec↔Tests (5bis — cohérence diagrammes) Référence : Spec §5bis (diagramme de séquence), §5.5 step 7, INV-103-38, CA-103-27 Description : Le diagramme de séquence montre UPLOADING -> UPLOADED + purge locale immediate dans le bloc alt "unwrap OK", mais comme annotation inline du participant App Mobile. L'action de purge n'est pas un message séparé et n'apparaît pas comme une étape distincte vérifiable dans le diagramme. Les tests (TC-NOM-17) testent cette purge comme un comportement distinct.
Impact : Un implémenteur lisant uniquement le diagramme pourrait manquer l'obligation de purge immédiate.
Gravité : Mineur
DIV-02 — Diagramme de séquence ne couvre pas le flux multipart¶
Type : Incohérence Spec↔Tests (5bis — cohérence diagrammes) Référence : Spec §5bis, §5.5bis Description : Le diagramme de séquence ne montre que le flux single-part (un seul PUT S3). Le flux multipart (§5.5bis) avec ses spécificités (upload_id, parts multiples, CompleteMultipartUpload, AbortMultipartUpload, reprise partielle) n'a pas de diagramme de séquence dédié. La spec a >= 2 services et des opérations crypto impliqués dans le multipart.
Impact : Lisibilité réduite pour les implémenteurs du flux multipart.
Gravité : Mineur
DIV-03 — Terminologie incohérente "bloquées" vs "orphelines" dans TC-INV-07¶
Type : Ambiguïté terminologique Référence : Tests §5 TC-INV-07 GIVEN ("captures non terminales bloquées"), Spec §5.9 réconciliation ("scan états non-terminaux") Description : TC-INV-07 utilise "captures non terminales bloquées injectées" dans le GIVEN, tandis que la spec parle de "scan états non-terminaux" et de "captures orphelines" (seuil orphelin). Le terme "bloquées" n'est pas défini dans le glossaire §3. TC-INV-11 utilise correctement "orphelin S3" pour le GC.
Impact : Ambiguïté mineure sur les conditions d'entrée du test.
Gravité : Mineur
DIV-04 — device_id : casse "insensitive hex" sans normalisation explicite¶
Type : Ambiguïté Référence : Spec §5.1 (device_id casse "insensitive hex"), §5.1 (capture_id casse "canonical lower") Description : capture_id a une politique de normalisation explicite (INV-103-31 : lowercase avant stockage/comparaison). device_id est marqué "insensitive hex" mais aucun invariant ni aucune règle de normalisation n'est définie. Le comportement de comparaison backend (lookup par device_id) n'est pas spécifié. Aucun test ne couvre la normalisation de device_id.
Impact : Risque de duplicats ou lookups échoués si le backend compare device_id de manière case-sensitive.
Gravité : Mineur
DIV-05 — Échec AbortMultipartUpload non couvert¶
Type : Hypothèse dangereuse Référence : Spec INV-103-29, §5.5bis step 8, ER-103-16 Description : INV-103-29 et §5.5bis step 8 exigent l'annulation de l'upload S3 multipart (AbortMultipartUpload) lors d'une annulation utilisateur. Aucun cas d'erreur ne couvre la situation où l'appel AbortMultipartUpload échoue (réseau KO, S3 indisponible). Les parts uploadées resteraient orphelines sur S3 jusqu'au GC (INV-103-33) après orphanTtl. Aucun test ne couvre ce scénario.
Impact : Fenêtre de rétention non maîtrisée d'artefacts chiffrés sur S3 si l'abort échoue. Le GC orphelins finit par nettoyer, mais le comportement intermédiaire n'est pas contractualisé.
Gravité : Mineur
Matrice récapitulative¶
| ID | Type | Gravité | Résumé |
|---|---|---|---|
| ECT-01 | Ambiguïté + Incohérence Spec↔Tests | Bloquant | upload_object_key non défini dans §5.1, inclus dans fingerprint canonique, absent des tests |
| ECT-02 | Risque sécu/conformité | Majeur | Q-103-07 (rétention légale locale 24h) retiré de BLOQUANT sans résolution pour UPLOAD_DEFERRED |
| ECT-03 | Hypothèse dangereuse | Majeur | Aucune annulation utilisateur possible depuis UPLOAD_DEFERRED |
| ECT-04 | Contradiction | Majeur | upload_object_key variable casse l'idempotence en reprise différée |
| ECT-05 | Hypothèse dangereuse | Majeur | Exclusion de timestamp_device/device_id du canonique non justifiée ni testée adversarialement |
| DIV-01 | Incohérence diagramme | Mineur | Purge locale post-upload non visible comme étape distincte dans le diagramme de séquence |
| DIV-02 | Incohérence diagramme | Mineur | Absence de diagramme de séquence pour le flux multipart |
| DIV-03 | Ambiguïté terminologique | Mineur | "bloquées" (tests) vs "non-terminaux" (spec) dans TC-INV-07 |
| DIV-04 | Ambiguïté | Mineur | device_id sans règle de normalisation contrairement à capture_id |
| DIV-05 | Hypothèse dangereuse | Mineur | Échec AbortMultipartUpload non contractualisé ni testé |