Aller au contenu

Threat modeling STRIDE avant écrire le code

Le threat modeling sert à décider ce que le logiciel doit empêcher avant que les choix d’architecture deviennent des dépendances coûteuses. STRIDE fournit une grille de lecture efficace à condition de partir des flux, des frontières de confiance et des actifs, pas d’une liste de vulnérabilités copiée dans un tableur.

→ Lire l’explication complète de la marmotte

Le compromis du threat modeling : délai initial contre dette de sécurité

Section intitulée « Le compromis du threat modeling : délai initial contre dette de sécurité »

Le compromis est brutal : investir quelques heures avant le code ralentit le premier commit, mais évite de découvrir après intégration qu’un mécanisme d’identité, de chiffrement ou de cloisonnement manque structurellement. La recommandation est de faire un threat model pour chaque nouveau flux exposé, chaque changement de frontière de confiance et chaque usage d’un secret à privilège. Pas pour chaque renommage de variable. La sécurité cérémonielle produit des diagrammes morts, ce qui est une forme d’art moderne assez répandue.

Un modèle de menace doit produire des décisions vérifiables : exigences d’authentification, autorisations, journalisation, limites de débit, règles de conservation, mécanismes de rotation et critères de refus. Une phrase comme « utiliser du chiffrement » n’est pas une exigence. Il faut préciser le périmètre, l’algorithme, l’emplacement des clés, l’identité autorisée à déchiffrer et le comportement quand le service de clés est indisponible.

Le résultat attendu n’est pas une évaluation de risque exhaustive au sens gouvernance. L’analyse EBIOS Risk Manager traite notamment les scénarios stratégiques, les parties prenantes et les risques organisationnels. Le threat modeling de développement traite le mécanisme concret : un jeton circule entre un navigateur, une passerelle, une API (Application Programming Interface) et une base de données. Qui peut le voler, le rejouer, le modifier ou le faire disparaître ?

Avant l’atelier, disposer de quatre éléments :

  1. Une description fonctionnelle limitée au changement envisagé.
  2. Un diagramme de flux de données, ou DFD (Data Flow Diagram), montrant processus, stockages, entités externes et frontières de confiance.
  3. La classification des actifs : données personnelles, secrets, jetons, clés, décisions d’autorisation, journaux.
  4. Les hypothèses de plateforme : réseau, fournisseur d’identité, gestionnaire de secrets, environnement d’exécution, mécanismes de sauvegarde.

Sans inventaire des identités et des flux, STRIDE devient une loterie à six cases. Les sujets d’identité doivent être raccordés aux règles d’IAM et fédération, pas laissés au framework applicatif avec une prière et une dépendance transitive.

STRIDE sur les flux et les frontières de confiance

Section intitulée « STRIDE sur les flux et les frontières de confiance »

STRIDE classe les menaces selon six propriétés attaquées : Spoofing (usurpation d’identité), Tampering (altération), Repudiation (répudiation), Information Disclosure (divulgation d’information), Denial of Service (déni de service) et Elevation of Privilege (élévation de privilèges). Cette taxonomie ne remplace pas une analyse. Elle force à examiner chaque élément du diagramme avec des questions précises.

Pour une entité externe, rechercher l’usurpation : un appelant peut-il présenter une identité forgée, rejouer un jeton ou contourner une authentification mutuelle ? Pour un flux, rechercher l’altération et la divulgation : le message peut-il être modifié, intercepté, redirigé ou inscrit dans des traces ? Pour un stockage, rechercher l’accès hors périmètre, la corruption et l’effacement. Pour un processus, rechercher l’élévation de privilèges et la répudiation des actions sensibles.

Une frontière de confiance existe lorsqu’un composant reçoit une donnée ou une identité dont il ne contrôle pas entièrement l’origine. Internet en est une, évidemment. Un cluster de conteneurs aussi, entre deux espaces de noms, deux comptes cloud ou deux services utilisant des identités distinctes. Chiffrer un flux entre deux composants ne supprime pas cette frontière : le chiffrement protège le transport, pas la décision prise après déchiffrement. Le protocole TLS (Transport Layer Security) ne transforme pas une requête malveillante en requête gentille, malgré plusieurs décennies de slides vendeurs.

Pour chaque menace retenue, documenter cinq champs :

  • l’actif affecté ;
  • la précondition d’attaque ;
  • le scénario technique ;
  • la contre-mesure et son propriétaire ;
  • le test ou signal qui prouve son existence.

Exemple : une API d’export accepte un identifiant de dossier. La menace est une élévation de privilèges par référence directe à un objet. La précondition est de connaître ou deviner un identifiant. La contre-mesure n’est pas « vérifier les droits » : elle consiste à évaluer l’autorisation sur l’objet cible côté serveur, après authentification, pour chaque requête, sans accepter un rôle fourni par le client. Le test doit vérifier qu’un jeton valide d’un autre locataire reçoit un refus, y compris sur les endpoints secondaires et les téléchargements asynchrones.

Le threat model doit arriver avant la sélection des bibliothèques, des schémas de données et des contrats d’API. Une contre-mesure ajoutée après coup impose souvent une migration de modèle d’identité, une rupture de compatibilité ou une reconstruction de journaux incomplets. Les tests après développement détectent des erreurs d’implémentation ; ils ne corrigent pas une frontière de confiance qui n’a jamais été modélisée.

Trancher tôt sur les propriétés suivantes :

  • Authentification : quel composant prouve quelle identité, par quel protocole, avec quelle durée de session et quelle révocation ?
  • Autorisation : la décision dépend-elle d’un rôle global, d’une relation sur une ressource, d’un contexte de locataire ou des quatre ? Les droits doivent être évalués côté serveur.
  • Confidentialité : quelles données doivent être chiffrées en transit, au repos et dans les sauvegardes ? Une base chiffrée au repos ne protège pas contre un compte applicatif compromis.
  • Intégrité : quelle donnée doit être signée, hachée ou rendue immuable ? Un journal modifiable par le même principal que l’application n’apporte pas de non-répudiation.
  • Disponibilité : quel coût maximal d’une requête est acceptable, quelles limites de taille, de concurrence et de débit appliquer, quelle dégradation accepter ?
  • Traçabilité : quels événements permettent de reconstruire une action privilégiée sans enregistrer les secrets, jetons ou données sensibles ?

Le mécanisme ne garantit pas que toutes les failles seront trouvées. Il ne remplace ni revue de code, ni analyse de dépendances, ni test d’intrusion, ni validation de configuration. Il ne garantit pas non plus qu’une exigence sera correctement implémentée : il fournit le contrat de sécurité que les tests, les revues et l’exploitation doivent vérifier. Lier ce contrat aux pratiques de développement sécurisé évite qu’il finisse en pièce jointe fossilisée.

Exemple de registre STRIDE pour une API d’export

Section intitulée « Exemple de registre STRIDE pour une API d’export »

Le registre doit vivre dans le dépôt, près du contrat d’interface et des décisions d’architecture. Un fichier versionné permet de relire les hypothèses lors d’une modification de flux, au lieu de chercher un PDF dans une nécropole documentaire.

threat-model/export-api.yaml
asset: export-donnees-client
boundary: internet-vers-api-interne
threats:
- stride: Spoofing # Usurpation d'un utilisateur ou d'un service
scenario: Rejeu d'un jeton d'accès volé sur un réseau non fiable
mitigation:
- Validation de l'émetteur, de l'audience et de l'expiration du jeton
- Durée de vie courte et rotation des clés de signature
- Authentification renforcée pour déclencher un export
evidence:
- test-integration: token_wrong_audience_is_rejected
- metric: auth_token_validation_failures_total
- stride: Elevation of Privilege # Accès à l'export d'un autre locataire
scenario: Modification de l'identifiant de ressource dans l'URL
mitigation:
- Autorisation côté serveur sur la ressource et le locataire
- Identifiants non prédictibles, sans les confondre avec un contrôle d'accès
evidence:
- test-integration: cross_tenant_export_is_forbidden

L’identifiant non prédictible réduit l’énumération opportuniste, mais ne constitue jamais une autorisation. Cette confusion produit des incidents très calmes : tout fonctionne, tous les tests nominalement passent, puis un identifiant apparaît dans une trace, un historique ou une URL partagée. Le contrôle d’accès doit donc porter sur l’identité authentifiée et la ressource demandée.

Les preuves listées dans le registre doivent être reliées à l’intégration continue. Une menace sans test ou sans métrique est une intention. Une intention n’arrête aucune requête.

Exploitation : secrets, rotation, supervision et reprise

Section intitulée « Exploitation : secrets, rotation, supervision et reprise »

Le threat model doit nommer les secrets nécessaires au mécanisme : clés de signature, certificats, mots de passe de comptes techniques, clés de chiffrement de données, jetons d’accès à un coffre. Pour chaque secret, définir le propriétaire, le système de stockage, le périmètre d’accès, la durée de vie, le mécanisme de rotation et le comportement en cas d’indisponibilité.

Une rotation de clé de signature exige que les validateurs acceptent temporairement l’ancienne et la nouvelle clé, avec un identifiant de clé dans le jeton ou le message signé. Retirer l’ancienne clé avant expiration des jetons invalide des sessions légitimes. La conserver indéfiniment annule la rotation. Les deux erreurs sont fréquentes parce que le mécanisme semble minuscule sur un diagramme.

La supervision doit couvrir les contre-mesures, pas seulement la santé des processus : échecs d’autorisation, dépassements de quota, refus de validation de certificat, accès au coffre de secrets, exports inhabituels, modifications de politique et erreurs de restauration. Une alerte sur le taux d’erreur global ne distingue pas une attaque par rejeu d’une panne de résolution de noms. Les deux méritent des réponses différentes, même si le graphique est très rouge.

Les sauvegardes doivent inclure les métadonnées nécessaires à la restauration : versions de schéma, politiques d’autorisation, références de clés et journaux indispensables à l’audit. Une sauvegarde chiffrée dont la clé a été détruite est cryptographiquement impeccable et opérationnellement décorative. Tester la restauration dans un environnement séparé, avec des identités et des clés de récupération prévues, fait partie de la contre-mesure contre la perte de disponibilité.

Sans threat modeling avant le développement, les frontières de confiance, les flux et les actifs ne sont jamais posés au moment où l’architecture peut encore les prendre en compte. Les décisions de conception se figent alors en dépendances coûteuses, et les défauts structurels ne se découvrent qu’à l’exploitation, quand les corriger implique de reconstruire. L’absence de cette grille laisse passer des catégories entières de risques que STRIDE aurait rendues visibles : usurpation, altération, répudiation, divulgation, déni de service, élévation de privilège. On découvre trop tard qu’une porte donne directement sur la rue, qu’une action critique n’est ni authentifiée ni journalisée, ou qu’une frontière supposée n’existe pas dans le code. Rattraper ces manques après coup coûte davantage et laisse souvent des compromis permanents, faute d’avoir vérifié les sorties et les zones sensibles avant de couler le béton.

Avant d’écrire le programme, l’équipe décrit ce que le futur service reçoit, traite, stocke et envoie. Elle note aussi les personnes, applications et machines qui peuvent lui parler. Entre deux parties qui ne se font pas totalement confiance, elle marque une séparation. Cette séparation oblige à vérifier l’identité, les droits et le contenu reçu.

Ensuite, elle cherche plusieurs familles de problèmes : quelqu’un qui se fait passer pour un autre, quelqu’un qui modifie une information, quelqu’un qui nie une action, quelqu’un qui lit une donnée protégée, quelqu’un qui bloque le service, ou quelqu’un qui obtient plus de droits que prévu. Pour chaque problème retenu, elle écrit les conditions nécessaires à l’attaque, le dommage possible, la protection choisie et la preuve attendue.

Cette preuve peut être un test automatique, un journal consultable ou une alerte. Si le programme refuse l’accès d’un compte à des données qui ne lui appartiennent pas, un test doit le vérifier. Si une clé permet de prouver l’identité d’un service, il faut prévoir où elle est gardée, quand elle change et ce qui arrive si elle disparaît.

Le document n’empêche rien par lui-même. Il sert à imposer des décisions avant que le code les rende coûteuses à modifier. Si une protection manque, il faut soit l’ajouter au plan, soit accepter explicitement le risque. Ignorer le sujet ne le fait pas disparaître, ce serait trop pratique.

À lire aussi

Pages voisines