bogdanticu88/threatmap
GitHub: bogdanticu88/threatmap
一个静态 IaC 威胁建模工具,解析 Terraform、CloudFormation 和 Kubernetes 清单并生成 STRIDE 威胁报告和数据流图。
Stars: 30 | Forks: 5
# threatmap
[](https://github.com/bogdanticu88/threatmap/actions/workflows/ci.yml)
[](https://pypi.org/project/threatmap/)
[](LICENSE)
[](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/标签:AWS, Azure, CISA项目, CloudFormation, DevSecOps, DFD, DPI, ECS, GCP, IaC安全, Mermaid, Python, SARIF, STRIDE, Terraform, 上游代理, 云安全监控, 威胁建模, 子域名突变, 数据流图, 无后门, 离线安全工具, 聊天机器人, 逆向工具, 静态分析