Clase 318 — Threat modeling para videojuegos

Parte: 19 — Ingeniería de producción, backend y confiabilidad · Fuente: OWASP Threat Modeling · Metodología STRIDE (Microsoft) ⏱️ Duración estimada: 115 min · Nivel: Avanzado


🎯 Objetivo

Aprender a modelar amenazas: un método sistemático para descubrir, antes de que ocurra, qué puede salir mal en tu juego y quién tiene incentivo para provocarlo. No es "pensar en seguridad": es un procedimiento con pasos, con una lista de comprobación y con un entregable — un documento que dice qué defiendes, de quién, y qué has decidido no defender y por qué.

La clase 154 enseñó a validar entradas y a cerrar exploits concretos. Esta clase es el paso anterior: cómo saber qué hay que validar. Vas a dibujar los límites de confianza de un juego, aplicar STRIDE a cada uno, priorizar por impacto y probabilidad, y derivar de ahí las defensas concretas — muchas de las cuales ya has construido en esta parte sin saber exactamente contra qué protegían.

Todo el contenido es defensivo: identificar riesgos en tu propio sistema y mitigarlos. No se enseñan técnicas para atacar juegos ajenos.

📚 Resultados de aprendizaje

Al finalizar, el alumno podrá:

  1. Dibujar un diagrama de flujo de datos con límites de confianza explícitos.
  2. Aplicar STRIDE sistemáticamente a cada elemento del diagrama.
  3. Identificar los activos de un juego y a quién le interesa atacarlos.
  4. Priorizar amenazas por impacto, probabilidad y coste de mitigación.
  5. Derivar controles concretos y trazarlos hasta el código que los implementa.
  6. Documentar riesgos aceptados con su justificación.
  7. Mantener el modelo vivo: revisarlo cuando cambia la arquitectura.

🗺️ Temas

# Tema Por qué importa
1 Activos Sin saber qué proteges, no puedes decidir cuánto invertir.
2 Atacantes e incentivos El perfil del atacante determina el nivel de defensa razonable.
3 Diagrama de flujo de datos Hace visible lo que se piensa "de memoria" y siempre incompleto.
4 Límite de confianza Es el concepto: todo cruce es un punto de validación.
5 STRIDE Seis categorías que cubren casi todo y evitan puntos ciegos.
6 Priorización No todo se puede mitigar: hay que elegir con criterio.
7 Controles La respuesta concreta a una amenaza concreta.
8 Riesgo aceptado Decidir no defender algo es legítimo si está escrito.
9 Trazabilidad Cada control debe apuntar al código o al proceso que lo cumple.
10 Modelo vivo Un modelo de hace dos años describe otro juego.

📖 Definiciones y características

🧰 Herramientas y preparación

No hace falta software: un diagrama y una tabla. Puedes usar papel, Graphviz o cualquier herramienta de diagramas. Documentación de referencia: OWASP Threat Modeling y la hoja de referencia de OWASP. El entregable de esta clase es un documento que se guarda en el repositorio junto al código, y se revisa como el código.

🧪 Laboratorio guiado

  1. Paso 1: los activos. Qué tienes que vale algo, y para quién:
Activo Valor para el jugador Valor para un atacante
Cuenta y progreso Muy alto (horas invertidas) Alto (reventa de cuentas)
Economía del juego Alto (esfuerzo) Muy alto (dinero real)
Integridad de la partida Muy alto (que sea justo) Medio (ventaja competitiva)
Datos personales Muy alto Alto (fraude, extorsión)
Disponibilidad del servicio Alto Bajo/medio (sabotaje, extorsión)
Contenido no publicado Bajo Medio (filtraciones, hype)
Código y assets Bajo Bajo/medio (clones, piratería)
  1. Paso 2: los atacantes. Nombrarlos evita defender de fantasmas y olvidar lo real:
Perfil Capacidad Incentivo Defensa proporcionada
Jugador curioso Baja (editar un JSON) Diversión Validación básica; asumible en single-player
Tramposo competitivo Media (herramientas públicas) Ganar Autoridad de servidor, detección de anomalías
Explotador de economía Media-alta Dinero real Idempotencia, auditoría, límites
Estafador de cuentas Media Reventa Autenticación fuerte, revocación
Atacante de disponibilidad Variable Sabotaje Límites, protección de infraestructura
Automatizador (bots) Alta Ventaja o beneficio Rate limiting, detección de patrones
  1. Paso 3: el diagrama con límites de confianza. El dibujo que hace visible lo invisible:
┌─────────────────── ZONA NO CONFIABLE (dispositivo del jugador) ──────────────────┐
│                                                                                  │
│   ┌──────────┐      ┌────────────┐      ┌──────────────┐      ┌──────────────┐   │
│   │  Entrada │─────►│  Cliente   │─────►│ Save local   │      │ Mods / packs │   │
│   │ (teclado)│      │  del juego │◄─────│ (user://)    │─────►│ (user://)    │   │
│   └──────────┘      └─────┬──────┘      └──────────────┘      └──────────────┘   │
│                           │                                                      │
└───────────────────────────┼══════ LÍMITE DE CONFIANZA (la red) ══════════════════┘
                            │
┌───────────────────────────┼─────────── ZONA CONFIABLE (tu backend) ──────────────┐
│                    ┌──────▼───────┐                                              │
│                    │ API Gateway  │  ◄── autenticación, límites, validación       │
│                    └──┬────────┬──┘                                              │
│          ┌────────────▼──┐  ┌──▼───────────┐  ┌──────────────┐                   │
│          │ Perfil/Economía│  │ Matchmaking │  │ Telemetría   │                   │
│          └────────┬───────┘  └──────┬──────┘  └──────────────┘                   │
│                   │                 │                                            │
│            ┌──────▼──────┐   ┌──────▼─────────┐                                  │
│            │ Base de datos│   │ Servidor       │ ◄── simulación autoritativa       │
│            └─────────────┘   │ dedicado       │                                  │
│                              └────────────────┘                                  │
└──────────────────────────────────────────────────────────────────────────────────┘

Ese doble trazo es lo único que hay que recordar: todo lo que lo cruza de arriba abajo se valida. Sin excepciones, sin "esto lo manda nuestro propio cliente".

  1. Paso 4: STRIDE, elemento por elemento. La parte mecánica, y por eso funciona:
Elemento S T R I D E
Cliente del juego ✔ binario y memoria modificables ✔ expone datos del mundo ✔ si valida él
Save local ✔ editable ✔ contiene estado
Red cliente↔servidor ✔ suplantar sesión ✔ paquetes alterados ✔ negar acción ✔ escucha ✔ inundación
API Gateway ✔ token robado ✔ parámetros ✔ sin registro ✔ mensajes de error ✔ sin límites ✔ autorización débil
Servicio de economía ✔ duplicación ✔ "yo no compré" ✔ operaciones caras ✔ operar sobre otro
Servidor dedicado ✔ cliente falso ✔ estado inyectado ✔ ve todo el mapa ✔ colgarlo
Mods / packs ✔ suplantar mod oficial ✔ contenido alterado ✔ leer archivos ✔ romper el juego ✔ ejecutar código
Telemetría ✔ eventos falsos ✔ métricas envenenadas ✔ datos personales ✔ inundar la ingesta
  1. Paso 5: priorizar. No todo se mitiga; hay que elegir con criterio, no con miedo:
Riesgo ≈ Impacto × Probabilidad ÷ Coste de mitigación

Impacto:      1 molesto · 2 perjudica a un jugador · 3 perjudica a muchos
              4 daña la economía o la confianza · 5 daño legal o de negocio
Probabilidad: 1 requiere capacidades excepcionales · 3 herramientas públicas
              5 lo hará alguien la primera semana
Amenaza I P Riesgo Mitigación Estado
Cliente decide su oro 5 5 Crítico Autoridad de servidor (clase 314) Implementado
Duplicación por reintento 5 4 Crítico Claves de idempotencia (314) Implementado
Token robado sin revocación 4 3 Alto Rotación y revocación (312) Implementado
Speed hack en partida 3 4 Alto Validación de movimiento (148, 319) Implementado
Editar el save en single-player 1 5 Bajo Aceptado: no afecta a terceros Aceptado
Mod malicioso 4 2 Medio Consentimiento informado, plataforma (309) Parcial
Ver la posición de rivales 3 3 Medio No enviar lo que no se ve (fog of war en servidor) Pendiente
Inundar la ingesta de telemetría 2 2 Bajo Rate limiting y cuotas (316) Implementado
  1. Paso 6: la trazabilidad. Un control que no apunta a código es una intención:
### C-07 — Toda operación económica es idempotente

- **Amenaza**: T (tampering) / duplicación por reintento en el límite de red.
- **Control**: clave de idempotencia generada por el cliente, resultado
  memorizado en el servidor.
- **Implementación**: `servidor/economia/servicio_economia.gd:ejecutar()`
- **Verificación**: `pruebas/economia_test.gd` — "el mismo comando cinco veces
  produce un solo efecto".
- **Riesgo residual**: una clave reutilizada intencionadamente por el cliente
  para "cancelar" una compra legítima. Mitigado por caducidad de 24 h.
  1. Paso 7: los riesgos aceptados. Escribirlos es lo que los convierte en decisiones:
### RA-02 — El save local es editable

El jugador puede modificar `user://saves/slot_0.json` y darse objetos.

- **Por qué se acepta**: en modo un jugador no perjudica a terceros ni a la
  economía (que es local). Impedirlo requeriría autoridad de servidor para una
  experiencia offline, con un coste desproporcionado.
- **Límite**: si en el futuro hay tablas de clasificación **globales** o
  intercambio de objetos entre jugadores, este riesgo deja de ser aceptable y
  hay que revisar la decisión.
- **Detección**: el checksum detecta ediciones torpes y se registra como
  telemetría anónima, sin sancionar.

Ese apartado "límite" es lo que hace útil el documento a los dos años: dice cuándo deja de valer la decisión.

  1. Paso 8: mantenerlo vivo. Un modelo que no se revisa describe un juego que ya no existe:

✍️ Ejercicios

  1. Dibuja el DFD de tu propio juego con sus límites de confianza reales.
  2. Aplica STRIDE a los tres elementos que más te preocupen y anota al menos dos amenazas por elemento.
  3. Prioriza las amenazas encontradas con la fórmula del paso 5.
  4. Escribe tres fichas de control con su trazabilidad a código y prueba.
  5. Escribe dos riesgos aceptados con su condición de caducidad.
  6. Revisa el modelo suponiendo que añades intercambio de objetos entre jugadores: ¿qué cambia?
  7. Haz una sesión de modelado de 45 minutos con otra persona y compara los hallazgos.

📝 Reto verificable

Entrega un documento de modelo de amenazas de un juego (el tuyo o el del capstone) en docs/modelo-amenazas.md que contenga: inventario de activos, perfiles de atacante, DFD con límites de confianza, tabla STRIDE completa para al menos seis elementos, priorización cuantificada de al menos doce amenazas, al menos ocho fichas de control con trazabilidad a archivo y prueba, y al menos tres riesgos aceptados con su condición de caducidad.

Criterio de aceptación: (a) cada elemento del DFD aparece en la tabla STRIDE con las seis categorías consideradas (aunque sea para descartarlas con motivo); (b) cada amenaza priorizada tiene impacto, probabilidad y estado; (c) cada ficha de control apunta a un archivo y una prueba que existen en el repositorio y pasan; (d) cada riesgo aceptado indica explícitamente qué cambio lo haría inaceptable; (e) el documento identifica al menos una amenaza que no estuviera ya mitigada, con su plan; (f) el documento indica su fecha de revisión y qué eventos disparan la siguiente.

⚠️ Errores comunes

Síntoma / mensaje Causa y cómo arreglar
El modelo dice "validamos todo" y no dice dónde Falta trazabilidad. Cada control apunta a archivo y prueba.
Se defienden amenazas improbables y falta lo obvio No se priorizó. Aplica impacto × probabilidad.
El diagrama no tiene límites de confianza Es un diagrama de arquitectura, no un DFD. Dibuja las fronteras.
"Nuestro cliente no manda datos falsos" Confianza en el cliente. Todo lo que cruza el límite se valida.
El modelo tiene dos años y la arquitectura cambió No hay proceso de revisión. Ligalo a los cambios de arquitectura.
Se aceptan riesgos sin escribirlos Entonces no son decisiones, son olvidos. Documenta con su caducidad.
El modelo lo hizo una persona sola Se pierden puntos ciegos. Hazlo en pareja o en grupo pequeño.
Se confunden amenazas con vulnerabilidades La amenaza es lo que alguien quiere hacer; la vulnerabilidad, el fallo que se lo permite. Modela lo primero.

❓ Preguntas frecuentes

❓ ¿Es esto necesario para un juego indie? El método completo, no siempre. Pero el dibujo de límites de confianza y una pasada de STRIDE ocupan una tarde y cambian decisiones de arquitectura que después cuestan meses. Si tu juego tiene cualquier componente online, hazlo.

❓ ¿STRIDE u otra metodología? STRIDE es la más fácil de aplicar sin formación previa y cubre bien el caso de los juegos. Existen otras (PASTA, LINDDUN para privacidad) más completas y más caras de aplicar. Para privacidad, LINDDUN complementa bien lo de la clase 317.

❓ ¿Cuándo hago el modelo? Al diseñar la arquitectura, antes de implementarla: es cuando cambiar decisiones es barato. Después se revisa, no se rehace. Hacerlo al final convierte hallazgos en deuda.

❓ ¿Y si encuentro una amenaza que no puedo mitigar? La documentas como riesgo aceptado con su justificación y su condición de caducidad, y añades detección aunque no puedas prevenir. Saber que está ocurriendo ya es una mitigación parcial: es lo que permite reaccionar.

❓ ¿Esto no enseña a atacar? Enseña a encontrar tus propios fallos, que es lo mismo que hace cualquier revisión de seguridad. No incluye herramientas ni técnicas ofensivas, y la clase 319 mantiene el mismo criterio: defensa de lo tuyo, nunca ataque a lo ajeno.

🔗 Referencias

⬅️ Clase anterior

Clase 317 - Telemetría, privacidad y gobernanza de datos

➡️ Siguiente clase

Clase 319 - Anti-cheat y respuesta frente al abuso