
Modellatore di minacce IaC con framework STRIDE, MITRE ATT&CK e PASTA. Supporto per REST API, GraphQL e Docker per Terraform, CloudFormation e Kubernetes.
Modellatore statico di minacce per IaC che analizza manifest Terraform, CloudFormation e Kubernetes e produce report strutturati di modelli di minaccia utilizzando i framework STRIDE, MITRE ATT&CK o PASTA. Nessuna chiamata di rete, nessuna credenziale cloud, completamente offline. Funziona come CLI, API REST o servizio containerizzato.
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
Server API REST:
threatmap serve --host 0.0.0.0 --port 8000
# Oppure tramite Docker:
docker run -p 8000:8000 bogdynn/threatmap:2.1.0
# Endpoint API: /health, /version, /rules, /analyze
API GraphQL:
docker run -p 8000:8000 bogdynn/threatmap:2.1.0
# Endpoint GraphQL: http://localhost:8000/graphql
# Query: health, version, rules
# Mutation: analyze(content, filename, framework)
Installa da PyPI:
pip install threatmap
Oppure per sviluppo locale:
git clone https://github.com/bogdanticu88/threatmap.git
cd threatmap
pip install -e .
Esegui la scansione di una directory e stampa un report Markdown su stdout:
threatmap scan ./terraform/
Esegui la scansione di più percorsi e scrivi un report JSON in un file:
threatmap scan ./terraform/ ./k8s/ ./cloudformation/ --format json --output report.json
Genera un report HTML interattivo o un report SARIF per GitHub Security:
threatmap scan ./infra/ --format html --output report.html
threatmap scan ./infra/ --format sarif --output report.sarif
Gate CI — codice di uscita 1 se viene trovata una minaccia CRITICAL o HIGH:
threatmap scan ./infra/ --fail-on HIGH --output threat-report.md
Stampa solo una tabella riepilogativa nel terminale, senza scrivere un report completo:
threatmap scan ./infra/ --summary
Usa indicatori di gravità solo ASCII (senza emoji) per ambienti che non supportano Unicode:
threatmap scan ./infra/ --ascii --output report.md
Analizza utilizzando diversi framework di modelli di minaccia:
# STRIDE (predefinito)
threatmap scan ./infra/ --framework stride
# MITRE ATT&CK (mappa a tattiche e tecniche)
threatmap scan ./infra/ --framework mitre --format json
# PASTA (modellazione di minacce incentrata sugli asset)
threatmap scan ./infra/ --framework pasta --format json
STRIDE (73 regole)
MITRE ATT&CK (11 regole, 14 tattiche)
PASTA (12 regole, incentrato sugli asset)
Eseguendo threatmap scan ./examples --output report.md sugli esempi inclusi si ottiene un report Markdown completo. Di seguito viene mostrato un estratto rappresentativo.
### T-002 — Spoofing (CRITICAL)
Resource: AWS::EC2::SecurityGroup.WebSecurityGroup
Property: ingress.ssh_rdp_open
Finding: Il gruppo di sicurezza 'WebSecurityGroup' espone SSH/RDP (porta 22/3389) a 0.0.0.0/0.
Mitigation: Rimuovere l'accesso SSH/RDP pubblico. Utilizzare AWS Systems Manager Session Manager
o un bastion host con restrizioni IP.
Il report aggiunge un diagramma Mermaid flowchart LR. I nodi sono colorati in base alla gravità peggiore (🔴 rosso = CRITICAL, 🟠 arancione = HIGH). Incolla il blocco in qualsiasi renderer Mermaid o visualizzalo direttamente su 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
threatmap ora include Graph Intelligence che traccia le relazioni tra le risorse. Identifica automaticamente minacce "a catena" in cui la compromissione di una risorsa (ad esempio, un EC2 esposto a Internet) porta direttamente a un'altra (ad esempio, un bucket S3 privato), segnalandole come percorsi di attacco Elevation of Privilege.
Puoi definire requisiti di sicurezza interni creando un file threatmap_rules.yaml nella radice del progetto.
rules:
- resource_type: "aws_s3_bucket"
property: "force_destroy"
expected: false
stride: "Tampering"
severity: "MEDIUM"
description: "I bucket di produzione non dovrebbero avere force_destroy abilitato."
mitigation: "Imposta force_destroy = false."
La maggior parte dei risultati ora include un campo remediation (visibile nei report JSON, HTML e SARIF) che fornisce lo snippet di codice esatto necessario per risolvere il problema di sicurezza.
Analizzatore STRIDE — Regole di minaccia specifiche per provider:
threatmap/analyzers/
├── aws.py # 22 regole — S3, IAM, EC2, RDS, EKS, CloudTrail, KMS, Lambda
├── azure.py # 19 regole — Storage, Key Vault, NSG, RBAC, AKS, ACR, SQL
├── gcp.py # 15 regole — GCS, Firewall, Compute, Cloud SQL, GKE, IAM, KMS
└── kubernetes.py # 17 regole — carichi di lavoro, RBAC, rete, segreti
Analizzatore MITRE ATT&CK — 11 regole mappate alle tattiche MITRE:
Analizzatore PASTA — 12 regole con focus incentrato sugli asset:
API:
/health, /version, /rules, /analyze, /analyze/file/graphql con Query (health, version, rules) e Mutation (analyze)Ogni regola è una funzione che riceve un oggetto Resource (normalizzato indipendentemente dal formato sorgente analizzato) e restituisce un Threat se la condizione è soddisfatta. Le regole sono semplici condizionali Python — nessun DSL, nessun motore regex, nessun file di regole esterno.
La severità riflette sia l'exploitability che il blast radius:
| Severità | Significato |
|---|---|
| CRITICAL | Sfruttabile direttamente senza precondizioni aggiuntive (ad es. SSH aperto a 0.0.0.0/0, policy IAM wildcard, binding cluster-admin ad anonimo) |
publicly_accessible = true, Principal: "*").metadata_options su un'istanza EC2 significa che IMDSv1 è attivo, perché questo è il default di AWS).(stride_category, resource_name, trigger_property) in modo che lo stesso problema logico non venga mai segnalato due volte, anche se appare in più formati di file.# .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
Il flag --fail-on HIGH fa sì che il job esca con codice 1 se viene trovata una minaccia HIGH o CRITICAL, bloccando il merge della PR. L'artefatto caricato fornisce ai revisori il report completo senza uscire dalla pull request.
| Provider | Regole |
|---|---|
| AWS (Terraform + CloudFormation) | 22 |
| Azure (Terraform) |
Categorie coperte per provider:
(S=Spoofing, T=Tampering, R=Repudiation, I=Information Disclosure, D=Denial of Service, E=Elevation of Privilege)
Esegui i test:
pytest tests/ -v
Esegui con copertura:
pytest tests/ --cov=threatmap --cov-report=term-missing
threatmap/analyzers/<provider>.py seguendo il pattern esistentetests/fixtures/ che attivi la nuova regolatests/test_analyzers.py| Formato | Provider | Estensione |
|---|
| Terraform HCL | AWS, Azure, GCP | .tf |
| CloudFormation | AWS | .yaml, .yml, .json |
| Kubernetes manifests | Kubernetes | .yaml, .yml |
| ID | Gravità | Categoria STRIDE | Risorsa | Descrizione |
|---|
| T-001 | 🔴 CRITICAL | Information Disclosure | AuditBucket | Il bucket S3 'AuditBucket' non ha un blocco di accesso pubblico configurato — il bucket potrebbe essere accessibile pubblicamente. |
| T-002 | 🔴 CRITICAL | Spoofing | WebSecurityGroup | Il gruppo di sicurezza 'WebSecurityGroup' espone SSH/RDP (porta 22/3389) a 0.0.0.0/0. |
| T-003 | 🔴 CRITICAL | Elevation of Privilege | app_contributor | L'assegnazione di ruolo 'app_contributor' concede il ruolo privilegiato 'Contributor'. |
| T-006 | 🟠 HIGH | Information Disclosure | AuditBucket | Il bucket S3 'AuditBucket' non ha la crittografia lato server configurata. |
| T-008 | 🟠 HIGH | Elevation of Privilege | api | Il contenitore 'api' nel Deployment 'api' potrebbe essere eseguito come root (nessun runAsNonRoot=true o runAsUser=0). |
| T-011 | 🟠 HIGH | Elevation of Privilege | web | L'istanza EC2 'web' consente IMDSv1 — il servizio di metadati è accessibile senza token di sessione, consentendo il furto di credenziali basato su SSRF. |
| HIGH |
| Rischio significativo che richiede un passaggio aggiuntivo (ad es. RDS non crittografato con accesso pubblico, IMDSv1 su un'istanza EC2) |
| MEDIUM | Mancano controlli di difesa in profondità — rischio immediato inferiore ma viola le baseline di sicurezza (ad es. nessun versioning, nessun logging, nessun limite di risorse) |
| LOW | Lacune nelle best practice con sfruttabilità autonoma limitata (ad es. Lambda non in VPC) |
| 19 |
| GCP (Terraform) | 15 |
| Kubernetes | 17 |
| Totale | 73 |
| Provider | S | T | R | I | D | E |
|---|
| AWS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Azure | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| GCP | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| Kubernetes | ✓ | ✓ | — | ✓ | ✓ | ✓ |