静态 IaC 威胁建模器,可解析 Terraform、CloudFormation 和 Kubernetes 清单,并使用 STRIDE、MITRE ATT&CK 或 PASTA 框架生成结构化威胁模型报告。无需网络调用,无需云凭据,完全离线运行。可作为 CLI、REST API 或容器化服务使用。
CLI:
pip install threatmap
threatmap scan ./examples --output report.md --fail-on HIGH
Docker:
docker run -v $(pwd):/workspace bogdynn/threatmap:2.1.0 threatmap scan /workspace --output /workspace/report.md
REST API 服务器:
threatmap serve --host 0.0.0.0 --port 8000
# 或通过 Docker:
docker run -p 8000:8000 bogdynn/threatmap:2.1.0
# API 端点: /health, /version, /rules, /analyze
GraphQL API:
docker run -p 8000:8000 bogdynn/threatmap:2.1.0
# GraphQL 端点: http://localhost:8000/graphql
# 查询: health, version, rules
# 变更: analyze(content, filename, framework)
从 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
使用不同的威胁建模框架进行分析:
# STRIDE(默认)
threatmap scan ./infra/ --framework stride
# MITRE ATT&CK(映射到战术和技术)
threatmap scan ./infra/ --framework mitre --format json
# PASTA(以资产为中心的威胁建模)
threatmap scan ./infra/ --framework pasta --format json
STRIDE(73 条规则)
MITRE ATT&CK(11 条规则,14 个战术)
PASTA(12 条规则,以资产为中心)
运行 threatmap scan ./examples --output report.md 针对附带的示例会生成完整的 Markdown 报告。以下是代表性摘录。
### T-002 — 欺骗(严重)
资源: AWS::EC2::SecurityGroup.WebSecurityGroup
属性: ingress.ssh_rdp_open
发现: 安全组 'WebSecurityGroup' 将 SSH/RDP(端口 22/3389)暴露给 0.0.0.0/0。
缓解措施: 移除公开的 SSH/RDP 访问。使用 AWS Systems Manager Session Manager
或带有 IP 限制的堡垒机。
报告会附加一个 Mermaid flowchart LR 图。节点按最坏情况严重等级着色(🔴 红色 = 严重,🟠 橙色 = 高)。将代码块粘贴到任何 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:#fffthreatmap 现在包含 图智能,可追踪资源之间的关系。它会自动识别“链式”威胁,即一个资源(例如,暴露于互联网的 EC2)的沦陷直接导致另一个资源(例如,私有 S3 存储桶)的沦陷,并将这些情况标记为权限提升攻击路径。
您可以通过在项目根目录创建 threatmap_rules.yaml 来定义内部安全需求。
rules:
- resource_type: "aws_s3_bucket"
property: "force_destroy"
expected: false
stride: "Tampering"
severity: "MEDIUM"
description: "生产环境的存储桶不应启用 force_destroy。"
mitigation: "设置 force_destroy = false。"
大多数发现现在包含一个 remediation 字段(在 JSON、HTML 和 SARIF 报告中可见),提供修复该安全问题所需的确切代码片段。
STRIDE 分析器 — 提供商特定的威胁规则:
threatmap/analyzers/
├── aws.py # 22 条规则 — S3, IAM, EC2, RDS, EKS, CloudTrail, KMS, Lambda
├── azure.py # 19 条规则 — Storage, Key Vault, NSG, RBAC, AKS, ACR, SQL
├── gcp.py # 15 条规则 — GCS, Firewall, Compute, Cloud SQL, GKE, IAM, KMS
└── kubernetes.py # 17 条规则 — workloads, RBAC, network, secrets
MITRE ATT&CK 分析器 — 11 条规则映射到 MITRE 战术:
PASTA 分析器 — 12 条规则,以资产为中心:
API:
/health, /version, /rules, /analyze, /analyze/file/graphql 包含 Query(health, version, rules)和 Mutation(analyze)每条规则都是一个函数,接收一个 Resource 对象(从任何源格式解析后标准化得到),如果条件满足则返回一个 Threat。规则是纯 Python 条件语句——无需 DSL、无需正则引擎、无需外部规则集文件。
严重等级同时反映可利用性和爆炸半径:
| 严重程度 | 含义 |
|---|---|
| 严重 | 无需额外前提条件即可直接利用(例如 SSH 暴露给 0.0.0.0/0、通配符 IAM 策略、集群管理员绑定给匿名用户) |
| 高 | 需要额外一步的重大风险(例如未加密的 RDS 具有公共访问权限、EC2 实例上的 IMDSv1) |
| 中 | 缺少纵深防御控制——直接风险较低但违反安全基线(例如无版本控制、无日志记录、无资源限制) |
| 低 | 最佳实践差距,独立可利用性有限(例如 Lambda 未在 VPC 内) |
publicly_accessible = true、Principal: "*")。metadata_options 块意味着 IMDSv1 处于活动状态,因为这是 AWS 的默认设置)。(stride_category, resource_name, trigger_property) 为键,因此即使同一个逻辑问题出现在多个文件格式中,也绝不会被报告两次。# .github/workflows/threat-model.yml
name: 威胁模型
on: [pull_request]
jobs:
threatmap:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 设置 Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: 安装 threatmap
run: pip install threatmap
- name: 运行威胁模型扫描
run: |
threatmap scan ./infra/ \
--format markdown \
--output threat-report.md \
--fail-on HIGH
- name: 上传威胁报告
if: always()
uses: actions/upload-artifact@v4
with:
name: threat-report
path: threat-report.md
--fail-on HIGH 标志使得如果发现任何 HIGH 或 CRITICAL 威胁,任务将以退出码 1 退出,从而阻止 PR 合并。上传的产物让审查者无需离开拉取请求即可查看完整报告。
| 提供商 | 规则数 |
|---|---|
| AWS(Terraform + CloudFormation) | 22 |
| Azure(Terraform) | 19 |
每个提供商覆盖的类别:
(S=欺骗, T=篡改, R=抵赖, I=信息泄露, D=拒绝服务, E=权限提升)
运行测试:
pytest tests/ -v
带覆盖率运行:
pytest tests/ --cov=threatmap --cov-report=term-missing
threatmap/analyzers/<provider>.py 中添加规则tests/fixtures/ 中添加触发新规则的 fixturetests/test_analyzers.py 中添加断言| 格式 | 提供商 | 扩展名 |
|---|
| Terraform HCL | AWS, Azure, GCP | .tf |
| CloudFormation | AWS | .yaml, .yml, .json |
| Kubernetes 清单 | Kubernetes | .yaml, .yml |
| ID | 严重程度 | STRIDE 类别 | 资源 | 描述 |
|---|
| T-001 | 🔴 严重 | 信息泄露 | AuditBucket | S3 存储桶 'AuditBucket' 未配置公共访问阻止——存储桶可能可公开访问。 |
| T-002 | 🔴 严重 | 欺骗 | WebSecurityGroup | 安全组 'WebSecurityGroup' 将 SSH/RDP(端口 22/3389)暴露给 0.0.0.0/0。 |
| T-003 | 🔴 严重 | 权限提升 | app_contributor | 角色分配 'app_contributor' 授予了特权角色 'Contributor'。 |
| T-006 | 🟠 高 | 信息泄露 | AuditBucket | S3 存储桶 'AuditBucket' 未配置服务器端加密。 |
| T-008 | 🟠 高 | 权限提升 | api | Deployment 'api' 中的容器 'api' 可能以 root 身份运行(未设置 runAsNonRoot=true 或 runAsUser=0)。 |
| T-011 | 🟠 高 | 权限提升 | web | EC2 实例 'web' 允许 IMDSv1——元数据服务无需会话令牌即可访问,导致基于 SSRF 的凭据窃取。 |
| GCP(Terraform) | 15 |
| Kubernetes | 17 |
| 总计 | 73 |
| 提供商 | S | T | R | I | D | E |
|---|
| AWS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Azure | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| GCP | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| Kubernetes | ✓ | ✓ | — | ✓ | ✓ | ✓ |