bogdanticu88/threatmap

GitHub: bogdanticu88/threatmap

一个静态 IaC 威胁建模工具,解析 Terraform、CloudFormation 和 Kubernetes 清单并生成 STRIDE 威胁报告和数据流图。

Stars: 30 | Forks: 5

image # threatmap [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/0e26b5c2fe102321.svg)](https://github.com/bogdanticu88/threatmap/actions/workflows/ci.yml) [![Python](https://img.shields.io/badge/python-3.9%20|%203.10%20|%203.11%20|%203.12-blue)](https://pypi.org/project/threatmap/) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) [![Offline](https://img.shields.io/badge/offline-no%20network%20calls-lightgrey)](https://github.com/bogdanticu88/threatmap) 静态 IaC 威胁建模工具,能够解析 Terraform、CloudFormation 和 Kubernetes 清单文件,并生成包含数据流图的结构化 STRIDE 威胁模型报告。无需网络调用,无需云凭证,完全离线运行。 ## 快速开始 ``` pip install threatmap # 作为命令运行 threatmap scan ./examples --output report.md --fail-on HIGH # 或作为模块 python -m threatmap scan ./examples --ascii ``` ## 支持的格式与提供商 | 格式 | 提供商 | 扩展名 | |--------|----------|-----------| | Terraform HCL | AWS, Azure, GCP | `.tf` | | CloudFormation | AWS | `.yaml`, `.yml`, `.json` | | Kubernetes 清单 | Kubernetes | `.yaml`, `.yml` | ## 安装 从 PyPI 安装: ``` pip install threatmap ``` 或者用于本地开发: ``` git clone https://github.com/bogdanticu88/threatmap.git cd threatmap pip install -e . ``` ## 使用方法 扫描目录并将 Markdown 报告打印到 stdout: ``` threatmap scan ./terraform/ ``` 扫描多个路径并将 JSON 报告写入文件: ``` threatmap scan ./terraform/ ./k8s/ ./cloudformation/ --format json --output report.json ``` 生成交互式 HTML 报告或用于 GitHub Security 的 SARIF 报告: ``` threatmap scan ./infra/ --format html --output report.html threatmap scan ./infra/ --format sarif --output report.sarif ``` CI 门禁 —— 如果发现任何 CRITICAL 或 HIGH 威胁则以退出代码 1 退出: ``` threatmap scan ./infra/ --fail-on HIGH --output threat-report.md ``` 仅打印终端摘要表,不写入完整报告: ``` threatmap scan ./infra/ --summary ``` 在不支持 Unicode 的环境中使用仅包含 ASCII 的严重性指示符(无表情符号): ``` threatmap scan ./infra/ --ascii --output report.md ``` ## 示例报告输出 针对捆绑的示例运行 `threatmap scan ./examples --output report.md` 会生成完整的 Markdown 报告。以下是一个具有代表性的摘录。 ### STRIDE 威胁表 | ID | 严重性 | STRIDE 类别 | 资源 | 描述 | |----|----------|----------------|----------|-------------| | T-001 | 🔴 CRITICAL | 信息泄露 | `AuditBucket` | S3 存储桶 'AuditBucket' 未配置公共访问阻止 —— 存储桶可能可被公开访问。 | | T-002 | 🔴 CRITICAL | 欺骗 | `WebSecurityGroup` | 安全组 'WebSecurityGroup' 将 SSH/RDP (端口 22/3389) 暴露给 0.0.0.0/0。 | | T-003 | 🔴 CRITICAL | 权限提升 | `app_contributor` | 角色分配 'app_contributor' 授予了特权角色 'Contributor'。 | | T-006 | 🟠 HIGH | 信息泄露 | `AuditBucket` | S3 存储桶 'AuditBucket` 未配置服务器端加密。 | | T-008 | 🟠 HIGH | 权限提升 | `api` | Deployment 'api' 中的容器 'api' 可能以 root 身份运行(无 runAsNonRoot=true 或 runAsUser=0)。 | | T-011 | 🟠 HIGH | 权限提升 | `web` | EC2 实例 'web' 允许 IMDSv1 —— 元数据服务无需会话令牌即可访问,可能导致基于 SSRF 的凭证窃取。 | ### 缓解措施详情(摘录) ``` ### T-002 — Spoofing (CRITICAL) Resource: AWS::EC2::SecurityGroup.WebSecurityGroup Property: ingress.ssh_rdp_open Finding: Security group 'WebSecurityGroup' exposes SSH/RDP (port 22/3389) to 0.0.0.0/0. Mitigation: Remove public SSH/RDP access. Use AWS Systems Manager Session Manager or a bastion host with IP restrictions. ``` ### 数据流图 (Mermaid) 报告会附加一个 Mermaid `flowchart LR` 图表。节点根据最坏情况的严重性进行着色(🔴 红色 = CRITICAL,🟠 橙色 = HIGH)。将代码块粘贴到任何 Mermaid 渲染器中或直接在 GitHub 上查看。 ``` flowchart LR Internet((Internet)) subgraph Networking aws_security_group_web_sg{web_sg} NetworkPolicy_default_deny{default-deny} azurerm_network_security_group_app_nsg{app_nsg} end subgraph Compute aws_instance_web[web] end subgraph Kubernetes Namespace_myapp[myapp] Deployment_api[api] Service_api_svc[api-svc] Ingress_api_ingress[api-ingress] end subgraph Data aws_s3_bucket_app_data[(app_data)] aws_db_instance_app_db[(app_db)] azurerm_storage_account_app_storage[(app_storage)] end subgraph Security azurerm_key_vault_app_kv[app_kv] end subgraph Identity azurerm_role_assignment_app_contributor[/app_contributor/] end AWS__S3__Bucket_AppBucket -->|ref| AWS__S3__Bucket_AuditBucket AWS__CloudTrail__Trail_AppTrail -->|ref| AWS__S3__Bucket_AuditBucket Internet -->|HTTPS| Ingress_api_ingress style aws_security_group_web_sg fill:#ff4444,color:#fff style aws_s3_bucket_app_data fill:#ff4444,color:#fff style aws_instance_web fill:#ff8800,color:#fff style Deployment_api fill:#ff8800,color:#fff style azurerm_key_vault_app_kv fill:#ffcc00,color:#000 style azurerm_network_security_group_app_nsg fill:#ff8800,color:#fff style azurerm_role_assignment_app_contributor fill:#ff4444,color:#fff ``` ## 高级功能 (v1.1.0+) ### 基于图的攻击路径分析 `threatmap` 现在包含**图智能**功能,可追踪资源之间的关系。它会自动识别“链式”威胁,即对一个资源的入侵(例如,暴露在互联网上的 EC2)直接导致对另一个资源的入侵(例如,私有 S3 存储桶),并将这些标记为**权限提升**攻击路径。 ### 自定义 YAML 规则 您可以通过在项目根目录中创建 `threatmap_rules.yaml` 来定义内部安全要求。 ``` rules: - resource_type: "aws_s3_bucket" property: "force_destroy" expected: false stride: "Tampering" severity: "MEDIUM" description: "Production buckets should not have force_destroy enabled." mitigation: "Set force_destroy = false." ``` ### 修复提示 大多数发现现在都包含一个 **remediation** 字段(在 JSON、HTML 和 SARIF 报告中可见),其中提供了修复安全问题所需的确切代码片段。 ### 规则存放位置 每个云提供商都有自己的分析器模块: ``` threatmap/analyzers/ ├── aws.py # 22 rules — S3, IAM, EC2, RDS, EKS, CloudTrail, KMS, Lambda ├── azure.py # 19 rules — Storage, Key Vault, NSG, RBAC, AKS, ACR, SQL ├── gcp.py # 15 rules — GCS, Firewall, Compute, Cloud SQL, GKE, IAM, KMS └── kubernetes.py # 17 rules — workloads, RBAC, network, secrets ``` 每条规则都是一个函数,它接收一个 `Resource` 对象(根据解析的源格式进行标准化),如果满足条件则返回一个 `Threat`。规则是普通的 Python 条件语句 —— 没有 DSL,没有正则表达式引擎,没有外部规则集文件。 ### 严重性判定标准 严重性反映了**可利用性**和**影响范围**: | 严重性 | 含义 | |----------|---------| | CRITICAL | 无需额外前提条件即可直接利用(例如 SSH 对 0.0.0.0/0 开放,通配符 IAM 策略,cluster-admin 绑定到匿名用户) | | HIGH | 需要一个额外步骤的重大风险(例如具有公共访问权限的未加密 RDS,EC2 实例上的 IMDSv1) | | MEDIUM | 缺失深度防御控制 —— 近期风险较低但违反安全基线(例如无版本控制,无日志记录,无资源限制) | | LOW | 具有有限独立可利用性的最佳实践差距(例如 Lambda 不在 VPC 中) | ### 如何避免误报 - **无启发式或机器学习 (ML)** —— 每条规则都基于具体、明确的属性值触发(例如 `publicly_accessible = true`,`Principal: "*"`)。 - **保守的默认值** —— 如果属性缺失,规则会假定不安全的默认值(例如 EC2 实例上没有 `metadata_options` 块意味着 IMDSv1 处于活动状态,因为这是 AWS 的默认设置)。 - **无跨账户或运行时状态** —— 该工具仅查看模板中声明的内容。它不会尝试推断 SCP、权限边界或运行时配置可能会如何缓解发现。 - **引擎中的去重** —— 发现结果以 `(stride_category, resource_name, trigger_property)` 为键,因此即使同一逻辑问题出现在多种文件格式中,也不会被报告两次。 ## CI 集成 ``` # .github/workflows/threat-model.yml name: Threat Model on: [pull_request] jobs: threatmap: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install threatmap run: pip install threatmap - name: Run threat model scan run: | threatmap scan ./infra/ \ --format markdown \ --output threat-report.md \ --fail-on HIGH - name: Upload threat report if: always() uses: actions/upload-artifact@v4 with: name: threat-report path: threat-report.md ``` `--fail-on HIGH` 标志使得如果发现任何 HIGH 或 CRITICAL 威胁,作业将以代码 1 退出,从而阻止 PR 合并。上传的构件让审查者无需离开 Pull Request 即可查看完整报告。 ## STRIDE 规则覆盖范围 | 提供商 | 规则数 | |----------|-------| | AWS (Terraform + CloudFormation) | 22 | | Azure (Terraform) | 19 | | GCP (Terraform) | 15 | | Kubernetes | 17 | | **总计** | **73** | 每个提供商涵盖的类别: | 提供商 | S | T | R | I | D | E | |----------|---|---|---|---|---|---| | AWS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Azure | ✓ | ✓ | ✓ | ✓ | — | ✓ | | GCP | ✓ | ✓ | ✓ | ✓ | — | ✓ | | Kubernetes | ✓ | ✓ | — | ✓ | ✓ | ✓ | *(S=欺骗, T=篡改, R=否认, I=信息泄露, D=拒绝服务, E=权限提升)* ## 开发 运行测试: ``` pytest tests/ -v ``` 运行覆盖率测试: ``` pytest tests/ --cov=threatmap --cov-report=term-missing ``` ## 贡献 1. Fork 本仓库 2. 遵循现有模式在 `threatmap/analyzers/.py` 中添加规则 3. 在 `tests/fixtures/` 中添加触发新规则的 fixture 4. 在 `tests/test_analyzers.py` 中添加断言 5. 打开一个 Pull Request
标签:AWS, Azure, CISA项目, CloudFormation, DevSecOps, DFD, DPI, ECS, GCP, IaC安全, Mermaid, Python, SARIF, STRIDE, Terraform, 上游代理, 云安全监控, 威胁建模, 子域名突变, 数据流图, 无后门, 离线安全工具, 聊天机器人, 逆向工具, 静态分析