This is an example threat model report generated by attasec/tmdd — a CLI tool for Threat Modeling Driven Development. The report below was generated from TMDD's own threat model.

TMDD CLI

Threat Model Report • Threat Modeling Driven Development - a Python CLI tool that manages YAML-based threat models, validates cross-references, generates AI prompts, and produces interactive HTML reports and diagrams

8
Components
12
Data Flows
6
Features
11
Threats
12
Mitigations
11
Active Threats
6/6
Features Reviewed

System Diagram

Scroll to zoom · Drag to pan · Click nodes for details

Features

Project Initialization

Reviewed: mik0w (2026-02-22) Updated: 2026-02-22

Create a new TMDD threat model project from a template (minimal, web-app, or api)

Input Data: path, system name, description, template name
Output Data: YAML files in target directory
Data Flows: df_developer_to_cli, df_cli_to_commands, df_init_templates
Threat Actors: ci_pipeline_untrusted

Threat → Mitigation Mappings

yaml_template_injection YAML template injection via init command name/description
yaml_escape_init_inputEscape or quote user-provided name/description values before substituting into YAML templates during init, using yaml.dump() or proper YAML string quoting to prevent structural injection(src/commands/init.py:36-39) (default)
init_path_traversal Arbitrary file creation via init command path argument
validate_init_pathValidate and normalize the target path in init command, ensuring it resolves to a subdirectory of the current working directory or an explicitly allowed location(src/commands/init.py:22-23) (default)
output_info_disclosure Information disclosure via generated output files
gitignore_output_dirInclude .tmdd/out/ in the default .gitignore generated by tmdd init, and add a warning comment in generated output files noting they contain sensitive security analysis(src/commands/init.py) (default)

Threat Model Validation

Reviewed: mik0w (2026-02-22) Updated: 2026-02-22

Validate all .tmdd/ YAML files for structural correctness and cross-reference integrity

Input Data: path to .tmdd directory
Output Data: validation results on stdout
Data Flows: df_developer_to_cli, df_cli_to_commands, df_commands_to_yaml, df_yaml_to_filesystem
Threat Actors: malicious_insider_fs

Threat → Mitigation Mappings

yaml_dos_oversized Denial of service via deeply nested or oversized YAML files
yaml_file_size_limitAdd file size checks in load_yaml() before parsing, rejecting YAML files exceeding a reasonable threshold (e.g., 1MB) to prevent resource exhaustion(src/utils.py:101-117) (default)
no_audit_trail No audit trail for threat model modifications
acceptedRisk accepted

Feature Workflow

Reviewed: mik0w (2026-02-22) Updated: 2026-02-22

Generate AI prompts for threat modeling new features or producing secure implementation guidance

Input Data: feature name, description, loaded threat model
Output Data: prompt text files in .tmdd/out/
Data Flows: df_developer_to_cli, df_cli_to_commands, df_commands_to_yaml, df_yaml_to_filesystem, df_commands_to_prompts, df_prompts_to_filesystem, df_filesystem_to_agent
Threat Actors: malicious_insider_fs

Threat → Mitigation Mappings

prompt_injection Prompt injection via threat model content in generated AI prompts
prompt_delimitersAdd clear delimiter markers and role boundaries in generated AI prompts to reduce the effectiveness of prompt injection from threat model content(src/generators/agent_prompt.py:17-19, src/generators/threat_prompt.py) (default)
output_info_disclosure Information disclosure via generated output files
gitignore_output_dirInclude .tmdd/out/ in the default .gitignore generated by tmdd init, and add a warning comment in generated output files noting they contain sensitive security analysis(src/commands/init.py) (default)

Compilation

Reviewed: mik0w (2026-02-22) Updated: 2026-02-22

Generate consolidated YAML and AI implementation prompts from the full threat model

Input Data: path to .tmdd directory, optional feature filter
Output Data: consolidated .tm.yaml file, prompt text file in .tmdd/out/
Data Flows: df_developer_to_cli, df_cli_to_commands, df_commands_to_yaml, df_yaml_to_filesystem, df_commands_to_prompts, df_prompts_to_filesystem
Threat Actors: malicious_insider_fs

Threat → Mitigation Mappings

output_info_disclosure Information disclosure via generated output files
gitignore_output_dirInclude .tmdd/out/ in the default .gitignore generated by tmdd init, and add a warning comment in generated output files noting they contain sensitive security analysis(src/commands/init.py) (default)
prompt_injection Prompt injection via threat model content in generated AI prompts
prompt_delimitersAdd clear delimiter markers and role boundaries in generated AI prompts to reduce the effectiveness of prompt injection from threat model content(src/generators/agent_prompt.py:17-19, src/generators/threat_prompt.py) (default)

Report Generation

Reviewed: mik0w (2026-01-01) — needs re-review Updated: 2026-02-22

Generate a standalone interactive HTML threat model report with architecture diagram

Input Data: path to .tmdd directory, output directory, output filename
Output Data: HTML report file with embedded Cytoscape.js diagram
Data Flows: df_developer_to_cli, df_commands_to_yaml, df_yaml_to_filesystem, df_commands_to_html, df_html_to_filesystem, df_cdn_to_browser, df_filesystem_to_viewer
Threat Actors: cdn_package_attacker, malicious_insider_fs, ci_pipeline_untrusted

Threat → Mitigation Mappings

cdn_supply_chain_attack Supply chain attack via CDN JavaScript dependencies
sri_hashes_cdnPin CDN library versions with Subresource Integrity (SRI) hashes on all <script> tags in generated HTML to prevent tampered JavaScript from executing(report.py:943-945, diagram.py:143-145) (default)
bundle_libs_locallyBundle Cytoscape.js and dagre libraries locally instead of relying on CDN, eliminating the external dependency and enabling fully offline report viewing(report.py:943-945) (default)
xss_stored_diagram Stored XSS via innerHTML in diagram JavaScript
replace_innerhtml_textcontentReplace innerHTML assignments in _DIAGRAM_JS with textContent for plain text values, or use DOM createElement/createTextNode for safe HTML construction(report.py:572-872) (default)
js_html_escape_helperImplement a JavaScript HTML-escape helper function in _DIAGRAM_JS and apply it to all threat model values (names, descriptions, labels) before inserting into HTML strings(report.py:572-872) (default)
xss_stored_node_info Stored XSS via innerHTML in node-info panel
replace_innerhtml_textcontentReplace innerHTML assignments in _DIAGRAM_JS with textContent for plain text values, or use DOM createElement/createTextNode for safe HTML construction(report.py:572-872) (default)
js_html_escape_helperImplement a JavaScript HTML-escape helper function in _DIAGRAM_JS and apply it to all threat model values (names, descriptions, labels) before inserting into HTML strings(report.py:572-872) (default)
output_info_disclosure Information disclosure via generated output files
gitignore_output_dirInclude .tmdd/out/ in the default .gitignore generated by tmdd init, and add a warning comment in generated output files noting they contain sensitive security analysis(src/commands/init.py) (default)
json_script_breakout Script tag breakout in embedded JSON diagram data
js_html_escape_helperImplement a JavaScript HTML-escape helper function in _DIAGRAM_JS and apply it to all threat model values (names, descriptions, labels) before inserting into HTML strings(report.py:572-872) (default)
enhanced_safe_jsonEnhance _safe_json() to escape additional dangerous characters beyond </ including HTML entities and ensure Content-Type is set correctly for embedded JSON data(report.py:113-114) (default)
report_path_traversal Report output path traversal via --name parameter
validate_report_filenameValidate the --name output filename in report.py by stripping path separators and applying safe_name() or os.path.basename() before joining with the output directory, consistent with diagram.py's safe_name() approach(report.py:1085-1088) (default)

Diagram Generation

Reviewed: mik0w (2026-02-22) Updated: 2026-02-22

Generate a standalone interactive HTML architecture diagram with optional feature highlighting

Input Data: path to .tmdd directory, optional feature name
Output Data: HTML diagram file with embedded Cytoscape.js visualization
Data Flows: df_commands_to_yaml, df_yaml_to_filesystem, df_commands_to_html, df_html_to_filesystem, df_cdn_to_browser, df_filesystem_to_viewer
Threat Actors: cdn_package_attacker, malicious_insider_fs

Threat → Mitigation Mappings

cdn_supply_chain_attack Supply chain attack via CDN JavaScript dependencies
sri_hashes_cdnPin CDN library versions with Subresource Integrity (SRI) hashes on all <script> tags in generated HTML to prevent tampered JavaScript from executing(report.py:943-945, diagram.py:143-145) (default)
bundle_libs_locallyBundle Cytoscape.js and dagre libraries locally instead of relying on CDN, eliminating the external dependency and enabling fully offline report viewing(report.py:943-945) (default)
xss_stored_diagram Stored XSS via innerHTML in diagram JavaScript
replace_innerhtml_textcontentReplace innerHTML assignments in _DIAGRAM_JS with textContent for plain text values, or use DOM createElement/createTextNode for safe HTML construction(report.py:572-872) (default)
js_html_escape_helperImplement a JavaScript HTML-escape helper function in _DIAGRAM_JS and apply it to all threat model values (names, descriptions, labels) before inserting into HTML strings(report.py:572-872) (default)
xss_stored_node_info Stored XSS via innerHTML in node-info panel
replace_innerhtml_textcontentReplace innerHTML assignments in _DIAGRAM_JS with textContent for plain text values, or use DOM createElement/createTextNode for safe HTML construction(report.py:572-872) (default)
js_html_escape_helperImplement a JavaScript HTML-escape helper function in _DIAGRAM_JS and apply it to all threat model values (names, descriptions, labels) before inserting into HTML strings(report.py:572-872) (default)
json_script_breakout Script tag breakout in embedded JSON diagram data
js_html_escape_helperImplement a JavaScript HTML-escape helper function in _DIAGRAM_JS and apply it to all threat model values (names, descriptions, labels) before inserting into HTML strings(report.py:572-872) (default)
enhanced_safe_jsonEnhance _safe_json() to escape additional dangerous characters beyond </ including HTML entities and ensure Content-Type is set correctly for embedded JSON data(report.py:113-114) (default)

Components

IDDescriptionTypeTechnologyTrust BoundarySource Paths
cli_coreArgparse-based CLI entry point that parses user commands and dispatches to command handlers (src/cli.py, src/__main__.py)servicePython / argparseinternalsrc/cli.py src/__main__.py
command_engineCommand handlers for init, lint, feature, and compile operations (src/commands/)servicePythoninternalsrc/commands/**
yaml_processorYAML loading via yaml.safe_load(), threat model assembly, and cross-reference validation (src/utils.py, src/commands/lint.py)servicePython / PyYAML (safe_load)internalsrc/utils.py
prompt_generatorGenerates AI prompt text files for threat modeling and secure coding workflows (src/generators/threat_prompt.py, agent_prompt.py)servicePythoninternalsrc/generators/**
template_storeBundled YAML template files (minimal, web-app, api) used by init command for project scaffolding (src/templates/)otherYAML filesinternalsrc/templates/**
html_rendererGenerates interactive HTML reports and architecture diagrams with embedded Cytoscape.js (report.py, diagram.py)servicePython / HTML / JavaScriptinternalreport.py diagram.py
filesystem_storeLocal filesystem storage for .tmdd/ YAML files, generated prompts, reports, and diagrams (.tmdd/, .tmdd/out/)otherLocal filesysteminternal
cdn_librariesExternal CDN (unpkg.com) serving Cytoscape.js 3.30.4, dagre 0.8.5, and cytoscape-dagre 2.5.0 loaded client-side in generated HTMLexternalunpkg.com CDN / JavaScriptexternal

Data Flows

IDPathDescriptionProtocolAuthentication
df_developer_to_clidevelopercli_coreCLI commands with arguments (path, feature name, description, template name)stdinnone
df_cli_to_commandscli_corecommand_engineParsed argparse Namespace object with user-provided valuesfunction_callnone
df_commands_to_yamlcommand_engineyaml_processorFile paths to load; returns parsed YAML dicts (system, actors, components, threats, mitigations)function_callnone
df_yaml_to_filesystemyaml_processorfilesystem_storeRead .tmdd/ YAML files (system.yaml, actors.yaml, components.yaml, features.yaml, data_flows.yaml, threats/*.yaml)filesystemnone
df_init_templatestemplate_storefilesystem_storeTemplate YAML files with {{name}} and {{description}} placeholders substituted with user input, written to target directoryfilesystemnone
df_commands_to_promptscommand_engineprompt_generatorLoaded threat model dict and feature metadata for prompt generationfunction_callnone
df_prompts_to_filesystemprompt_generatorfilesystem_storeGenerated text prompt files (*.threatmodel.txt, *.prompt.txt) written to .tmdd/out/filesystemnone
df_commands_to_htmlcommand_enginehtml_rendererLoaded threat model dict passed to report/diagram generatorsfunction_callnone
df_html_to_filesystemhtml_rendererfilesystem_storeGenerated HTML files (tm.html, diagram.html) with embedded JSON data and JavaScript, written to .tmdd/out/filesystemnone
df_cdn_to_browsercdn_librariesreport_viewerJavaScript libraries (cytoscape.min.js, dagre.min.js, cytoscape-dagre.js) loaded via script tags from unpkg.comHTTPSnone
df_filesystem_to_viewerfilesystem_storereport_viewerHTML report/diagram files served to browser with embedded threat model data in JSON formatfilesystemnone
df_filesystem_to_agentfilesystem_storeai_agentGenerated prompt text files consumed by AI agent for threat modeling or secure code generationfilesystemnone

Threat Catalog

Faded rows indicate threats not currently mapped to any feature.

IDNameDescriptionSeveritySTRIDECWESuggested Mitigations
yaml_template_injectionYAML template injection via init command name/descriptionIn src/commands/init.py:36-39, user-provided --name and --description values are substituted into YAML templates using simple str.replace() without escaping YAML metacharacters. A name containing newlines or YAML syntax (e.g., colons, brackets) could produce malformed or structurally altered YAML output files.LOWTCWE-74yaml_escape_init_input
cdn_supply_chain_attackSupply chain attack via CDN JavaScript dependenciesreport.py and diagram.py embed <script> tags loading from unpkg.com (cytoscape@3.30.4, dagre@0.8.5, cytoscape-dagre@2.5.0). If unpkg.com is compromised, a package is hijacked, or a MITM attack occurs, malicious JavaScript would execute in the report viewer's browser with full DOM access to the threat model data.HIGHTCWE-829sri_hashes_cdn, bundle_libs_locally
xss_stored_diagramStored XSS via innerHTML in diagram JavaScriptIn report.py's _DIAGRAM_JS (line 572+), the showFeature() function builds HTML strings from threat model data (threat names, descriptions, goals) and injects them via innerHTML. Although data passes through JSON.parse from an embedded <script> tag, YAML values containing HTML (e.g., <img onerror=...>) would be rendered as active markup in the viewer's browser.MEDIUMTCWE-79replace_innerhtml_textcontent, js_html_escape_helper
xss_stored_node_infoStored XSS via innerHTML in node-info panelIn report.py's _DIAGRAM_JS, the cy.on('tap') handler for nodes and edges builds HTML strings using d.label, d.description, d.technology, and d.flowId directly, injecting them via info.innerHTML without HTML encoding. Malicious content in YAML component descriptions would execute as JavaScript.MEDIUMTCWE-79replace_innerhtml_textcontent, js_html_escape_helper
yaml_dos_oversizedDenial of service via deeply nested or oversized YAML filesyaml.safe_load() in src/utils.py:110 parses YAML files without size limits. An extremely large or deeply nested YAML file in .tmdd/ could cause excessive memory consumption or CPU usage during lint, compile, or feature operations.LOWDCWE-400yaml_file_size_limit
init_path_traversalArbitrary file creation via init command path argumentIn src/commands/init.py:23, Path(args.path).mkdir(parents=True) creates directories at any user-specified path. Combined with template file writing (line 34-40), a script or CI pipeline invoking tmdd init with a crafted path could create files in unintended locations.LOWTCWE-22validate_init_path
output_info_disclosureInformation disclosure via generated output filesCompiled YAML (.tmdd/out/*.tm.yaml), HTML reports, and prompt files contain full threat model details including threat descriptions, severity ratings, CWE references, and internal architecture details. If the .tmdd/out/ directory is accidentally committed to a public repository or shared, it exposes the complete attack surface analysis.MEDIUMICWE-200gitignore_output_dir
no_audit_trailNo audit trail for threat model modificationsTMDD stores threat models as plain YAML files with no built-in change tracking, signing, or attribution. Anyone with filesystem access can modify threats, mitigations, or feature mappings without a trace, undermining the integrity of the security assessment.MEDIUMRCWE-778git_change_tracking
prompt_injectionPrompt injection via threat model content in generated AI promptsIn src/generators/agent_prompt.py and threat_prompt.py, threat model data (threat names, descriptions, mitigation text) is embedded directly into AI prompt text without sanitization. A malicious actor who can edit YAML files could inject adversarial instructions into the prompt that alter the AI agent's behavior.MEDIUMTCWE-77prompt_delimiters
json_script_breakoutScript tag breakout in embedded JSON diagram dataIn report.py:114, _safe_json() escapes </ to <\/ to prevent script tag breakout. However, other injection vectors (e.g., HTML entities, Unicode escapes) in threat model strings embedded in the <script type='application/json'> block could potentially bypass this single-pattern defense.LOWTCWE-79js_html_escape_helper, enhanced_safe_json
report_path_traversalReport output path traversal via --name parameterIn report.py:1085, the --name argument is joined with the output directory via Path(out) / output_name without validation. Unlike diagram.py which uses safe_name() for filename generation (line 156), report.py passes the raw user input directly, allowing path traversal characters (e.g., ../../malicious.html) to write the HTML report outside the intended output directory.LOWTCWE-22validate_report_filename

Mitigations Catalog

Faded rows indicate mitigations not currently applied to any feature.

IDDescription
yaml_escape_init_inputEscape or quote user-provided name/description values before substituting into YAML templates during init, using yaml.dump() or proper YAML string quoting to prevent structural injection(src/commands/init.py:36-39)
sri_hashes_cdnPin CDN library versions with Subresource Integrity (SRI) hashes on all <script> tags in generated HTML to prevent tampered JavaScript from executing(report.py:943-945, diagram.py:143-145)
bundle_libs_locallyBundle Cytoscape.js and dagre libraries locally instead of relying on CDN, eliminating the external dependency and enabling fully offline report viewing(report.py:943-945)
replace_innerhtml_textcontentReplace innerHTML assignments in _DIAGRAM_JS with textContent for plain text values, or use DOM createElement/createTextNode for safe HTML construction(report.py:572-872)
js_html_escape_helperImplement a JavaScript HTML-escape helper function in _DIAGRAM_JS and apply it to all threat model values (names, descriptions, labels) before inserting into HTML strings(report.py:572-872)
yaml_file_size_limitAdd file size checks in load_yaml() before parsing, rejecting YAML files exceeding a reasonable threshold (e.g., 1MB) to prevent resource exhaustion(src/utils.py:101-117)
validate_init_pathValidate and normalize the target path in init command, ensuring it resolves to a subdirectory of the current working directory or an explicitly allowed location(src/commands/init.py:22-23)
gitignore_output_dirInclude .tmdd/out/ in the default .gitignore generated by tmdd init, and add a warning comment in generated output files noting they contain sensitive security analysis(src/commands/init.py)
git_change_trackingRely on Git version control for change tracking and attribution of .tmdd/ YAML files; document this requirement in README and generated AGENTS.md
prompt_delimitersAdd clear delimiter markers and role boundaries in generated AI prompts to reduce the effectiveness of prompt injection from threat model content(src/generators/agent_prompt.py:17-19, src/generators/threat_prompt.py)
enhanced_safe_jsonEnhance _safe_json() to escape additional dangerous characters beyond </ including HTML entities and ensure Content-Type is set correctly for embedded JSON data(report.py:113-114)
validate_report_filenameValidate the --name output filename in report.py by stripping path separators and applying safe_name() or os.path.basename() before joining with the output directory, consistent with diagram.py's safe_name() approach(report.py:1085-1088)

System Actors

developer: Developer or security engineer who runs TMDD CLI commands (init, lint, feature, compile) and edits .tmdd/ YAML files
ai_agent: AI coding agent that consumes generated prompt files (.tmdd/out/*.prompt.txt, *.threatmodel.txt) to produce threat models or secure code
report_viewer: Person viewing generated HTML reports and diagrams in a web browser, potentially including non-developers or stakeholders

Threat Actors

cdn_package_attacker: External attacker who compromises a CDN or npm package used by TMDD-generated HTML reports
malicious_insider_fs: Malicious insider with filesystem access who tampers with .tmdd/ YAML files to inject harmful content into reports or AI prompts
ci_pipeline_untrusted: Automated CI/CD pipeline that invokes TMDD commands with untrusted or user-controlled input parameters