From n00b to ZeroCool / El lado oscuro
Threat modeling sin humo: pensar como atacante para defender mejor
Threat modeling sin drama: STRIDE, activos y flujos con ejemplos reales y checklist para evitar sustos en producción sin volverte paranoico.
Lo que vale la pena leer aquí
Empiezas con lo típico: logs, métricas, pensar en rollback, buscar qué cambió “desde la tarde”. Y sí, a veces se arregla. Pero muchas de esas noches se evitan antes, cuando todavía estás diseñando el feature y no parchando production a ciegas.
Intro con gancho
Te cae un mensaje a las 2:17 a.m.: “Oye, el cliente dice que le aparecieron cargos raros… y el dashboard está lento”. Tú con tu laptop ya dando las últimas, el café recalentado y el Slack explotando.
Empiezas con lo típico: logs, métricas, pensar en rollback, buscar qué cambió “desde la tarde”. Y sí, a veces se arregla. Pero muchas de esas noches se evitan antes, cuando todavía estás diseñando el feature y no parchando production a ciegas.
Threat modeling es eso: sentarte un rato a pensar como atacante para encontrar lo que se puede romper, antes de que alguien (o algo) lo rompa por ti.
Qué vas a sacar de esto
- Cómo hacer threat modeling sin convertirlo en tesis ni “meeting infinito”.
- Cómo ubicar activos, fronteras de confianza y rutas de ataque en un flujo real.
- Cómo usar STRIDE (sin sufrir) para sacar amenazas accionables.
- Cómo convertir hallazgos en controles concretos: auth, autorización, rate limiting, logging, secretos, hardening.
- Un checklist final para meterlo a tu workflow aunque traigas deadline.
Contexto práctico: cuándo sí vale la pena (y cuándo no)
Threat modeling no es para vivir paranoico. Es para tomar decisiones con datos: qué riesgo aceptas, qué control metes y qué de plano no puedes dejar pasar.
Úsalo sí o sí cuando…
- Vas a tocar pagos, PII (datos personales), sesiones, permisos o admin panels.
- Estás abriendo una API pública, integrando webhooks o conectándote con terceros (Stripe, WhatsApp, Google, SAT… tú sabes).
- Te metiste a microservicios / event-driven y ahora hay 7 colas y 12 tokens volando.
- “Nomás es un formulario”, pero termina guardando CURP, RFC, domicilio y foto de INE (clásico en el jale).
Tal vez no (todavía) cuando…
- Es un prototipo interno sin datos sensibles y sin exposición a internet.
- Cambios de UI que no mueven permisos, datos o integraciones.
Decisión rápida: si no hay tiempo para hacerlo “bien”, hazlo express. 30 minutos: activos + flujo + top 5 amenazas. Con eso ya dejas de volar a ciegas.
Guía principal: threat modeling paso a paso (modo defensivo)
La meta no es juntar 200 amenazas para sentir que trabajaste. La meta es encontrar las 10 que sí te duelen y amarrar qué harás al respecto.
Paso 0: define el “qué” en una frase
Ejemplo:
“Usuarios se registran, inician sesión y consultan su estado de cuenta. Admins gestionan movimientos. Hay integraciones con un proveedor de pagos.”
Si no lo puedes decir simple, el sistema está demasiado borroso para modelarlo. Ahí el bug no es de seguridad: es de definición.
Paso 1: delimita alcance y supuestos
Anota lo que sí entra y lo que no. Esto mata discusiones eternas y te evita el “ah, yo pensé que alguien ya lo había configurado”.
- En alcance: API, app web, base de datos, storage, proveedor de pagos, panel admin.
- Fuera: seguridad física del datacenter, ataques al proveedor (pero sí consideras fallas de integración).
- Supuestos: TLS habilitado, WAF existe (si existe), IAM medio ordenado (si no, se dice).
Advertencia de guerra: el supuesto no escrito es el lugar favorito del incidente.
Paso 2: inventario de activos (lo que de verdad proteges)
No empieces por “hackers”. Empieza por lo que vale. Porque eso define prioridades.
Activos típicos:
- Datos: PII (nombre, correo, teléfono), tokens, movimientos, facturas.
- Dinero: cargos, reembolsos, cupones.
- Operación: disponibilidad (que no se caiga), reputación, cumplimiento.
- Credenciales: llaves API, secretos, certificados, sesiones.
Ponles prioridad Alto/Medio/Bajo. Si todo es “Alto”, terminas haciendo talacha sin foco.
Paso 3: dibuja el flujo (DFD) con fronteras de confianza
Un DFD no tiene que estar bonito. Tiene que estar honesto.
Ejemplo (texto):
- Usuario (Internet) → Frontend (CDN) → API Gateway
- API → Auth Service → DB de usuarios
- API → Payments Provider (salida a tercero)
- API → Storage (comprobantes)
- Admin (VPN o SSO) → Admin Panel → API
Marca fronteras de confianza:
- Internet ↔ tu infraestructura
- Tu red ↔ proveedor tercero
- App ↔ base de datos
- Usuario normal ↔ admin
Decisión práctica: cada frontera es un punto donde se vale exigir disciplina: validas, autenticas, autorizas, limitas y registras. Si no lo marcas, sueles asumir confianza de más.
Paso 4: aplica STRIDE por componente (pero con foco)
STRIDE te da un mapa mental para no olvidar categorías:
- Spoofing (suplantación)
- Tampering (alteración)
- Repudiation (no trazabilidad)
- Information disclosure (filtración)
- Denial of service (caída/abuso)
- Elevation of privilege (escalar permisos)
Hazlo por componente/flujo. Si lo haces “en el aire”, salen puras generalidades.
Ejemplo aterrizado: “Consulta de estado de cuenta”
Activo: movimientos y saldo (alto), sesión (alto).
- Spoofing: robo de sesión (cookies/token) o reutilización de tokens.
- Tampering: manipular
account_idpara ver otra cuenta (IDOR). - Repudiation: “yo no hice ese movimiento” y no tienes auditoría.
- Info disclosure: logs con datos sensibles, respuestas con demasiado detalle.
- DoS: scraping masivo de cuentas; bots pegándole al endpoint.
- EoP: usuario normal accede a endpoint admin por mala autorización.
Filo real: en muchos sistemas, el top 2 que te truena el negocio en una tarde es autorización (IDOR) y abuso/rate limiting. Lo demás también importa, pero esos dos son los que te dejan sin sueño.
Paso 5: baja amenazas a escenarios concretos (abuso realista)
No es “un atacante hackea”. Es:
- “Un usuario autenticado cambia un ID en la URL y ve datos ajenos.”
- “Un bot intenta 10k requests por minuto para enumerar cuentas.”
- “Un integrador manda webhooks falsos y marca pagos como pagados sin que haya pago.”
En la vida real (y más cuando hay prisa) se cuelan cosas como:
- Reuso de contraseñas y sesiones abiertas.
- Flujos por WhatsApp/Excel (“mándame el CSV y yo lo subo”) que acaban en leaks.
Paso 6: define controles (mitigaciones) con dueño y evidencia
Cada amenaza debe aterrizarse a algo verificable. Si no se puede verificar, no se puede defender.
Ejemplos de controles defensivos:
- Autorización server-side por recurso (no confíes en el frontend):
- Checar
resource.owner_id == user.id. - RBAC/ABAC claro para admin vs user.
- Checar
- Tokens/sesiones:
- Expiración corta, rotación, invalidación en eventos sensibles.
- Cookies
HttpOnly,Secure,SameSitedonde aplique.
- Webhooks de terceros:
- Verificación de firma (HMAC) y timestamp + replay protection.
- Rate limiting + detección:
- Límites por IP/usuario/endpoint.
- Alertas por spikes y patrones raros.
- Logging y auditoría:
- Bitácora de acciones admin, cambios de permisos, movimientos.
- Correlación con request-id.
- Manejo de secretos:
- Secrets manager, rotación, nunca en repo, nunca en logs.
Aterrízalo con “Dueño + Fecha + Prueba”. Ejemplo:
- Dueño: Backend
- Fecha: antes del deploy a prod
- Prueba: test automatizado + verificación en staging
Paso 7: prioriza con riesgo (rápido y útil)
Matriz simple: Impacto (1-5) x Probabilidad (1-5).
- Impacto alto: dinero/PII/admin.
- Probabilidad alta: endpoints públicos, features nuevos, integraciones.
Decisión incómoda pero sana: si el riesgo es alto y no hay mitigación, no es “deuda técnica”. Es “nos va a pegar un incidente”.
Paso 8: conviértelo en trabajo real (tickets y tests)
Threat modeling que no aterriza en tickets se vuelve documento de adorno.
Crea issues con formato:
- Amenaza
- Escenario
- Mitigación
- Criterio de aceptación
- Evidencia (test/log)
Snippet de criterio de aceptación (ejemplo IDOR):
Dado un usuario autenticado
Cuando solicita /accounts/{id}/statement con un id que no le pertenece
Entonces recibe 403
Y se registra el evento con request-id y user-id

Screenshots sugeridos
- Un diagrama simple del flujo (DFD) en Miro/Draw.io/FigJam con fronteras de confianza marcadas.
- Tabla de amenazas priorizadas (Impacto x Probabilidad) en Notion/Google Sheets.
- Ejemplo de ticket en Jira/GitHub Issues con criterios de aceptación.
- Captura de un dashboard de rate limiting/alertas (Cloudflare, NGINX, API Gateway, etc.).
Errores comunes + solución (cosas que sí pasan en el jale)
1) “Threat modeling es para cuando seamos enterprise”
Síntoma: lo posponen hasta que haya “equipo de seguridad”.
Arreglo: versión express: 30-45 min por feature crítico. Si ya tienes CI/CD y pull requests, tienes dónde colgarlo.
2) Confundir autenticación con autorización
Síntoma: “pero ya tiene JWT”.
Riesgo: IDOR, endpoints admin expuestos.
Arreglo: checks por recurso en backend + pruebas negativas (403) en endpoints sensibles.
3) Modelar el sistema ideal, no el real
Síntoma: el diagrama dice “SSO y VPN”, pero en la práctica el admin entra desde un café con WiFi chafa porque el jefe pidió el cambio “en corto”.
Arreglo: documenta el as-is y luego el to-be. Primero sobrevives, luego optimizas.
4) Olvidar integraciones (webhooks, cron jobs, scripts)
Síntoma: el ataque entra por “el script que sube facturas” que nadie revisa porque lo hizo un freelance mal cotizado y se quedó tal cual.
Arreglo: todo lo que tenga credenciales o toque datos entra al modelo. Incluye jobs y pipelines.
5) Mitigaciones que nadie puede verificar
Síntoma: “capacitar al equipo” como solución única.
Arreglo: acompaña con controles técnicos y evidencia: tests, config, alertas, auditoría.

Checklist final (para aplicar mañana sin drama)
- Definí el alcance en una frase y anoté supuestos.
- Listé activos y prioricé (qué duele más perder).
- Dibujé flujo con fronteras de confianza.
- Apliqué STRIDE a los componentes críticos (no todo el universo).
- Convertí amenazas a escenarios de abuso reales.
- Elegí mitigaciones con dueño, fecha y evidencia.
- Priorización Impacto x Probabilidad (top 5 primero).
- Abrí tickets y agregué criterios de aceptación + tests.
- Definí logging/auditoría para lo sensible.
- Quedó una nota de “qué aceptamos como riesgo” (con ok de la persona responsable).
FAQ
1) ¿Threat modeling es solo para apps web?
No. Sirve para APIs, mobile, infra, pipelines de datos, IoT… donde haya activos y fronteras de confianza.
2) ¿Qué tan seguido se hace?
Ideal: en features nuevos o cambios de arquitectura. Práctico: cada que tocas auth/permisos/datos sensibles/integraciones.
3) ¿STRIDE es obligatorio?
No, pero ayuda a no olvidar categorías. Si tu equipo va arrancando, STRIDE es buen andamio mental. Si ya tienen callo, lo puedes mezclar con casos de abuso y experiencia del stack.
4) ¿Cómo lo meto al workflow sin frenar el delivery?
Timebox. 45-60 min con quien implementa + alguien que revise (peer review). Output mínimo: diagrama simple + top amenazas + tickets. Si no hay tickets, no pasó.
5) ¿Cuál es la señal más clara de que necesitas threat modeling ya?
Cuando tienes integraciones y permisos, pero nadie puede explicar con seguridad: “¿quién puede ver qué, y por qué?”. Ese hueco se cobra caro.
Siguiente episodio
La mentalidad ya está. Ahora toca bajarla a práctica diaria: convertir tu threat model en controles que sí aguantan producción.
Spoiler: no todo es “más seguridad”. Es elegir el control correcto para el riesgo correcto, antes de que el primer susto te obligue a hacerlo con prisas.
Idea para cerrar bien este post: toma una sola práctica de aquí y conviértela en algo que tu equipo pueda aplicar hoy.
Cuando un artículo aterriza en decisiones reales, deja de ser contenido y se vuelve ventaja.


