Threat Model — superficies comerciales SaaS (STRIDE)¶
Read in your language: English · Português · Español
audit-v6 DOCS-ARCH:
SECURITY_ZTP_PREM.mdcubre el modelo de amenaza insider on-prem; este documento cubre las superficies comerciales expuestas a Internet. Es un artefacto vivo — actualícelo cuando una superficie, flujo de datos o trust boundary cambie.
1. Alcance & trust boundaries¶
En el alcance: app.tlsstress.art (customer-app), admin.tlsstress.art
(admin-console), el edge worker de Cloudflare y la ingestión de usage-report
on-prem → SaaS. Fuera del alcance: el data plane aislado del test-bed NGFW
(lab operado por el operador; threat model on-prem separado en
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 firmados), operador↔admin-console (MFA).
2. Análisis STRIDE¶
| # | Amenaza (STRIDE) | Superficie | Mitigación (vigente) | Residual / follow-up |
|---|---|---|---|---|
| S1 | Spoofing de sesión de cliente | customer-app | JWT HS256, algoritmo fijado server-side (sin alg-confusion), timingSafeEqual, checks de exp/iat/iss/aud, denylist por request + staleness de credential-epoch (middleware + por ruta) |
— |
| S2 | Spoofing del reporter on-prem | usage ingest | Usage report firmado + usage_report_nonces (anti-replay) |
Rotar signing keys según cronograma |
| S3 | Spoofing de webhooks de Stripe | customer-app | Verificación de firma HMAC, fail-closed 503 cuando el secret no está seteado (payment y KYC tras audit-v6) | — |
| T1 | Tampering del audit trail | admin-console/DB | WORM: trigger en el DB bloquea UPDATE + DELETE temprano; hash chain SHA-256; export RFC-5424 firmado | Registrar un IANA PEN (actualmente placeholder) |
| T2 | Tampering de las imágenes de release | supply chain | Build multi-arch + firma cosign keyless + SBOM; release ahora en runners GitHub-hosted; todas las actions con SHA-pin (audit-v6) | — |
| R1 | Repudiation de acciones de admin | admin-console | Hash chain de admin_audit_events con actor + IP de origen + before/after |
SSO + SoD (depende de la épica RBAC E1) |
| I1 | Information disclosure cross-tenant | customer-app/DB | WHERE account_id por query; RLS tenant_isolation; withTenant() en rutas de tenant + guard test en CI (audit-v6) |
Cutover completo a default-deny (dual DB roles) |
| I2 | Information disclosure vía headers | edge/customer-app | El middleware remueve x-admin-*/x-customer-* entrantes antes de setear la identidad verificada; CSP con nonce por request y strict-dynamic |
— |
| I3 | Information disclosure de secrets | todas | Pepper/KMS fail-closed; sin secrets hardcodeados (gate gitleaks); guard de placeholder-secret rechaza REPLACE_ME (audit-v6) |
— |
| I4 | Information disclosure — KYC/PII | customer-app | Stripe Identity (los datos de KYC quedan en Stripe); redacción de PII en el audit log | Mapa de flujo de datos GDPR + DPA (track de privacidad) |
| D1 | Denial of service — brute force de auth | customer-app | Rate limiter LRU + respaldado en Postgres, fail-closed | — |
| D2 | Denial of service — edge | edge worker | Rate limit + reglas de WAF; rate cap del SLO | El rate-limit del edge falla abierto ante error de DO (rastreado) |
| D3 | Denial of service — body sobredimensionado | customer-app/dashboard | readJson() hace stream con tope de bytes (audit-v6 — bypass de chunked-encoding corregido) |
— |
| E1 | Elevation of privilege — refund IDOR | customer-app | La ruta de refund verifica charge.customer == cuenta de la sesión antes del refund; gated por MFA |
— |
| E2 | Elevation of privilege — auto-verificación de KYC | customer-app | Webhook de KYC fail-closed con secret sin setear (audit-v6) — un evento forjado ya no puede auto-verificarse | — |
| E3 | Elevation of privilege — K8s | on-prem control plane | pods/exec del pie-pa-executor namespaced; DaemonSets de host privilegiados aislados en dut-system; hostPath del dashboard removido (audit-v6) |
web-agents permanece PSA privileged — los init containers de DSCP/policy-routing de los agentes necesitan NET_ADMIN/NET_RAW, que baseline rechaza en la admission (revert del audit-v7) |
3. Supuestos¶
- El edge de Cloudflare termina TLS y es la primera capa de WAF/rate-limit.
- AWS KMS y Stripe son terceros confiables; su compromiso está fuera del alcance.
- Postgres es alcanzable solo desde el tier de app (PgBouncer); no expuesto a Internet.
4. Ítems abiertos que alimentan el risk register¶
Registro de IANA PEN · mTLS/CA-bundle para audit forwarding · SSO + SoD (RBAC E1) · mapa de flujo de datos GDPR + DPA · cutover completo de RLS default-deny · edge rate-limit fail-closed. Rastreados en el go/no-go de lanzamiento y en el plan de remediación.