Aller au contenu

PD-262 — Scenarios de tests contractuels

1. References

  • Specification : PD-262-specification.md
  • Epic : EPIC-XX

2. Matrice de couverture

ID Invariant ID Critere ID Test Couverture Commentaire
INV-262-01-fail-closed CA-04, CA-13 TC-NOM-04, TC-NOM-09, TC-ERR-02 Oui Detection positive et erreur detecteur forcent tampered=true (TC-NOM-09 fusionne ERR-01).
INV-262-02-native-authority CA-01 TC-INV-02, TC-NEG-03 Oui Verifie impossibilite JS d'inhiber/retarder lockout natif.
INV-262-03-trigger-coverage CA-01, CA-02, CA-03 TC-NOM-01, TC-NOM-02, TC-NOM-03 Oui Cold start, foreground, periodique couverts.
INV-262-04-single-lockout-state CA-05 TC-INV-04, TC-ERR-07 Oui Un seul etat lockout, causes distinctes en audit local uniquement.
INV-262-05-purge-on-detect CA-07, CA-19 TC-NOM-04, TC-ERR-05, TC-ERR-11 Oui Purge immediate + gestion purge partielle avec retries bornes.
INV-262-06-local-first CA-10 TC-NOM-05, TC-ERR-04 Oui Reseau non bloquant pour securite locale.
INV-262-07-release-gating CA-11 TC-NOM-06, TC-ERR-06 Oui Matrice environnements contractuelle + flag QA compile-time.
INV-262-08-transition-model CA-05 TC-NOM-11, TC-INV-08, TC-NR-01 Oui Transitions interdites bloquees.
INV-262-09-terminal-state CA-06, CA-17, CA-18 TC-NOM-08, TC-NR-02, TC-ERR-09, TC-ERR-10 Oui LOCKED_PERSISTENT terminal, y compris absence/corruption/interruption.
INV-262-10-envelope-encryption CA-14 TC-NOM-10, TC-INV-10 Oui Aucun secret temporaire en clair au repos.
INV-262-11-no-sensitive-telemetry CA-09, CA-12 TC-NOM-07, TC-INV-11, TC-NEG-01 Oui Telemetrie en allowlist stricte, sans materiau sensible.
INV-262-12-state-persistence CA-06, CA-16 TC-NOM-08, TC-ERR-08, TC-ERR-09, TC-ERR-10 Oui Lockout persiste et se reapplique au redemarrage.
n/a CA-08, CA-15 TC-NOM-12 Oui Blobs deja chiffres non wipes automatiquement, frontiere avec caches crypto respectee.

3. Scenarios de test - Flux nominaux

TEST-ID: TC-NOM-01
Reference spec: INV-262-03, INV-262-07, CA-01

GIVEN
  - Build RELEASE sur device iOS reel non compromis
  - Journalisation locale active (horodatage monotonic)
WHEN
  - Demarrage a froid de l'application
THEN
  - Un controle anti-tampering est execute avant tout acces aux secrets applicatifs
  - Etat final = MONITORED
AND
  - tampered=false
  - Trace locale contient trigger=cold_start puis resultat de controle
TEST-ID: TC-NOM-02
Reference spec: INV-262-03, CA-02

GIVEN
  - Session active en MONITORED
  - Application en background >= 5s
WHEN
  - Retour foreground
THEN
  - Un re-check anti-tampering est execute avant reprise des operations sensibles
AND
  - Compteur de checks incremente de +1 par transition foreground
TEST-ID: TC-NOM-03
Reference spec: INV-262-03, CA-03

GIVEN
  - Session active en MONITORED
  - detection_interval_sec successivement configure a 45, 20, 75
WHEN
  - Le scheduler periodique est lance
THEN
  - Intervalle observe = 45s (defaut), puis 30s (clamp min), puis 60s (clamp max)
AND
  - Mesure stable sur N>=10 intervalles par configuration
TEST-ID: TC-NOM-04
Reference spec: INV-262-01, INV-262-05, INV-262-08, CA-04, CA-07

GIVEN
  - Device reel avec signal de compromission injecte: FRIDA_DETECTED
  - Session MONITORED
WHEN
  - Un controle anti-tampering s'execute
THEN
  - Transition MONITORED -> TAMPERED_SESSION est observee
  - tampered=true
  - Lockout affiche en <=1s P95 (N>=100 executions)
AND
  - Purge immediate executee (memoire sensible, tokens session/refresh, caches crypto, temporaires dechiffres, previews)
  - Transition vers LOCKED_PERSISTENT observee
TEST-ID: TC-NOM-05
Reference spec: INV-262-06, CA-10

GIVEN
  - Compromission detectee
  - Reseau indisponible (mode offline)
WHEN
  - Tentative d'emission ANTI_TAMPERING_LOCKOUT
THEN
  - Lockout/purge restent effectifs sans delai additionnel
AND
  - Aucun rollback securite
  - Echec d'emission journalise localement
TEST-ID: TC-NOM-06
Reference spec: INV-262-07, CA-11

GIVEN
  - Matrice: DEBUG, SIMULATOR, QA(device reel build flag OFF/ON), RELEASE, TESTFLIGHT, PRODUCTION
WHEN
  - Initialisation du module anti-tampering
THEN
  - DEBUG + SIMULATOR: module inactif
  - RELEASE/TESTFLIGHT/PRODUCTION: module actif
  - QA sur device reel: activation strictement conforme au build flag compile
AND
  - Aucune mutation runtime (UserDefaults/remote config) ne modifie l'etat d'activation
``` <!-- FIX E-08 -->

```text
TEST-ID: TC-NOM-07
Reference spec: INV-262-11, CA-09, CA-12

GIVEN
  - Evenement audit construit apres lockout
WHEN
  - Validation schema stricte est appliquee
THEN
  - Payload accepte uniquement si champs conformes a §3.3
  - Aucun champ hors allowlist (§3.3) n'est present
AND
  - Aucune donnee sensible (secret, dump memoire, token) n'apparait dans payload
TEST-ID: TC-NOM-08
Reference spec: INV-262-09, INV-262-12, CA-06, CA-16

GIVEN
  - Etat LOCKED_PERSISTENT persiste localement (Keychain)
WHEN
  - Redemarrage de l'application
THEN
  - Lockout reapplique immediatement
  - Aucune transition sortante autorisee
AND
  - Etat terminal conserve sur redemarrages successifs
``` <!-- FIX E-04 -->

```text
TEST-ID: TC-NOM-09
Reference spec: INV-262-01, ERR-01, CA-13

GIVEN
  - Detecteur force en erreur interne
WHEN
  - Controle anti-tampering execute
THEN
  - reason_code=DETECTOR_ERROR
  - tampered=true
AND
  - Lockout applique en fail-closed
  - Aucune reprise normale possible
``` <!-- FIX E-10 -->

```text
TEST-ID: TC-NOM-10
Reference spec: INV-262-10, CA-14

GIVEN
  - Artefacts cryptographiques temporaires existants (cle, fragment, DEK, ReKey)
WHEN
  - Audit de stockage local au repos
THEN
  - Aucun artefact temporaire en clair n'est observable
AND
  - Chiffrement au repos verifiable (AES-256-GCM ou enveloppe HSM)
TEST-ID: TC-NOM-11
Reference spec: INV-262-08, CA-05

GIVEN
  - Etat TAMPERED_SESSION etabli
WHEN
  - Tentative explicite de transition vers MONITORED
THEN
  - Transition refusee
AND
  - Etat reste TAMPERED_SESSION puis LOCKED_PERSISTENT selon sequence
TEST-ID: TC-NOM-12
Reference spec: CA-08, CA-15

GIVEN
  - Blobs locaux deja chiffres presents avant detection
  - Caches crypto temporaires presents
WHEN
  - Lockout et purge sont declenches
THEN
  - Les blobs chiffres ne sont pas wipes automatiquement
  - Les caches crypto sont purges
AND
  - Les donnees persistantes restent inexploitables sans secrets purges
``` <!-- FIX E-03 -->

## 4. Scenarios de test - Cas d'erreur

```text
TEST-ID: TC-ERR-02
Reference spec: ERR-02, INV-262-01

GIVEN
  - Budget cold start controle force au depassement >1500ms P95
WHEN
  - Controle cold start execute
THEN
  - Fail-closed active
  - Lockout applique
AND
  - Journalisation locale du timeout presente
TEST-ID: TC-ERR-03
Reference spec: ERR-03, CA-12

GIVEN
  - Payload audit avec au moins un champ invalide §3.3
WHEN
  - Envoi audit tente
THEN
  - Envoi rejete
  - Lockout conserve
AND
  - Log local de rejet present
TEST-ID: TC-ERR-04
Reference spec: ERR-04, INV-262-06

GIVEN
  - Backend indisponible
WHEN
  - Emission d'evenement lockout
THEN
  - Lockout conserve
  - Aucun retry bloquant UX
AND
  - Securite locale inchangee
TEST-ID: TC-ERR-05
Reference spec: ERR-05, INV-262-05, CA-19

GIVEN
  - Un sous-ensemble purge est inaccessible
WHEN
  - Purge initiale executee apres detection
THEN
  - Lockout maintenu
  - Retry purge locale enclenche
AND
  - Aucune reprise etat nominal
``` <!-- FIX E-11 -->

```text
TEST-ID: TC-ERR-06
Reference spec: ERR-06, INV-262-07

GIVEN
  - Tentative d'activation QA via runtime (UserDefaults/remote config) ou flag QA active en simulateur
WHEN
  - Module initialise
THEN
  - Anti-tampering reste inactif en simulateur
  - Toute mutation runtime est ignoree
AND
  - Incoherence journalisee
``` <!-- FIX E-08 -->

```text
TEST-ID: TC-ERR-07
Reference spec: ERR-07, INV-262-04

GIVEN
  - Detection concurrente de plusieurs causes
WHEN
  - Lockout est declenche
THEN
  - Un seul lockout unique est cree
  - Cause primaire retenue
AND
  - Causes secondaires stockees uniquement en audit local si disponible
TEST-ID: TC-ERR-08
Reference spec: ERR-08, INV-262-12

GIVEN
  - Donnee locale de lockout corrompue
WHEN
  - Application redemarre
THEN
  - Comportement fail-closed
  - Etat interprete comme LOCKED_PERSISTENT
AND
  - Aucune transition vers etat nominal

```text TEST-ID: TC-ERR-09 Reference spec: ERR-09, CA-17, INV-262-09, INV-262-12

GIVEN - App deja initialisee - Donnee lockout absente au boot - first_launch_clean absent WHEN - Application demarre THEN - Etat force a LOCKED_PERSISTENT (fail-closed) AND - Lockout immediat, aucune transition sortante ```

```text TEST-ID: TC-ERR-10 Reference spec: ERR-10, CA-18, INV-262-09, INV-262-12

GIVEN - Detection compromission en cours - Process tue entre TAMPERED_SESSION et LOCKED_PERSISTENT WHEN - Application redemarre THEN - Etat reconstruit en LOCKED_PERSISTENT AND - Lockout immediat, aucune reprise nominale ```

```text TEST-ID: TC-ERR-11 Reference spec: ERR-05, CA-19, INV-262-05

GIVEN - Purge echoue de facon repetee WHEN - Mecanisme de retry purge s'execute THEN - Maximum 3 retries sont executes - Intervalle de 1s respecte entre retries AND - Apres 3 echecs: abandon retry, lockout maintenu, purge incomplete loggee ```

5. Tests d'invariants (non negociables)

Invariant Test(s) dedies Observable Commentaire
INV-262-01-fail-closed TC-NOM-04, TC-NOM-09, TC-ERR-02 tampered=true, lockout, reason_code Couvre detection + panne detecteur + timeout budget.
INV-262-02-native-authority TC-INV-02, TC-NEG-03 Lockout natif applique malgre tentative JS Autorite native verifiee en adversarial.
INV-262-03-trigger-coverage TC-NOM-01, TC-NOM-02, TC-NOM-03 Traces trigger cold/fg/periodique Couverture complete des contextes d'execution.
INV-262-04-single-lockout-state TC-INV-04, TC-ERR-07 Etat unique tampered=true Distinction causes reservee a l'audit.
INV-262-05-purge-on-detect TC-NOM-04, TC-ERR-05, TC-ERR-11 Effacement cibles purge + retry borne Pas de reprise normale en purge partielle.
INV-262-06-local-first TC-NOM-05, TC-ERR-04 Lockout indep. reseau Best effort strictement non bloquant.
INV-262-07-release-gating TC-NOM-06, TC-ERR-06 Matrice environnement conforme Simulateur toujours inactif + flag QA compile-time.
INV-262-08-transition-model TC-NOM-11, TC-INV-08 Rejet transitions interdites Pas de downgrade etat compromis.
INV-262-09-terminal-state TC-NOM-08, TC-NR-02, TC-ERR-09, TC-ERR-10 Etat terminal conserve Sorties LOCKED_PERSISTENT -> * interdites.
INV-262-10-envelope-encryption TC-NOM-10, TC-INV-10 Aucun secret temporaire en clair Controle au repos local obligatoire.
INV-262-11-no-sensitive-telemetry TC-NOM-07, TC-INV-11, TC-NEG-01 Payload en allowlist + sans secret Zero dump memoire/secret telemetrie.
INV-262-12-state-persistence TC-NOM-08, TC-ERR-08, TC-ERR-09, TC-ERR-10 Lockout persistant au redemarrage Corruption/absence/interruption traitees fail-closed.

5.1 Scenarios dedies invariants (Given / When / Then)

```text TEST-ID: TC-INV-02 Reference spec: INV-262-02-native-authority

GIVEN - Couche JS instrumentee pour retarder/inhiber l'affichage lockout - Couche native detecte une compromission valide WHEN - Decision lockout est prise cote natif THEN - Lockout est applique sans attendre JS AND - Toute tentative JS de bypass est sans effet observable ```

```text TEST-ID: TC-INV-04 Reference spec: INV-262-04-single-lockout-state

GIVEN - Plusieurs causes de compromission detectees sur la meme session WHEN - Etat de securite est calcule THEN - Un seul etat fonctionnel tampered=true est expose AND - La distinction des causes reste limitee au champ audit (reason_code primaire + secondaires locales) ```

```text TEST-ID: TC-INV-08 Reference spec: INV-262-08-transition-model

GIVEN - Etat courant = TAMPERED_SESSION WHEN - Une transition vers MONITORED est demandee THEN - Transition est refusee AND - Seule transition autorisee reste vers LOCKED_PERSISTENT ```

```text TEST-ID: TC-INV-10 Reference spec: INV-262-10-envelope-encryption

GIVEN - Artefacts cryptographiques temporaires presents sur stockage local WHEN - Verification de conformite chiffrement au repos est executee THEN - Tous les artefacts temporaires sont chiffres (AES-256-GCM ou enveloppe HSM) AND - Aucun secret temporaire en clair n'est lisible ```

```text TEST-ID: TC-INV-11 Reference spec: INV-262-11-no-sensitive-telemetry

GIVEN - Payload telemetrie lockout pret a emission WHEN - Controle allowlist des champs est applique THEN - Seuls les champs de §3.3 sont conserves AND - Tout champ sensible (dump memoire, secret, token) est absent/rejete ```

6. Tests de non-regression

Test ID Objet Observable Commentaire
TC-NR-01 Interdiction TAMPERED_SESSION -> MONITORED Transition rejetee Verrouille toute regression de downgrade.
TC-NR-02 Persistance lockout multi-redemarrages Lockout immediat a chaque reboot Protege l'etat terminal.
TC-NR-03 Budget lockout <=1s P95 P95 mesure <=1s Evite derive de latence securite.
TC-NR-04 Intervalle periodique clamp [30..60] Intervalles observes aux bornes Empeche regressions scheduler.
TC-NR-05 Validation schema payload stricte Rejet des champs/regex invalides Evite fuite et rupture backend.
TC-NR-06 Independance reseau Meme lockout online/offline Garantit local-first.

6.1 Scenario detaille non-regression

```text TEST-ID: TC-NR-02 Reference spec: INV-262-09, INV-262-12, CA-06

GIVEN - lockout_persistent_flag=true en Keychain - Application redemarree N fois (N>=5) WHEN - Chaque boot est execute en conditions nominales (sans reinstallation) THEN - Lockout est affiche immediatement a chaque redemarrage AND - Aucune transition sortante de LOCKED_PERSISTENT n'est observable ```

7. Tests negatifs et adversariaux

Test ID Entree invalide / abus Resultat attendu Observable
TC-NEG-01 Payload avec champ supplementaire (memory_dump) Rejet evenement + lockout conserve Log local rejet schema
TC-NEG-02 reason_code hors enum / casse invalide Rejet evenement Validation regex KO
TC-NEG-03 Tentative JS de neutraliser callback lockout Echec tentative, lockout natif maintenu Traces natives prioritaire
TC-NEG-04 Ports Frida invalides (0, 70000) Ports invalides ignores, decision non degradee Journal validation port
TC-NEG-05 detection_interval_sec non numerique Valeur par defaut/clamp applique Config effective observee
TC-NEG-06 Corruption volontaire stockage lockout Fail-closed en LOCKED_PERSISTENT Etat terminal au boot
TC-NEG-07 Injection concurrence multi-causes rapide Un seul lockout cree Unicite etat + cause primaire

8. Observabilite requise pour les tests

  • Etat systeme : machine d'etats (MONITORED, TAMPERED_SESSION, LOCKED_PERSISTENT) et horodatages de transition.
  • Reponse API : statut tentative audit backend (succes/echec/rejet schema), sans coupler securite locale.
  • Journal d'audit : traces locales structurees (trigger, reason_code, decision, purge, transition, resultat emission).
  • Evenement signe / horodate : horodatage ISO-8601 UTC obligatoire ; signature NON SPECIFIEE dans la specification.
  • Export probatoire : export immuable des journaux locaux + captures payload reseau + mesures temporelles (P95).
  • Journal retry purge : compteur retries, intervalle observe, motif d'abandon apres 3 echecs.
  • Observabilite persistance lockout : lecture metadonnees Keychain (kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly) et marqueur first_launch_clean.

9. Regles non testables

Regle Raison Impact
"Ecran lockout non contournable" au sens absolu universel L'absence de contournement pour toutes techniques futures est non prouvable exhaustivement; testable seulement sur corpus d'attaques defini Majeur
Exhaustivite de la purge ("tous emplacements de caches/temporaires") La liste exhaustive/versionnee des emplacements n'est pas contractualisee (Q-05) Majeur
Niveau de detail des causes secondaires en audit local Format/structure non contractualises (Q-04) Mineur
Signature cryptographique de l'evenement audit Exigee par template d'observabilite mais non definie dans la spec contractuelle Mineur
Chemin documentaire final {DOMAINE}/{PD-262-nom} Metadata manquante (Q-02), bloque uniquement la publication de l'artefact Mineur

10. Verdict QA

  • ⚠️ Testable partiellement (avec reserves listees)

Les exigences fonctionnelles et de securite sont majoritairement testables de facon deterministe. Les reserves portent sur l'exhaustivite formelle de purge, la non-contournabilite absolue et des zones non contractualisees (causes secondaires, signature evenement, metadata de chemin).