---
name: threat-model-lite
description: Modelado de amenazas ligero basado en STRIDE simplificado. Identifica la superficie de ataque del sistema, los activos críticos, los flujos de datos sensibles y genera mitigaciones priorizadas. Diseñado para completarse en una sesión de trabajo, no en semanas.
version: "1.0.0"
herramientasPermitidas: [Read, Grep]
evolvable: true  # default para skill estandar
nist_csf: [ID.RA-01, ID.RA-03, ID.RA-04]
nist_ai_rmf: [MAP-1.1, MAP-5.1, MAP-5.2]
exclusiones:
  - "No cargar para implementar las mitigaciones técnicas identificadas (RBAC, rate limiting, TLS) — threat model produce el diagnóstico; para implementación cargar el skill del stack correspondiente."
  - "No cargar para auditoría de código buscando vulnerabilidades específicas (SQL injection, XSS en código) — para revisión de código de seguridad cargar `checklist-seguridad` o el skill de revisión del lenguaje."
  - "No cargar para análisis de cumplimiento normativo (PCI-DSS, SOC 2, ISO 27001) — el threat model es una entrada para el compliance, no el análisis de cumplimiento completo."
  - "No cargar para red-teaming o pruebas de penetración activas — threat model es análisis estático; para pentest activo usar herramientas especializadas con autorización explícita."
---
# Habilidad: Threat Model Lite

## Cuándo NO cargar

- La tarea es implementar las mitigaciones identificadas (RBAC, rate limiting, TLS): usar el skill del stack correspondiente para la implementación.
- La tarea es revisión de código buscando vulnerabilidades: cargar `checklist-seguridad`.
- La tarea es análisis de cumplimiento normativo (PCI-DSS, SOC 2): el threat model es una entrada, no el análisis completo.
- La tarea es pentest activo o red-teaming: usar herramientas especializadas con autorización explícita.

## Propósito

Un threat model completo toma semanas. Esta versión toma entre 2 y 4 horas y
cubre el 80% de los riesgos reales. El objetivo no es ser exhaustivo — es
identificar las amenazas de mayor impacto antes de que lleguen a producción.

## Cuándo activar

- Al diseñar un nuevo sistema o módulo crítico
- Antes del primer deploy a producción de una aplicación nueva
- Cuando el sistema maneja datos PII, financieros o de salud
- Cuando se añade una nueva integración con sistemas externos
- Como parte de la revisión de seguridad trimestral

---

## Paso 1 — Definir el alcance en 15 minutos

Responder estas 4 preguntas antes de proceder:

1. **¿Qué estamos protegiendo?** (activos: datos, dinero, reputación, disponibilidad)
2. **¿De quién lo protegemos?** (actores: usuarios maliciosos, atacantes externos,
   empleados deshonestos, errores accidentales)
3. **¿Cuál sería el peor escenario?** (impacto: pérdida de datos, fraude, downtime)
4. **¿Cuál es el perímetro del análisis?** (módulo específico, sistema completo,
   integración puntual)

Si no puedes responder estas preguntas, detente y habla con el stakeholder antes
de continuar.

---

## Paso 2 — Mapear la superficie de ataque

### Diagrama de flujo de datos (DFD simplificado)

Identificar y documentar:

**Puntos de entrada** (donde datos externos entran al sistema):
- [ ] Endpoints HTTP/REST públicos
- [ ] Endpoints autenticados
- [ ] Webhooks recibidos de sistemas externos
- [ ] Archivos cargados por usuarios
- [ ] Variables de entorno y configuración
- [ ] Mensajes de colas (Kafka, RabbitMQ, SQS)
- [ ] Interfaces de línea de comandos (CLI)

**Flujos de datos sensibles** (donde los datos críticos viajan):
- [ ] Datos de usuario en tránsito (login, sesión)
- [ ] Datos financieros (pagos, montos, cuentas)
- [ ] PII en requests/responses
- [ ] Tokens y credenciales en headers
- [ ] Datos en logs
- [ ] Datos exportados (CSV, PDF, reportes)

**Límites de confianza** (dónde cambia el nivel de confianza):
- [ ] Internet → API Gateway / Load Balancer
- [ ] API → Base de datos
- [ ] Microservicio A → Microservicio B
- [ ] Sistema interno → Sistema externo

---

## Paso 3 — STRIDE simplificado

Para cada punto de entrada y flujo de datos, evaluar las 6 categorías STRIDE:

### S — Spoofing (Suplantación de identidad)
**Pregunta**: ¿Puede un atacante hacerse pasar por un usuario legítimo?
- Autenticación débil o ausente en algún endpoint
- Tokens sin expiración o sin firma válida
- No verificación de origen en webhooks
- Reset de contraseña sin validación de identidad

### T — Tampering (Manipulación de datos)
**Pregunta**: ¿Puede un atacante modificar datos en tránsito o en reposo?
- Comunicación HTTP (no HTTPS) entre componentes internos
- HMAC ausente en mensajes de colas
- Validación insuficiente de inputs antes de persistir
- Archivos subidos sin verificación de integridad

### R — Repudiation (Repudio)
**Pregunta**: ¿Puede un actor negar haber realizado una acción?
- Acciones críticas sin audit log
- Logs sin timestamp confiable o sin integridad garantizada
- Sin registro de IP/agente en acciones de alto riesgo

### I — Information Disclosure (Divulgación de información)
**Pregunta**: ¿Puede un atacante acceder a información que no debería ver?
- Stack traces expuestos en respuestas de error
- Datos sensibles en logs
- Respuestas de API que revelan más de lo necesario
- Endpoints de debug accesibles en producción
- IDOR: acceso a recursos de otros usuarios

### D — Denial of Service (Denegación de servicio)
**Pregunta**: ¿Puede un atacante degradar o eliminar el servicio?
- Sin rate limiting en endpoints públicos
- Queries sin límite de resultados (full table scan por input del usuario)
- Archivos de tamaño ilimitado aceptados
- Operaciones costosas sin throttling

### E — Elevation of Privilege (Escalación de privilegios)
**Pregunta**: ¿Puede un usuario normal obtener permisos de administrador?
- RBAC incompleto o con brechas
- Endpoints de admin sin verificación de rol
- Parámetros de rol aceptados del cliente sin validación del servidor
- Tokens JWT con claims manipulables

---

## Paso 4 — Identificar activos críticos

Clasificar los activos del sistema por impacto si se comprometen:

| Activo | Tipo | Impacto si comprometido | Nivel |
|--------|------|------------------------|-------|
| Contraseñas de usuarios | PII + Auth | Acceso no autorizado a cuentas | CRÍTICO |
| Datos financieros | Financiero | Pérdida monetaria / fraude | CRÍTICO |
| PII (nombre, email, RFC) | PII | Violación de privacidad / LFPDPPP | ALTO |
| Tokens JWT | Auth | Suplantación de identidad | ALTO |
| Logs de acceso | Operacional | Pérdida de auditoría | MEDIO |
| Datos de configuración | Operacional | Exposición de infraestructura | MEDIO |

---

## Paso 5 — Generar mitigaciones priorizadas

Usar la matriz de riesgo para priorizar:

```
Riesgo = Probabilidad × Impacto

Probabilidad: 1 (baja) → 5 (casi seguro)
Impacto: 1 (insignificante) → 5 (crítico)
Prioridad: [1-5] Baja | [6-14] Media | [15-25] Alta
```

Para cada amenaza STRIDE encontrada, generar:

```markdown
### [ID-001] [Nombre de la amenaza]
- **Categoría STRIDE**: [S/T/R/I/D/E]
- **Activo afectado**: [nombre del activo]
- **Flujo de datos**: [de dónde a dónde]
- **Descripción del ataque**: [cómo un atacante lo exploraría]
- **Probabilidad**: [1-5] | **Impacto**: [1-5] | **Riesgo**: [producto]
- **Mitigación propuesta**: [solución técnica específica]
- **Costo de mitigación**: [Bajo/Medio/Alto]
- **Estado**: Pendiente / En progreso / Mitigado / Aceptado
```

---

## Plantilla de salida: `THREAT-MODEL.md`

```markdown
# THREAT-MODEL.md — [Nombre del Sistema]
**Fecha**: [fecha]  **Versión**: [N]  **Autor**: [agente/persona]

## Alcance
[Descripción del sistema y qué está dentro/fuera del análisis]

## Activos críticos
| Activo | Nivel | Propietario |
|--------|-------|------------|
|        |       |            |

## Superficie de ataque
### Puntos de entrada
- [lista]

### Flujos de datos sensibles
- [lista]

### Límites de confianza
- [lista]

## Amenazas identificadas
[Para cada amenaza, la ficha del formato anterior]

## Resumen de riesgos
| ID | Amenaza | Riesgo | Estado |
|----|---------|--------|--------|
|    |         |        |        |

## Plan de mitigación (priorizado)
| Prioridad | ID | Acción | Responsable | Fecha límite |
|-----------|---|--------|-------------|-------------|
| 1 (ALTO)  |   |        |             |             |
| 2 (MEDIO) |   |        |             |             |

## Amenazas aceptadas (con justificación)
| ID | Amenaza | Justificación | Quién aceptó |
|----|---------|--------------|-------------|
|    |         |              |             |

## Próxima revisión
**Fecha**: [fecha de revisión] o cuando ocurra: [evento trigger]
```

---

## Triggers para actualizar el modelo

El threat model debe revisarse cuando:
- Se añade un nuevo punto de entrada al sistema
- Se integra un servicio externo nuevo
- Se cambia el mecanismo de autenticación
- Los datos que maneja el sistema cambian de clasificación
- Se detecta una vulnerabilidad en producción

---

## Gotchas / Errores comunes no obvios

**El STRIDE simplificado de este skill omite sistemáticamente amenazas de "confused deputy" donde un servicio interno con privilegios elevados ejecuta acciones en nombre de un actor de menor privilegio sin verificar la identidad original**: en un microservicio de reportes que llama al microservicio de pagos usando credenciales de servicio (no del usuario), un atacante que compromete el microservicio de reportes puede consultar pagos de cualquier usuario. Causa: STRIDE evalúa cada componente aisladamente; las amenazas confused deputy emergen en la interacción entre dos límites de confianza. Fix: al mapear límites de confianza en el Paso 2, agregar explícitamente la pregunta: "¿Este servicio actúa en nombre de un actor? ¿Verifica que la acción solicitada está autorizada para ese actor específico?" Documentar la identidad que fluye entre servicios en el DFD.

**Las mitigaciones de prioridad calculadas con `Probabilidad × Impacto` son inconsistentes entre revisores porque la escala 1-5 es subjetiva y dos ingenieros pueden asignar probabilidad 2 vs 4 a la misma amenaza según su experiencia personal**: un equipo que usa el threat model sin calibración previa genera matrices de riesgo donde "SQL injection en el endpoint de búsqueda" tiene riesgo 6 para un revisor (Prob=2, Imp=3) y riesgo 20 para otro (Prob=4, Imp=5). Causa: las escalas ordinales sin anclas concretas son inherentemente subjetivas. Fix: antes de la sesión, calibrar la escala con 2-3 amenazas históricas conocidas del sector: "CVE-XXXX-YYYY tuvo Probabilidad=4 porque fue explotado activamente en los 6 meses anteriores al parche". Las anclas históricas reducen la varianza entre revisores.

**El THREAT-MODEL.md marcado como "Mitigado" para una amenaza de IDOR queda obsoleto en 3 meses cuando se agrega un nuevo endpoint de API que expone el mismo recurso sin la verificación de autorización implementada en los endpoints originales**: el threat model registra que "IDOR en `/api/v1/pedidos/{id}`" fue mitigado, pero el endpoint nuevo `/api/v2/orders/{id}` (agregado en sprint 14) no fue evaluado y tiene el mismo vector. Causa: el threat model es un documento puntual; los cambios incrementales al sistema no lo actualizan automáticamente. Fix: en el mapa de propagación de cambios del proyecto, agregar una regla: "nuevo endpoint en `api/` → verificar si el THREAT-MODEL.md cubre el nuevo recurso expuesto". Revisar las amenazas de tipo I (Information Disclosure) y E (Elevation of Privilege) del modelo cada vez que se añade un endpoint.

**La categoría S (Spoofing) suele generar mitigaciones de "agregar autenticación" que quedan como ítems en el backlog indefinidamente porque no tienen criterio de aceptación técnico medible**: la mitigación "implementar autenticación JWT en el endpoint" sin especificar qué claims verificar, qué algoritmo usar, qué TTL del token, ni cómo manejar revocación es inaccionable. El ticket se cierra cuando se agrega "cualquier autenticación" aunque sea trivialmente bypasseable. Causa: las mitigaciones STRIDE son descripciones de objetivo, no especificaciones técnicas. Fix: para cada mitigación en el plan de acción, agregar los criterios de aceptación mínimos: "Verificar firma RS256, audience claim = 'api.mi-sistema.com', exp < now() + 1h, validar contra JWKS endpoint del IdP. Test: request sin token retorna 401, request con token expirado retorna 401, request con audience incorrecta retorna 401."
