Threat Model — superfícies comerciais SaaS (STRIDE)¶
Read in your language: English · Português · Español
audit-v6 DOCS-ARCH:
SECURITY_ZTP_PREM.mdcobre o modelo de ameaça insider on-prem; este documento cobre as superfícies comerciais voltadas à Internet. É um artefato vivo — atualize-o quando uma superfície, fluxo de dados ou trust boundary mudar.
1. Escopo & trust boundaries¶
No escopo: app.tlsstress.art (customer-app), admin.tlsstress.art
(admin-console), o edge worker da Cloudflare e a ingestão de usage-report
on-prem → SaaS. Fora do escopo: o data plane isolado do test-bed NGFW
(lab operado pelo operador; threat model on-prem separado em
security/THREAT_MODEL.md).
flowchart LR
U[Customer browser] -->|TLS| E[Cloudflare edge worker]
E -->|auth gate, rate limit, WAF| CA[customer-app]
A[Admin] -->|TLS + MFA| AC[admin-console]
OP[On-prem reporter] -->|signed usage report| CA
CA --> DB[(Postgres — RLS)]
AC --> DB
CA --> ST[Stripe]
ST -->|webhook| CA
CA --> KMS[AWS KMS]
Trust boundaries: browser↔edge, edge↔customer-app, customer-app↔DB (RLS), customer-app↔Stripe, on-prem↔SaaS (reports assinados), operador↔admin-console (MFA).
2. Análise STRIDE¶
| # | Ameaça (STRIDE) | Superfície | Mitigação (em vigor) | Residual / follow-up |
|---|---|---|---|---|
| S1 | Spoofing de sessão de cliente | customer-app | JWT HS256, algoritmo fixado server-side (sem alg-confusion), timingSafeEqual, checks de exp/iat/iss/aud, denylist por request + staleness de credential-epoch (middleware + por rota) |
— |
| S2 | Spoofing do reporter on-prem | usage ingest | Usage report assinado + usage_report_nonces (anti-replay) |
Rotacionar signing keys num cronograma |
| S3 | Spoofing de webhooks Stripe | customer-app | Verificação de assinatura HMAC, fail-closed 503 quando o secret não está setado (payment e KYC pós audit-v6) | — |
| T1 | Tampering da trilha de auditoria | admin-console/DB | WORM: trigger no DB bloqueia UPDATE + DELETE precoce; hash chain SHA-256; export RFC-5424 assinado | Registrar um IANA PEN (atualmente placeholder) |
| T2 | Tampering das imagens de release | supply chain | Build multi-arch + assinatura cosign keyless + SBOM; release agora em runners GitHub-hosted; todas as actions com SHA-pin (audit-v6) | — |
| R1 | Repudiation de ações de admin | admin-console | Hash chain de admin_audit_events com actor + IP de origem + before/after |
SSO + SoD (depende do épico RBAC E1) |
| I1 | Information disclosure cross-tenant | customer-app/DB | WHERE account_id por query; RLS tenant_isolation; withTenant() nas rotas de tenant + guard test no CI (audit-v6) |
Cutover completo para default-deny (dual DB roles) |
| I2 | Information disclosure via headers | edge/customer-app | Middleware remove x-admin-*/x-customer-* de entrada antes de setar a identidade verificada; CSP com nonce por request e strict-dynamic |
— |
| I3 | Information disclosure de secrets | todas | Pepper/KMS fail-closed; sem secrets hardcoded (gate gitleaks); guard de placeholder-secret rejeita REPLACE_ME (audit-v6) |
— |
| I4 | Information disclosure — KYC/PII | customer-app | Stripe Identity (dados de KYC ficam na Stripe); redação de PII no audit log | Mapa de fluxo de dados GDPR + DPA (trilha de privacidade) |
| D1 | Denial of service — brute force de auth | customer-app | Rate limiter LRU + Postgres-backed, fail-closed | — |
| D2 | Denial of service — edge | edge worker | Rate limit + regras de WAF; rate cap do SLO | Rate-limit do edge falha aberto em erro de DO (rastreado) |
| D3 | Denial of service — body sobredimensionado | customer-app/dashboard | readJson() faz stream com cap de bytes (audit-v6 — bypass de chunked-encoding corrigido) |
— |
| E1 | Elevation of privilege — refund IDOR | customer-app | Rota de refund verifica charge.customer == conta da sessão antes do refund; gated por MFA |
— |
| E2 | Elevation of privilege — auto-verificação de KYC | customer-app | Webhook de KYC fail-closed com secret não setado (audit-v6) — um evento forjado não consegue mais se auto-verificar | — |
| E3 | Elevation of privilege — K8s | on-prem control plane | pods/exec do pie-pa-executor namespaced; DaemonSets de host privilegiados isolados em dut-system; hostPath do dashboard removido (audit-v6) |
web-agents permanece PSA privileged — os init containers de DSCP/policy-routing dos agentes precisam de NET_ADMIN/NET_RAW, que baseline rejeita na admission (revert do audit-v7) |
3. Premissas¶
- O edge da Cloudflare termina TLS e é a primeira camada de WAF/rate-limit.
- AWS KMS e Stripe são terceiros confiáveis; comprometê-los está fora do escopo.
- O Postgres é alcançável apenas pelo tier de app (PgBouncer); não exposto à Internet.
4. Itens abertos que alimentam o risk register¶
Registro de IANA PEN · mTLS/CA-bundle para audit forwarding · SSO + SoD (RBAC E1) · mapa de fluxo de dados GDPR + DPA · cutover completo de RLS default-deny · edge rate-limit fail-closed. Rastreados no go/no-go de lançamento e no plano de remediação.