Aller au contenu

PD-264 — Revue Securite

Resume

Critere Statut
Forbidden patterns
Injection SQL
Auth/Authz ✅ (hors perimetre REST direct)
Fuite donnees
Validation ✅ avec reserve mineure
Timing attacks
CSPRNG exclusif
Anti-rejeu
Automate d'etats ⚠️ Partiellement integre (stub processor)

Verdict : ⚠️ RESERVES

Barrieres primaires identifiees

Barriere Composant Attenuation
Unicite DB du nonce idx_timestamp_token_nonce dans src/database/migrations/1740600000000-PD264NonceByteaMigration.ts Bloque le rejeu meme si la verification applicative est contournee (defense primaire anti-replay)
Contrainte de taille DB chk_nonce_length (16 octets) dans src/database/migrations/1740600000000-PD264NonceByteaMigration.ts Empeche la persistance de nonces malformes
Immutabilite post-insert trigger trg_timestamp_token_immutable reactive dans src/database/migrations/1740600000000-PD264NonceByteaMigration.ts Empeche alteration/suppression de preuve apres insertion
CSPRNG randomBytes(16) dans src/modules/tsa/services/nonce.service.ts Garantit l'entropie cryptographique du nonce

Audit des forbidden patterns

Pattern interdit Recherche Trouve
Math.random() nonce.service.ts, processor ✅ Absent
Buffer.equals() pour nonce nonce.service.ts, nonce-validation.service.ts ✅ Absent
Log nonce en clair logs nonce ✅ Absent (hash tronque SHA-256)
Acceptation nonce absent validateResponseNonce ✅ Absent (rejet fail-closed)
Acceptation nonce mismatch validateResponseNonce ✅ Absent (rejet explicite)
Ecriture DB avant validation batch-timestamp.processor.ts ✅ Absent
Trigger immutabilite laisse OFF migration up/down ✅ Absent

Tentatives de bypass

Attaque Resultat Commentaire
Injection SQL (batchId = "'; DROP TABLE--") Echec Aucune concat SQL applicative ; acces ORM parametre
Replay nonce (nonce deja vu) Echec checkUniqueness + index UNIQUE DB
Nonce mismatch Echec REJECTED_MISMATCH
Nonce absent/reponse invalide Echec REJECTED_ABSENT fail-closed
Nonce taille invalide (8 octets) Echec REJECTED_INVALID_SIZE
Timing attack comparaison Attenue timingSafeEqual ; seul cas longueur differente retourne tot (risque negligeable car format fixe a 16)
Bypass auth REST N/A Aucun endpoint REST dans le scope audite (services/processor internes)
Transition inverse (ACCEPTED -> RECEIVED) Echec TRANSITION_FORBIDDEN
PRNG non crypto (Math.random) Absent Uniquement crypto.randomBytes(16)

Vulnerabilites identifiees

ID Description Gravite Fichier
S-01 Signalement d'erreur trop generique : dans le catch global du processor, errorCode est force a QTSA_UNREACHABLE meme pour d'autres causes (validation/etat), ce qui peut masquer un incident securite et retarder la detection. MINEUR src/modules/tsa/processors/batch-timestamp.processor.ts
S-02 Divulgation potentielle de details internes : errorMessage brut est renvoye dans le resultat de job ; si ce resultat est expose en API plus tard, fuite d'info possible (stack/business details). MINEUR src/modules/tsa/processors/batch-timestamp.processor.ts

Ecarts documentes (non vulnerabilites majeures)

ID Ecart Classification
D-01 QTSA client non implemente (TODO explicite, retour controle) Ecart documente MINEUR
D-02 Automate d'etats defini mais non exerce end-to-end dans le processor (flux futur commente) Reserve d'integration

Recommandations

  • Mapper precisement les erreurs dans le processor (NONCE_*, BATCH_*, QTSA_*) au lieu de forcer QTSA_UNREACHABLE.
  • Sanitizer les messages renvoyes hors worker (message fonctionnel court + trace interne separee).
  • Lors de l'integration QTSA reelle, imposer l'ordre strict : REQUEST_EMITTED -> RESPONSE_RECEIVED -> VALIDATION -> PERSIST.
  • Ajouter un test de concurrence (2 workers, meme nonce) pour valider le comportement sur violation UNIQUE DB et le code d'erreur metier attendu.
  • Conserver le logging actuel du nonce en hash tronque (bonne pratique, conforme).