
Моделировщик угроз IaC с использованием фреймворков STRIDE, MITRE ATT&CK и PASTA. Поддержка REST API, GraphQL и Docker для Terraform, CloudFormation и Kubernetes.
Статический моделировщик угроз 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 Server:
threatmap serve --host 0.0.0.0 --port 8000
# Or via Docker:
docker run -p 8000:8000 bogdynn/threatmap:2.1.0
# API endpoints: /health, /version, /rules, /analyze
GraphQL API:
docker run -p 8000:8000 bogdynn/threatmap:2.1.0
# GraphQL endpoint: http://localhost:8000/graphql
# Queries: health, version, rules
# Mutations: analyze(content, filename, framework)
| Формат | Провайдер | Расширение |
|---|---|---|
| Terraform HCL | AWS, Azure, GCP | .tf |
| CloudFormation | AWS | .yaml, .yml, .json |
| Kubernetes manifests | 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-отчёт или SARIF-отчёт для GitHub Security:
threatmap scan ./infra/ --format html --output report.html
threatmap scan ./infra/ --format sarif --output report.sarif
CI-шлюз — код возврата 1, если найдена угроза CRITICAL или HIGH:
threatmap scan ./infra/ --fail-on HIGH --output threat-report.md
Вывести только сводную таблицу в терминал, без записи полного отчёта:
threatmap scan ./infra/ --summary
Использовать только ASCII-индикаторы серьёзности (без эмодзи) для сред, не поддерживающих Unicode:
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. Ниже приведён репрезентативный фрагмент.
| ID | Серьёзность | Категория STRIDE | Ресурс | Описание |
|---|---|---|---|---|
| T-001 | 🔴 CRITICAL | Information Disclosure | AuditBucket | S3 bucket 'AuditBucket' не имеет настроенного блока публичного доступа — bucket может быть общедоступен. |
| T-002 | 🔴 CRITICAL | Spoofing | WebSecurityGroup | Группа безопасности 'WebSecurityGroup' открывает SSH/RDP (порт 22/3389) для 0.0.0.0/0. |
| T-003 | 🔴 CRITICAL | Elevation of Privilege | app_contributor | Назначение роли 'app_contributor' предоставляет привилегированную роль 'Contributor'. |
| T-006 | 🟠 HIGH | Information Disclosure | AuditBucket | S3 bucket 'AuditBucket' не использует шифрование на стороне сервера. |
| T-008 | 🟠 HIGH | Elevation of Privilege | api | Контейнер 'api' в Deployment 'api' может работать от root (нет runAsNonRoot=true или runAsUser=0). |
| T-011 | 🟠 HIGH | Elevation of Privilege | web | EC2 instance '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 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:#fffthreatmap теперь включает графовую интеллектуальность, которая отслеживает связи между ресурсами. Он автоматически выявляет "цепочки" угроз, когда компрометация одного ресурса (например, доступного из интернета EC2) напрямую ведёт к другому (например, приватному S3 bucket), помечая их как пути атак Elevation of Privilege.
Вы можете определить внутренние требования безопасности, создав файл 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 отчётах), которое содержит точный фрагмент кода, необходимый для устранения проблемы безопасности.
STRIDE Analyzer — правила угроз, специфичные для провайдеров:
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 Analyzer — 11 правил, сопоставленных с тактиками MITRE:
PASTA Analyzer — 12 правил с ориентацией на активы:
APIs:
/health, /version, /rules, /analyze, /analyze/file/graphql с Query (health, version, rules) и Mutation (analyze)Каждое правило — это функция, получающая объект Resource (нормализованный из любого исходного формата) и возвращающая Threat при выполнении условия. Правила — это простые условные конструкции Python: без DSL, без движка регулярных выражений, без внешних файлов с правилами.
Серьёзность отражает как эксплуатируемость, так и радиус поражения:
| Серьёзность | Значение |
|---|---|
| CRITICAL | Напрямую эксплуатируемо без дополнительных условий (например, SSH открыт для 0.0.0.0/0, политика IAM с wildcard, привязка cluster-admin к anonymous) |
| HIGH | Значительный риск, требующий одного дополнительного шага (например, незашифрованная RDS с публичным доступом, IMDSv1 на EC2) |
| MEDIUM | Отсутствие элементов защиты в глубину — более низкий непосредственный риск, но нарушение базовых стандартов безопасности (например, отсутствие версионирования, логирования, ограничений ресурсов) |
| LOW | Пробелы в лучших практиках с ограниченной самостоятельной эксплуатируемостью (например, Lambda не в VPC) |
publicly_accessible = true, Principal: "*").metadata_options на EC2 означает, что IMDSv1 активен, так как это значение по умолчанию AWS).(stride_category, resource_name, trigger_property), поэтому одна и та же логическая проблема никогда не сообщается дважды, даже если появляется в нескольких форматах файлов.# .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 заставляет задачу завершиться с кодом 1, если обнаружена угроза HIGH или CRITICAL, блокируя слияние PR. Загруженный артефакт предоставляет рецензентам полный отчёт без выхода из pull request.
| Провайдер | Правила |
|---|---|
| AWS (Terraform + CloudFormation) | 22 |
| Azure (Terraform) | 19 |
| GCP (Terraform) | 15 |
| Kubernetes | 17 |
| Итого | 73 |
Категории, охваченные для каждого провайдера:
| Provider | S | T | R | I | D | E |
|---|---|---|---|---|---|---|
| AWS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Azure | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| GCP | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| Kubernetes | ✓ | ✓ | — | ✓ | ✓ | ✓ |
(S=Spoofing, T=Tampering, R=Repudiation, I=Information Disclosure, D=Denial of Service, E=Elevation of Privilege)
Запустить тесты:
pytest tests/ -v
Запустить с покрытием:
pytest tests/ --cov=threatmap --cov-report=term-missing
threatmap/analyzers/<provider>.py по существующему шаблонуtests/fixtures/, которая активирует новое правилоtests/test_analyzers.py