Aller au contenu

PD-19 — Scénarios de tests contractuels

1. Références

  • Spécification : PD-19-specification.md (v2 corrigée)
  • Epic : PD-186 (BACKEND-CORE)

2. Matrice de couverture

Règle Description contractuelle v2 Cas de test Commentaire
INV-01 Socle headers défini (dont HSTS/Cache-Control conditionnels) TC-NOM-01, TC-NOM-02 Testable avec assertions exactes sur noms/valeurs
INV-03 CORS contractualisé (méthodes, headers autorisés/exposés, credentials) TC-NOM-03, TC-NOM-04 Testable avec préflight + requête simple
INV-04 Origines autorisées par environnement TC-NOM-03, TC-ERR-01 Testable avec matrice d'origines
INV-05 Access-Control-Max-Age : 600/300/60 TC-NOM-04 Testable selon environnement
INV-06 Rate limit S=100 req, W=60s, clé=IP client TC-NOM-07, TC-ERR-03 Testable en charge contrôlée multi-IP
INV-07 Réponse 429 contractuelle + Retry-After + JSON strict TC-NOM-08, TC-ERR-04 Testable intégralement
INV-09 Logs JSON structurés (UTC ISO-8601, corrélation, 90j) TC-NOM-05, TC-NOM-06 Testable via schéma + stratégie de rétention
INV-10 Dev borné à http://localhost:3000 et http://localhost:8080 TC-NOM-03, TC-ERR-01 Testable explicitement
ERR-01 S'applique à toute requête contenant Origin TC-ERR-01, TC-ERR-02 Testable sur simple + preflight
ERR-04 Corps JSON d'erreur contractuel TC-ERR-04 Testable par égalité de payload
ERR-05 Mode fail-fast uniquement TC-ERR-05 Testable via ordre de rejet
CA-01 Observable via middleware global (pas d'échantillon) TC-NOM-05 Testable sur routes variées
CA-11 Logs JSON UTC corrélables TC-NOM-06 Testable par format + corrélation
CA-14 Couverture erreurs 404, 405, 500 TC-ERR-02 Testable par injection de cas

3. Données et paramètres de test

  • Environnements cibles :
  • DEV : origines autorisées http://localhost:3000, http://localhost:8080
  • TEST : origines autorisées https://app-test.probatiovault.com, https://site-test.probatiovault.com
  • PROD : origines autorisées https://app.probatiovault.com, https://www.probatiovault.com
  • CORS contractuel :
  • Méthodes autorisées : GET, POST, PUT, PATCH, DELETE, OPTIONS
  • Headers autorisés : Authorization, Content-Type, Accept, Origin, X-Requested-With, X-Correlation-Id
  • Headers exposés : X-Correlation-Id, Retry-After
  • Credentials : true
  • Preflight max-age :
  • PROD=600, TEST=300, DEV=60
  • Rate limiting :
  • Seuil S=100, fenêtre W=60s, clé d'agrégation=IP client

4. Scénarios nominaux

TC-NOM-01 — Headers de sécurité (socle)

Given une requête GET sans erreur applicative When la réponse est émise Then les headers suivants sont présents et conformes : - X-Content-Type-Options: nosniff - X-Frame-Options: DENY - Content-Security-Policy: default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none' - Referrer-Policy: no-referrer - Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=()

TC-NOM-02 — Headers conditionnels (HSTS / Cache-Control)

Given une requête servie en HTTPS en prod ou test When la réponse est émise Then Strict-Transport-Security: max-age=31536000; includeSubDomains est présent

Given une route d'authentification ou renvoyant des données personnelles ou un statut 401/403 When la réponse est émise Then Cache-Control: no-store est présent

TC-NOM-03 — Origine autorisée par environnement

Given environnement DEV et Origin: http://localhost:3000 When une requête cross-origin est reçue Then l'origine est acceptée et les headers CORS contractuels sont retournés

Given environnement DEV et Origin: http://localhost:8080 When une requête cross-origin est reçue Then l'origine est acceptée et les headers CORS contractuels sont retournés

Given environnement PROD et Origin: https://app.probatiovault.com When une requête cross-origin est reçue Then l'origine est acceptée et les headers CORS contractuels sont retournés

TC-NOM-04 — Preflight CORS contractualisé

Given une requête OPTIONS avec Origin autorisée When le middleware CORS traite le preflight Then la réponse contient : - Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS - Access-Control-Allow-Headers: Authorization, Content-Type, Accept, Origin, X-Requested-With, X-Correlation-Id - Access-Control-Expose-Headers: X-Correlation-Id, Retry-After - Access-Control-Allow-Credentials: true - Access-Control-Max-Age = 600 (PROD) / 300 (TEST) / 60 (DEV)

TC-NOM-05 — Observabilité middleware global (CA-01)

Given des requêtes sur routes métier, inexistante (404), et en erreur (500) When elles traversent la stack HTTP Then le middleware global applique les security headers sur chaque réponse (vérification exhaustive, pas d'échantillonnage)

TC-NOM-06 — Logs JSON UTC corrélables (INV-09 / CA-11)

Given une requête avec X-Correlation-Id When les logs sont émis Then chaque entrée est en JSON structuré, timestamp UTC ISO-8601, corrélée via l'identifiant, et alignée avec la politique de rétention 90 jours

TC-NOM-07 — Limitation de débit sous seuil

Given un client identifié par IP source unique When il envoie 100 requêtes dans 60s Then les 100 requêtes sont traitées normalement sans réponse 429

TC-NOM-08 — Dépassement de seuil (429 contractuel)

Given un client IP ayant déjà consommé 100 requêtes dans 60s When il envoie la requête 101 dans la même fenêtre Then la réponse est 429 avec : - header Retry-After présent (secondes restantes) - corps JSON strict :

{"error":"rate_limited","message":"Too many requests","retryAfter":<s>}

5. Scénarios d'erreur

TC-ERR-01 — Origine non autorisée (ERR-01 + INV-04)

Given une requête avec Origin: http://malicious.local When la requête est traitée (simple ou preflight) Then aucun indicateur CORS positif n'est retourné (ERR-01 s'applique à toute requête avec Origin)

TC-ERR-02 — Couverture erreurs techniques (CA-14)

Given des appels provoquant 404, 405, 500 When les réponses sont produites Then les security headers restent présents, le comportement CORS/logging reste conforme et observable pour chaque code d'erreur

TC-ERR-03 — Rate limiting multi-IP (clé = IP client)

Given deux IP clientes distinctes A et B When A dépasse 100/60s et B reste sous le seuil Then A reçoit 429, B n'est pas impactée

TC-ERR-04 — Corps JSON contractuel en dépassement de quota

Given un dépassement du seuil 100/60s/IP When la réponse d'erreur est retournée Then le payload est strictement :

{"error":"rate_limited","message":"Too many requests","retryAfter":<s>}
et le header Retry-After est cohérent avec le champ retryAfter du corps

TC-ERR-05 — Fail-fast uniquement (ERR-05)

Given une configuration de sécurité manquante ou invalide au démarrage When le service tente de démarrer Then le service échoue explicitement (fail-fast), sans mode permissif implicite ni mode bloquant alternatif

6. Tests de non-régression

Test ID Objet Observable Commentaire
TC-NR-01 Stabilité des décisions CORS autorisées Entrée identique rejouée sur 3 exécutions => sorties identiques Détecte dérive de politique involontaire.
TC-NR-02 Stabilité des refus CORS Origine non autorisée toujours sans indicateur CORS positif Détecte réouverture accidentelle.
TC-NR-03 Stabilité du socle de security headers Diff des en-têtes contractuels sur panel 2xx/4xx/5xx Détecte régression de durcissement.
TC-NR-04 Stabilité de la limitation sous seuil Absence persistante de 429 pour charge <= 100/60s Détecte faux positifs de rate limit.
TC-NR-05 Stabilité de la limitation au-dessus du seuil Présence persistante de 429 + signal documenté pour charge > 100/60s Détecte perte de protection en surcharge.
TC-NR-06 Non-divulgation d'infrastructure Absence continue de signatures techno dans en-têtes Détecte fuite via upgrade middleware/proxy.

7. Tests négatifs et adversariaux

Test ID Entrée invalide / abus Résultat attendu Observable
TC-NEG-01 Origin malformé (schéma invalide, port non conforme) Refus CORS sans indicateur positif En-têtes CORS de refus, décision auditée
TC-NEG-02 Origin forgé similaire visuellement à une origine autorisée (ex: app.probati0vault.com) Refus strict si non exacte selon politique Absence d'autorisation CORS positive
TC-NEG-03 Preflight avec méthode non permise + en-têtes excessifs Refus déterministe Réponses identiques sur répétitions
TC-NEG-04 Rafale > 100/60s sur plusieurs endpoints 429 explicite selon politique Statut, Retry-After, corps JSON contractuel
TC-NEG-05 Tentative de contournement via alternance utilisateurs/rôles Décision CORS/limitation inchangée (clé=IP) Comparatif de réponses et logs
TC-NEG-06 Appels sur 404/405/500 pour fuite d'info Security headers présents, aucune bannière techno En-têtes de réponse multi-statuts

8. Table de traçabilité ST↔TC

ID Spécification (ST) Cas de test (TC)
ST-01 (CA-03) TC-NOM-03
ST-02 (CA-04) TC-ERR-01
ST-03 (CA-05) TC-NOM-04
ST-04 (CA-06) TC-NOM-04 (refus)
ST-05 (CA-01, CA-14) TC-NOM-01, TC-NOM-05, TC-ERR-02
ST-06 (CA-02) TC-NEG-06
ST-07 (CA-08) TC-NOM-08, TC-ERR-04
ST-08 (CA-09) TC-NOM-07
ST-09 (CA-10) TC-NOM-03 (multi-env)
ST-10 (CA-12) TC-NOM-03 (DEV)
ST-11 (CA-13) TC-NEG-05
ST-12 (CA-11) TC-NOM-06
INV-05 TC-NOM-04
INV-06 TC-NOM-07, TC-ERR-03, TC-ERR-04
INV-07 TC-NOM-08, TC-ERR-04
INV-09 TC-NOM-06
INV-10 TC-NOM-03 (DEV), TC-ERR-01
ERR-01 TC-ERR-01
ERR-05 TC-ERR-05

9. Règles non testables

Règle Raison Impact
Exceptions contrôlées Cas d'exception B2B non spécifiés Mineur
Exigences d'alerting Aucune condition de déclenchement définie Mineur

10. Verdict QA

Verdict : testable quasi-intégralement. Le référentiel est désormais testable sur l'ensemble des règles contractuelles v2, avec uniquement 2 réserves mineures non bloquantes (exceptions B2B non spécifiées, alerting non paramétré).

11. Préconditions d'exécution

  • Horloge système synchronisée (UTC) pour valider timestamps ISO-8601
  • Possibilité de contrôler l'IP source en test (proxy/fixtures réseau)
  • Jeux d'origines configurés par environnement (DEV/TEST/PROD)
  • Configuration rate limiting active avec seuil 100/60s/IP

12. Observabilité requise pour les tests

  • État système : environnement actif (dev/test/prod), version de configuration sécurité chargée, horodatage de démarrage.
  • Réponse API : statut HTTP, en-têtes complets (CORS, security headers, limitation), corps de réponse d'erreur le cas échéant.
  • Journal d'audit : décision CORS (origine, méthode, en-têtes demandés, verdict), décision de limitation (IP client, fenêtre 60s, seuil 100, verdict), identifiant de corrélation.
  • Événement signé / horodaté : preuve horodatée des changements de configuration active et des démarrages d'environnement.
  • Export probatoire : rapport de campagne (tests, entrées, sorties, verdict), comparaison documentation vs observé, écarts qualifiés.

Document produit par le workflow de gouvernance IA — Étape 2 (corrigé après Gate 3 v1) Date : 2026-02-09