Générateur Microsoft Threat Modeling Tool (.tm7)
Tu génères des fichiers .tm7 valides pour l'outil Microsoft Threat Modeling Tool (v7.3+). Un fichier .tm7 n'est pas du XML générique — c'est un document WCF DataContractSerializer avec un namespace et une structure d'éléments exacts. Si la structure est incorrecte, l'outil refuse d'ouvrir le fichier avec :
« File is not an actual threat model or the threat model may be corrupted. »
Ton travail est de traduire un système décrit (composants, magasins de données, acteurs externes, flux de données, limites de confiance) en un diagramme plus des menaces STRIDE, sérialisés dans le format .tm7 exact décrit ci-dessous.
Workflow
Quand on te demande de produire un fichier .tm7 :
- Modélise le système. Identifie les éléments :
- Processus (applications web, services, fonctions) →
StencilEllipse,GE.P - Magasins de données (bases de données, caches, files d'attente, blobs) →
StencilParallelLines,GE.DS - Interacteurs externes (utilisateurs, navigateurs, systèmes tiers) →
StencilRectangle,GE.EI - Limites de confiance →
BorderBoundary,GE.TB - Flux de données reliant les éléments ci-dessus →
Connector,GE.DF
- Processus (applications web, services, fonctions) →
- Assigne un UUID unique en minuscules (p. ex.
148ade68-5c80-40f3-8e1f-4e2cabdb5991) à chaque stencil et chaque flux. N'utilise jamais d'identifiants lisibles par l'homme commeusers-browser. - Définis les coordonnées (
Left/Top/Width/Height) pour que les stencils ne se chevauchent pas. - Génère des menaces STRIDE par interaction et place-les dans
<ThreatInstances>. - Sérialise en utilisant la structure de ce guide, en miroir de
assets/example-minimal.tm7. - Valide par rapport à la checklist « Common Mistakes » avant de retourner le fichier.
- Écris le fichier sans déclaration XML et sans indentation pretty-print (un flux XML continu unique est ce que le sérialiseur émet).
Ouvre toujours assets/example-minimal.tm7 en premier et adapte-le — réutilise son squelette de sérialisation exact et ne change que les types de stencil, les noms, les coordonnées, les flux et les menaces.
CRITIQUE : Format de sérialisation
Les fichiers TM7 utilisent XML WCF DataContractSerializer, pas du XML standard.
Le fichier DOIT commencer par cet élément racine exact — pas de déclaration <?xml?> :
<ThreatModel xmlns="http://schemas.datacontract.org/2004/07/ThreatModeling.Model" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
N'utilise JAMAIS :
<?xml version="1.0" encoding="utf-8"?>— provoque un échec de désérialisation.xmlns:xsi/xmlns:xsd— ce sont des namespaces XML standard, pas des namespaces DataContract.- Des éléments inventés tels que
<SecurityGaps>ou<Mitigations>— ils n'existent pas dans le schéma TM7.
Remarque :
<MetaInformation>(avec des enfants comme<Owner>,<Contributors>,<Reviewer>,<Assumptions>,<ExternalDependencies>,<HighLevelSystemDescription>,<ThreatModelName>),<Notes>et<KnowledgeBase>font partie du vrai schéma et sont émis par l'outil — conserve-les (voir la structure ci-dessous etassets/example-minimal.tm7). N'invente simplement pas d'éléments que l'outil ne produit jamais.
Préfixes de namespace requis
| Préfixe | URI | Utilisé pour |
|---|---|---|
| (défaut) | http://schemas.datacontract.org/2004/07/ThreatModeling.Model |
ThreatModel racine |
xmlns:i |
http://www.w3.org/2001/XMLSchema-instance |
Attributs de type |
xmlns:z |
http://schemas.microsoft.com/2003/10/Serialization/ |
IDs de référence (z:Id) |
xmlns:a |
http://schemas.microsoft.com/2003/10/Serialization/Arrays |
Arrays / collections |
xmlns:b |
http://schemas.datacontract.org/2004/07/ThreatModeling.KnowledgeBase |
Propriétés de stencil |
xmlns:c |
http://www.w3.org/2001/XMLSchema |
Valeurs de type primitif |
Structure de fichier (ordre correct)
Une exportation d'outil complète contient, dans cet ordre : DrawingSurfaceList, MetaInformation, Notes, ThreatInstances, ThreatMetaData (souvent vide/auto-fermant), puis le grand KnowledgeBase générique comme frère de premier niveau (pas imbriqué dans ThreatMetaData), et enfin Profile.
<ThreatModel xmlns="..." xmlns:i="...">
<DrawingSurfaceList>
<DrawingSurfaceModel z:Id="i1" xmlns:z="...">
<GenericTypeId xmlns="...Abstracts">DRAWINGSURFACE</GenericTypeId>
<Guid xmlns="...Abstracts">{guid}</Guid>
<Properties xmlns="...Abstracts" xmlns:a="...Arrays">...</Properties>
<TypeId xmlns="...Abstracts">DRAWINGSURFACE</TypeId>
<Borders xmlns:a="...Arrays">
<!-- Éléments stencil : processus, magasins de données, entités externes, limites -->
</Borders>
<Lines xmlns:a="...Arrays">
<!-- Lignes de flux de données reliant les stencils -->
</Lines>
<Notes xmlns:a="...Arrays"/>
</DrawingSurfaceModel>
</DrawingSurfaceList>
<MetaInformation>
<!-- Owner, Contributors, Reviewer, Assumptions, ThreatModelName, etc. -->
</MetaInformation>
<Notes xmlns:a="...Arrays"/>
<ThreatInstances>
<!-- Entrées de menace -->
</ThreatInstances>
<ThreatMetaData/>
<KnowledgeBase z:Id="i21" xmlns:a="...ThreatModeling.KnowledgeBase" xmlns:z="...">
<!-- Catalogue générique de stencils SDL / menaces — frère de premier niveau de ThreatMetaData -->
</KnowledgeBase>
<Profile>
<PromptedKb xmlns=""/>
</Profile>
</ThreatModel>
Le
<KnowledgeBase>(le catalogue générique de stencils SDL / menaces) est volumineux mais requis — l'outil l'utilise pour résoudre chaqueTypeIdde stencil. C'est un frère de premier niveau placé aprèsThreatMetaDataet avantProfile, pas imbriqué dansThreatMetaData. Réutilise-le textuellement deassets/example-minimal.tm7; ajoute uniquement des stencils dont leTypeIdapparaît déjà dans ce KnowledgeBase.
Éléments stencil
Chaque stencil dans <Borders> est enveloppé dans <a:KeyValueOfguidanyType> :
<a:KeyValueOfguidanyType>
<a:Key>{guid}</a:Key>
<a:Value z:Id="i2" i:type="StencilEllipse">
<GenericTypeId xmlns="...Abstracts">GE.P</GenericTypeId>
<Guid xmlns="...Abstracts">{guid}</Guid>
<Properties xmlns="...Abstracts">
<a:anyType i:type="b:HeaderDisplayAttribute" xmlns:b="...KnowledgeBase">
<b:DisplayName>Web Application</b:DisplayName>
<b:Name/>
<b:Value i:nil="true"/>
</a:anyType>
<a:anyType i:type="b:StringDisplayAttribute" xmlns:b="...KnowledgeBase">
<b:DisplayName>Name</b:DisplayName>
<b:Name/>
<b:Value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">My Component</b:Value>
</a:anyType>
<!-- Out Of Scope, Reason, attributs configurables -->
</Properties>
<TypeId xmlns="...Abstracts">SE.P.TMCore.WebApp</TypeId>
<Height xmlns="...Abstracts">100</Height>
<Left xmlns="...Abstracts">400</Left>
<StrokeDashArray i:nil="true" xmlns="...Abstracts"/>
<StrokeThickness xmlns="...Abstracts">1</StrokeThickness>
<Top xmlns="...Abstracts">200</Top>
<Width xmlns="...Abstracts">100</Width>
</a:Value>
</a:KeyValueOfguidanyType>
Types de formes de stencil
| Forme | i:type |
GenericTypeId |
Description |
|---|---|---|---|
| Processus (cercle) | StencilEllipse |
GE.P |
Processus, applications web, services |
| Magasin de données (lignes parallèles) | StencilParallelLines |
GE.DS |
Bases de données, stockage, caches |
| Interacteur externe (rectangle) | StencilRectangle |
GE.EI |
Utilisateurs, systèmes externes |
| Limite de confiance | BorderBoundary |
GE.TB |
Limites de confiance |
Valeurs TypeId communes (base de connaissances SDL TM)
TypeId |
Composant |
|---|---|
SE.P.TMCore.WebApp |
Web Application |
SE.P.TMCore.AzureAppServiceWebApp |
Azure App Service Web App |
SE.P.TMCore.AzureEventHub |
Azure Event Hub |
SE.P.TMCore.DynamicsCRM |
Dynamics CRM |
SE.DS.TMCore.SQL |
SQL Database |
SE.DS.TMCore.AzureSQLDB |
Azure SQL Database |
SE.EI.TMCore.Browser |
Browser |
SE.EI.TMCore.Mobile |
Mobile Client |
Lignes de flux de données
Les lignes dans <Lines> utilisent aussi <a:KeyValueOfguidanyType>, avec i:type="Connector" :
<a:KeyValueOfguidanyType>
<a:Key>{line-guid}</a:Key>
<a:Value z:Id="i10" i:type="Connector">
<GenericTypeId xmlns="...Abstracts">GE.DF</GenericTypeId>
<Guid xmlns="...Abstracts">{line-guid}</Guid>
<Properties xmlns="...Abstracts">...</Properties>
<TypeId xmlns="...Abstracts">SE.DF.TMCore.Request</TypeId>
<HandleX xmlns="...Abstracts">0</HandleX>
<HandleY xmlns="...Abstracts">0</HandleY>
<SourceGuid xmlns="...Abstracts">{source-stencil-guid}</SourceGuid>
<SourceX xmlns="...Abstracts">0</SourceX>
<SourceY xmlns="...Abstracts">0</SourceY>
<TargetGuid xmlns="...Abstracts">{target-stencil-guid}</TargetGuid>
<TargetX xmlns="...Abstracts">0</TargetX>
<TargetY xmlns="...Abstracts">0</TargetY>
</a:Value>
</a:KeyValueOfguidanyType>
Types d'attributs de propriété
Les propriétés utilisent des éléments <a:anyType> typés :
i:type |
Objectif | Valeur |
|---|---|---|
b:HeaderDisplayAttribute |
En-tête de section | i:nil="true" |
b:StringDisplayAttribute |
Valeur texte (Name, Reason) | i:type="c:string" |
b:BooleanDisplayAttribute |
Booléen (Out Of Scope) | i:type="c:boolean" |
b:ListDisplayAttribute |
Liste déroulante | A <b:SelectedIndex> |
Instances de menace
Les menaces vont dans <ThreatInstances> en utilisant <a:KeyValueOfstringThreatpc_P0_PhOB> (remarque le suffixe exact PhOB). Contrairement aux stencils, les champs <a:Value> de la menace sont préfixés b: (le namespace ThreatModeling.KnowledgeBase), et la <a:Key> de la menace est la concaténation littérale TH<id> + <SourceGuid> + <FlowGuid> + <TargetGuid> :
<ThreatInstances xmlns:a="...Arrays">
<a:KeyValueOfstringThreatpc_P0_PhOB>
<a:Key>TH117{source-guid}{flow-guid}{target-guid}</a:Key>
<a:Value xmlns:b="...KnowledgeBase">
<b:ChangedBy/>
<b:DrawingSurfaceGuid>{drawing-surface-guid}</b:DrawingSurfaceGuid>
<b:FlowGuid>{flow-guid}</b:FlowGuid>
<b:Id>32</b:Id>
<b:InteractionKey>{source-guid}:{flow-guid}:{target-guid}</b:InteractionKey>
<b:InteractionString i:nil="true"/>
<b:ModifiedAt>2025-01-01T00:00:00</b:ModifiedAt>
<b:Priority>High</b:Priority>
<b:Properties>
<a:KeyValueOfstringstring>
<a:Key>Title</a:Key>
<a:Value>An adversary may spoof the user and gain access</a:Value>
</a:KeyValueOfstringstring>
<a:KeyValueOfstringstring>
<a:Key>UserThreatCategory</a:Key>
<a:Value>Spoofing</a:Value>
</a:KeyValueOfstringstring>
<a:KeyValueOfstringstring>
<a:Key>UserThreatShortDescription</a:Key>
<a:Value>Spoofing is when a process or entity is something other than its claimed identity.</a:Value>
</a:KeyValueOfstringstring>
<a:KeyValueOfstringstring>
<a:Key>PossibleMitigations</a:Key>
<a:Value>Enable multi-factor authentication and least-privilege access control.</a:Value>
</a:KeyValueOfstringstring>
<a:KeyValueOfstringstring>
<a:Key>Priority</a:Key>
<a:Value>High</a:Value>
</a:KeyValueOfstringstring>
<a:KeyValueOfstringstring>
<a:Key>SDLPhase</a:Key>
<a:Value>Design</a:Value>
</a:KeyValueOfstringstring>
</b:Properties>
<b:SourceGuid>{source-stencil-guid}</b:SourceGuid>
<b:State>Mitigated</b:State>
<b:StateInformation i:nil="true"/>
<b:TargetGuid>{target-stencil-guid}</b:TargetGuid>
<b:Title i:nil="true"/>
<b:TypeId>TH117</b:TypeId>
<b:Upgraded>false</b:Upgraded>
<b:Wide>false</b:Wide>
</a:Value>
</a:KeyValueOfstringThreatpc_P0_PhOB>
</ThreatInstances>
Chaque GUID doit être résolu : SourceGuid et TargetGuid doivent égaler les valeurs <a:Key> de stencils réels dans <Borders>, et FlowGuid doit égaler la <a:Key> d'un connecteur réel dans <Lines>. Les références en suspens produisent un modèle qui s'ouvre avec des éléments de diagramme manquants.
Utilise les catégories STRIDE standard pour UserThreatCategory : Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege.
Erreurs courantes qui cassent les fichiers TM7
- Ajouter une déclaration
<?xml version="1.0"?>—DataContractSerializern'en émet pas. - Utiliser
xmlns:xsi/xmlns:xsdau lieu des namespaces DataContract. - Utiliser des noms d'éléments simples comme
<Border>,<Line>,<Stencil>— tu dois utiliser les types de wrapper DataContract tels que<a:KeyValueOfguidanyType>. - Inventer des éléments que l'outil n'émet jamais comme
<SecurityGaps>ou<Mitigations>— ils ne sont pas dans le schéma. (<MetaInformation>,<Notes>et<KnowledgeBase>sont valides et doivent être préservés.) - Utiliser des GUIDs lisibles par l'homme comme
users-browserau lieu d'UUIDs réels (p. ex.148ade68-5c80-40f3-8e1f-4e2cabdb5991). - Références en suspens — une
Line, unSourceGuid/TargetGuidde menace ou unFlowGuidde menace qui pointe vers un GUID de stencil/flux qui n'est pas réellement défini dans<Borders>/<Lines>. Chaque référence doit se résoudre à un élément inclus. - Attributs de référence
z:Idmanquants ou dupliqués — chaque objet sérialisé a besoin d'unz:Id, et chaquez:Id(p. ex.i1,i2,i10) doit être unique dans tout le fichier. Quand tu dupliques un bloc de modèle pour ajouter un élément, renumérote toujours sonz:Id(et tout imbriqué) avec des valeurs non utilisées ailleurs ; réutiliser un id crée des IDs d'objet DataContract dupliqués et rend la désérialisation échouée. - Manque
xmlnssur les éléments enfants — chaqueGenericTypeId,Guid,Properties,TypeId, etc. doit porter son proprexmlns="http://schemas.datacontract.org/2004/07/ThreatModeling.Model.Abstracts". - Pretty-printing avec indentation — la sortie correcte est un flux XML continu unique sans retours à la ligne ou indentation ajoutés dans le contenu.
Ressource de référence
Utilise toujours assets/example-minimal.tm7 du répertoire de cette compétence comme référence structurelle. C'est une exportation entièrement synthétique et assainie (pas de données personnelles ou de projet) qui s'ouvre proprement dans l'outil : deux stencils reliés par un flux de données, avec une menace STRIDE dont chaque référence se résout. Adapte les types de stencil, les noms, les propriétés, les coordonnées, les flux de données et les menaces à l'architecture de l'utilisateur, mais ne change jamais le format de sérialisation ou la structure de namespace, et utilise uniquement des valeurs TypeId de stencil qui apparaissent déjà dans son KnowledgeBase fourni. Après la génération, fais mentalement un diff du squelette de ta sortie par rapport à l'exemple pour confirmer que chaque namespace, élément de wrapper et référence GUID correspond.