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
Create a new TMDD threat model project from a template (minimal, web-app, or api)
yaml_template_injection YAML template injection via init command name/descriptionyaml_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 argumentvalidate_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 filesgitignore_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)Validate all .tmdd/ YAML files for structural correctness and cross-reference integrity
yaml_dos_oversized Denial of service via deeply nested or oversized YAML filesyaml_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 modificationsacceptedRisk acceptedGenerate AI prompts for threat modeling new features or producing secure implementation guidance
prompt_injection Prompt injection via threat model content in generated AI promptsprompt_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 filesgitignore_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)Generate consolidated YAML and AI implementation prompts from the full threat model
output_info_disclosure Information disclosure via generated output filesgitignore_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 promptsprompt_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)Generate a standalone interactive HTML threat model report with architecture diagram
cdn_supply_chain_attack Supply chain attack via CDN JavaScript dependenciessri_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 JavaScriptreplace_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 panelreplace_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 filesgitignore_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 datajs_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 parametervalidate_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)Generate a standalone interactive HTML architecture diagram with optional feature highlighting
cdn_supply_chain_attack Supply chain attack via CDN JavaScript dependenciessri_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 JavaScriptreplace_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 panelreplace_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 datajs_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)| ID | Description | Type | Technology | Trust Boundary | Source Paths |
|---|---|---|---|---|---|
cli_core | Argparse-based CLI entry point that parses user commands and dispatches to command handlers (src/cli.py, src/__main__.py) | service | Python / argparse | internal | src/cli.py src/__main__.py |
command_engine | Command handlers for init, lint, feature, and compile operations (src/commands/) | service | Python | internal | src/commands/** |
yaml_processor | YAML loading via yaml.safe_load(), threat model assembly, and cross-reference validation (src/utils.py, src/commands/lint.py) | service | Python / PyYAML (safe_load) | internal | src/utils.py |
prompt_generator | Generates AI prompt text files for threat modeling and secure coding workflows (src/generators/threat_prompt.py, agent_prompt.py) | service | Python | internal | src/generators/** |
template_store | Bundled YAML template files (minimal, web-app, api) used by init command for project scaffolding (src/templates/) | other | YAML files | internal | src/templates/** |
html_renderer | Generates interactive HTML reports and architecture diagrams with embedded Cytoscape.js (report.py, diagram.py) | service | Python / HTML / JavaScript | internal | report.py diagram.py |
filesystem_store | Local filesystem storage for .tmdd/ YAML files, generated prompts, reports, and diagrams (.tmdd/, .tmdd/out/) | other | Local filesystem | internal | — |
cdn_libraries | External CDN (unpkg.com) serving Cytoscape.js 3.30.4, dagre 0.8.5, and cytoscape-dagre 2.5.0 loaded client-side in generated HTML | external | unpkg.com CDN / JavaScript | external | — |
| ID | Path | Description | Protocol | Authentication |
|---|---|---|---|---|
df_developer_to_cli | developer → cli_core | CLI commands with arguments (path, feature name, description, template name) | stdin | none |
df_cli_to_commands | cli_core → command_engine | Parsed argparse Namespace object with user-provided values | function_call | none |
df_commands_to_yaml | command_engine → yaml_processor | File paths to load; returns parsed YAML dicts (system, actors, components, threats, mitigations) | function_call | none |
df_yaml_to_filesystem | yaml_processor → filesystem_store | Read .tmdd/ YAML files (system.yaml, actors.yaml, components.yaml, features.yaml, data_flows.yaml, threats/*.yaml) | filesystem | none |
df_init_templates | template_store → filesystem_store | Template YAML files with {{name}} and {{description}} placeholders substituted with user input, written to target directory | filesystem | none |
df_commands_to_prompts | command_engine → prompt_generator | Loaded threat model dict and feature metadata for prompt generation | function_call | none |
df_prompts_to_filesystem | prompt_generator → filesystem_store | Generated text prompt files (*.threatmodel.txt, *.prompt.txt) written to .tmdd/out/ | filesystem | none |
df_commands_to_html | command_engine → html_renderer | Loaded threat model dict passed to report/diagram generators | function_call | none |
df_html_to_filesystem | html_renderer → filesystem_store | Generated HTML files (tm.html, diagram.html) with embedded JSON data and JavaScript, written to .tmdd/out/ | filesystem | none |
df_cdn_to_browser | cdn_libraries → report_viewer | JavaScript libraries (cytoscape.min.js, dagre.min.js, cytoscape-dagre.js) loaded via script tags from unpkg.com | HTTPS | none |
df_filesystem_to_viewer | filesystem_store → report_viewer | HTML report/diagram files served to browser with embedded threat model data in JSON format | filesystem | none |
df_filesystem_to_agent | filesystem_store → ai_agent | Generated prompt text files consumed by AI agent for threat modeling or secure code generation | filesystem | none |
Faded rows indicate threats not currently mapped to any feature.
| ID | Name | Description | Severity | STRIDE | CWE | Suggested Mitigations |
|---|---|---|---|---|---|---|
yaml_template_injection | YAML template injection via init command name/description | In 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. | LOW | T | CWE-74 | yaml_escape_init_input |
cdn_supply_chain_attack | Supply chain attack via CDN JavaScript dependencies | report.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. | HIGH | T | CWE-829 | sri_hashes_cdn, bundle_libs_locally |
xss_stored_diagram | Stored XSS via innerHTML in diagram JavaScript | In 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. | MEDIUM | T | CWE-79 | replace_innerhtml_textcontent, js_html_escape_helper |
xss_stored_node_info | Stored XSS via innerHTML in node-info panel | In 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. | MEDIUM | T | CWE-79 | replace_innerhtml_textcontent, js_html_escape_helper |
yaml_dos_oversized | Denial of service via deeply nested or oversized YAML files | yaml.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. | LOW | D | CWE-400 | yaml_file_size_limit |
init_path_traversal | Arbitrary file creation via init command path argument | In 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. | LOW | T | CWE-22 | validate_init_path |
output_info_disclosure | Information disclosure via generated output files | Compiled 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. | MEDIUM | I | CWE-200 | gitignore_output_dir |
no_audit_trail | No audit trail for threat model modifications | TMDD 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. | MEDIUM | R | CWE-778 | git_change_tracking |
prompt_injection | Prompt injection via threat model content in generated AI prompts | In 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. | MEDIUM | T | CWE-77 | prompt_delimiters |
json_script_breakout | Script tag breakout in embedded JSON diagram data | In 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. | LOW | T | CWE-79 | js_html_escape_helper, enhanced_safe_json |
report_path_traversal | Report output path traversal via --name parameter | In 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. | LOW | T | CWE-22 | validate_report_filename |
Faded rows indicate mitigations not currently applied to any feature.
| ID | Description |
|---|---|
yaml_escape_init_input | Escape 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_cdn | Pin 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_locally | Bundle 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_textcontent | Replace 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_helper | Implement 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_limit | Add 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_path | Validate 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_dir | Include .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_tracking | Rely on Git version control for change tracking and attribution of .tmdd/ YAML files; document this requirement in README and generated AGENTS.md |
prompt_delimiters | Add 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_json | Enhance _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_filename | Validate 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) |
developer: Developer or security engineer who runs TMDD CLI commands (init, lint, feature, compile) and edits .tmdd/ YAML filesai_agent: AI coding agent that consumes generated prompt files (.tmdd/out/*.prompt.txt, *.threatmodel.txt) to produce threat models or secure codereport_viewer: Person viewing generated HTML reports and diagrams in a web browser, potentially including non-developers or stakeholderscdn_package_attacker: External attacker who compromises a CDN or npm package used by TMDD-generated HTML reportsmalicious_insider_fs: Malicious insider with filesystem access who tampers with .tmdd/ YAML files to inject harmful content into reports or AI promptsci_pipeline_untrusted: Automated CI/CD pipeline that invokes TMDD commands with untrusted or user-controlled input parameters