Módulo 1: Threat Modeling Andes Cargo

3. Qué es el modelado de amenazas y el framework STRIDE

Descripción

La lección 2 te dejó con siete preguntas sin contestar y ninguna forma sistemática de encontrar más. Esta lección resuelve eso: modelado de amenazas es el proceso estructurado de responder, para un sistema real, tres preguntas —¿qué estamos construyendo?, ¿qué puede salir mal?, ¿qué vamos a hacer al respecto?— antes de que algo salga mal de verdad. Y STRIDE es el framework, creado por ingenieros de Microsoft a fines de los años noventa y todavía el más usado de la industria, que le da estructura a la segunda pregunta: seis categorías, cada una nombrando una forma distinta en que un sistema puede fallar en seguridad.

Conexión con el módulo

Esta lección es puramente conceptual —a propósito, sin ningún comando todavía—. Cada una de las seis categorías que vas a aprender aquí, con un ejemplo genérico, reaparece en la lección 5 con un hallazgo específico y real de Andes Cargo. Piensa en esta lección como aprender el alfabeto antes de leer la palabra completa.


Modelado de amenazas: la pregunta antes de la pregunta

Antes de STRIDE, antes de cualquier framework, el modelado de amenazas es una disciplina simple de nombrar y difícil de mantener bajo presión de entrega: en vez de esperar a que algo falle para preguntarse por qué falló, alguien se sienta —con un diagrama del sistema real, no uno idealizado— y se pregunta, deliberadamente, qué podría salir mal. La Fundación OWASP lo resume con tres preguntas que vale la pena memorizar literalmente:

  1. ¿En qué estamos trabajando? — un diagrama del sistema real: qué componentes existen, cómo se comunican, dónde cruzan un límite de confianza (por ejemplo, del internet público hacia tu VPC, o de un rol EC2 hacia un bucket S3).
  2. ¿Qué puede salir mal? — la pregunta que STRIDE estructura, categoría por categoría.
  3. ¿Qué vamos a hacer al respecto? — la respuesta se convierte en un control concreto, con un dueño y, en esta guía, con el módulo exacto que lo construye.

La lección 4 de este módulo resuelve la primera pregunta para Andes Cargo (el diagrama real, con comandos, no imaginado). La lección 5 resuelve la segunda con STRIDE. Las lecciones 7 y 8 documentan la tercera.

Por qué esto se hace antes de escribir código de seguridad, no después. La analogía correcta —y la que vas a usar en toda esta guía— es la de un inspector de edificios: revisar el plano antes de que se ponga el primer ladrillo cuesta una tarde de trabajo y un cambio de diseño en papel; revisar el edificio terminado y descubrir que falta una salida de emergencia cuesta demoler una pared. El modelado de amenazas es, literalmente, revisar el plano. Escanear infraestructura ya desplegada (lo que vas a hacer en el Módulo 5 de esta guía) es valioso, pero es el segundo tipo de revisión, no un sustituto del primero.


STRIDE: las seis formas en que un candado puede fallar

STRIDE es un acrónimo mnemónico: Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege. Cada letra nombra una categoría distinta de amenaza, y cada una responde a una pregunta distinta sobre un sistema. Antes de cualquier ejemplo técnico, vale la pena una analogía cotidiana única que sostiene las seis a la vez: piensa en tu casa, con una puerta, una cerradura, y las distintas formas en que esa seguridad puede fallar —no todas son "alguien rompió la puerta a patadas". La mayoría son más sutiles que eso, y esa es exactamente la razón por la que STRIDE tiene seis categorías en vez de una sola llamada "ataque".

S — Spoofing (suplantación)

Definición oficial (Microsoft Learn): "Involves illegally accessing and then using another user's authentication information, such as username and password." — usar, sin permiso, las credenciales de identidad de otro para pasar por él.

Analogía cotidiana. Alguien se presenta en la puerta de tu edificio con una llave que no es suya —la copió, la robó, o simplemente la encontró— y el portero, viendo solo que la llave gira en la cerradura, lo deja pasar sin verificar que sea realmente el inquilino. La cerradura no distingue entre "el dueño legítimo de esta llave" y "cualquiera que tenga esta llave física en la mano".

Ejemplo técnico. Una credencial de AWS de larga vida —un AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY estático— funciona exactamente como esa llave física: cualquiera que la tenga, sin importar quién sea, puede autenticarse como si fuera el sistema legítimo que originalmente la recibió. Si esa credencial se filtra —en un log, en un commit de Git, en una captura de pantalla compartida por error—, quien la encuentre puede hacerse pasar por el pipeline de Andes Cargo ante AWS, indistinguible del pipeline real desde el punto de vista de la API.

T — Tampering (alteración)

Definición oficial: "Involves the malicious modification of data [...] such as that held in a database, and the alteration of data as it flows between two computers over an open network."

Analogía cotidiana. Un paquete llega a tu puerta con el sello del remitente roto y vuelto a pegar —alguien lo abrió en el camino, quizás cambió lo que había adentro, y lo volvió a cerrar para que pareciera intacto. Sin ese sello, no hay ninguna forma de distinguir un paquete que viajó sin tocar de uno que alguien manipuló en el trayecto.

Ejemplo técnico. Un artefacto de despliegue —el .zip que empaqueta el código de una función Lambda— que nadie firma es exactamente ese paquete sin sello. Entre el momento en que un ingeniero revisó el código y el momento en que ese .zip se despliega de verdad, nada impide que el archivo cambie —un byte, una línea, una dependencia entera— sin que ningún paso del proceso lo note.

R — Repudiation (repudio)

Definición oficial: "Associated with users who deny performing an action without other parties having any way to prove otherwise [...] a user performs an illegal operation in a system that lacks the ability to trace the prohibited operations."

Analogía cotidiana. Tu edificio no tiene ni cámara de seguridad ni libro de registro de visitas. Si algo desaparece de un departamento, cualquiera que haya entrado ese día puede negar haber estado ahí —y nadie, ni el portero ni el resto de los inquilinos, tiene ninguna forma de probar lo contrario. No es que alguien mienta con éxito porque es convincente; es que el sistema mismo nunca guardó la evidencia que permitiría desmentirlo.

Ejemplo técnico. Un cambio de infraestructura aplicado sin que exista ningún trail de auditoría —sin CloudTrail, sin ningún registro de qué identidad ejecutó qué llamada y cuándo— deja al equipo en la misma posición que el edificio sin cámaras: si una política de IAM cambia de forma inesperada, no hay ningún registro consultable para responder "¿quién hizo esto, y cuándo?" con evidencia, solo con memoria y suposiciones.

I — Information disclosure (divulgación de información)

Definición oficial: "Involves the exposure of information to individuals who are not supposed to have access to it [...] the ability of users to read a file that they were not granted access to."

Analogía cotidiana. Un archivador con documentos privados queda en un pasillo de acceso público, sin llave, porque nadie pensó que hiciera falta cerrarlo —no porque alguien lo forzó, sino porque nunca tuvo ninguna cerradura en primer lugar. Cualquiera que pase por ese pasillo puede abrirlo y leer lo que hay adentro.

Ejemplo técnico. Un bucket S3 sin ningún bloqueo de acceso público configurado —ni a nivel de cuenta ni a nivel de bucket— es ese archivador sin cerradura: nada en la configuración actual lo hace público hoy, pero tampoco nada impide que un cambio futuro (una política mal escrita, un ACL aplicado sin pensarlo) lo vuelva público sin que ninguna capa lo detenga antes de que pase.

D — Denial of service (denegación de servicio)

Definición oficial: "Deny service to valid users [...] you must protect against certain types of DoS threats simply to improve system availability and reliability."

Analogía cotidiana. Alguien estaciona un auto bloqueando la única entrada de tu edificio. Nadie entró por la fuerza, nadie robó nada —pero, mientras el auto siga ahí, ningún inquilino legítimo puede entrar ni salir. La disponibilidad del edificio, no su contenido, es lo que queda comprometido.

Ejemplo técnico. Esta categoría suele asociarse, primero, con un ataque de red que satura un servidor de tráfico — pero la definición oficial de Microsoft es más amplia: cualquier cosa que le niegue servicio a un usuario legítimo cuenta. Un cambio de infraestructura que borra la única tabla que sostiene el estado de negocio de un sistema —sin que nada lo impida antes de aplicarse— es, en este sentido preciso, una denegación de servicio: nadie atacó el sistema desde afuera, pero el resultado —el sistema deja de estar disponible para sus usuarios reales— es exactamente el que esta categoría nombra. Vas a ver este caso concreto en la lección 5.

E — Elevation of privilege (elevación de privilegios)

Definición oficial: "An unprivileged user gains privileged access and thereby has sufficient access to compromise or destroy the entire system."

Analogía cotidiana. Te dan una tarjeta de acceso para tu habitación de hotel, y esa misma tarjeta, sin que nadie te lo haya pedido ni tú lo hayas notado, también abre todas las demás habitaciones del piso, la lavandería y la oficina del gerente. No hiciste nada para conseguir ese acceso extra —simplemente te lo dieron, de más, sin que nadie revisara si de verdad lo necesitabas.

Ejemplo técnico. Un rol IAM al que se le otorgó, "por si acaso" o por copiar y pegar una política existente, más permisos de los que el código que lo usa realmente ejecuta —s3:* cuando el código solo llama s3:GetObject, o acceso al bucket completo cuando solo necesita un prefijo— es esa tarjeta de hotel de más. Nadie "elevó" el privilegio con un ataque activo; el privilegio de más ya estaba ahí desde el diseño, esperando a que alguien —o algo, un proceso comprometido con ese rol— lo usara.


El diagrama de flujo de datos: dónde vive cada categoría

STRIDE se aplica sobre un diagrama de flujo de datos (DFD, por sus siglas en inglés) — una representación simple de qué componentes existen y por dónde cruza la información entre ellos, con especial atención a los límites de confianza: los puntos donde el nivel de confianza cambia (de "internet público" a "tu VPC", de "un rol EC2" a "un bucket S3"). Un boceto mínimo, aplicado al flujo central de Andes Cargo — sin todavía los nombres reales de recursos, que llegan en la lección 4 —:

   [ GitHub Actions runner ]
            │
            │ credenciales AWS ─────────────── (1) LÍMITE DE CONFIANZA:
            ▼                                       ¿quién puede autenticarse
   [ Terraform / awslocal ]                          como este pipeline?
            │
            │ llamadas a la API de AWS
            ▼
   [ Bucket S3 ] ──(evento)──▶ [ Función Lambda ] ──(escribe)──▶ [ Tabla DynamoDB ]
        ▲                              │
        │ lee                          │ rol de ejecución
        │                              ▼
   [ Rol EC2 / App de tracking ]   [ IAM Role ] ─────────────── (2) LÍMITE DE CONFIANZA:
                                                                     ¿este rol puede hacer
                                                                     más de lo que necesita?

Cada flecha de este diagrama es un candidato a alguna categoría de STRIDE: la flecha de credenciales (1) es donde vive el riesgo de Spoofing; el rol de ejecución (2) es donde vive el riesgo de Elevation of privilege; el propio bucket es donde vive Information disclosure; y así sucesivamente. La lección 4 construye este mismo diagrama con nombres reales y con evidencia de comandos reales —no un boceto, un inventario—.


Una amenaza puede caer en más de una categoría, y eso es normal

Una credencial de larga vida filtrada no es únicamente un riesgo de Spoofing (alguien se hace pasar por el pipeline) — también habilita, en cadena, Tampering (esa identidad podría modificar recursos) y Elevation of privilege si el rol asociado tiene más permisos de los necesarios. STRIDE no exige que cada amenaza tenga una única categoría "correcta" — exige que, para cada componente del sistema, te preguntes las seis categorías, una por una, sin saltarte ninguna. Es exactamente el mismo tipo de disciplina que un piloto usa con una lista de verificación antes de despegar: no porque espere que todos los puntos fallen, sino porque el costo de no revisar uno que sí estaba fallando es demasiado alto para confiar en la memoria.


Errores comunes

Tratar STRIDE como una lista de ataques específicos en vez de categorías de pregunta (de definición). Qué pasa: alguien intenta memorizar "los ataques de Spoofing" como una lista cerrada (phishing, robo de contraseña, etc.) en vez de entender la pregunta de fondo que la categoría hace. Cómo detectarlo: si frente a un componente nuevo de un sistema no sabes qué preguntarte para cada letra, aunque memorizaste ejemplos de otros sistemas. Cómo corregirlo: cada letra es una pregunta reutilizable, no una lista de casos —Spoofing: "¿cómo sabe este componente que quien le habla es quien dice ser?"; Tampering: "¿qué le impide a alguien modificar esto sin que se note?"; y así con las seis—. Aplica la pregunta al componente real, no busques si coincide con un ejemplo memorizado.

Confundir Information disclosure con "cualquier dato que exista en el sistema" (de alcance). Qué pasa: alguien marca como riesgo de Information disclosure cualquier dato sensible que el sistema procesa, sin importar si de verdad hay algún camino por el cual alguien no autorizado podría leerlo. Cómo detectarlo: si tu hallazgo de Information disclosure no incluye ningún mecanismo concreto por el cual la exposición podría ocurrir. Cómo corregirlo: la categoría exige un camino real —una ausencia de control específica (como un bloqueo de acceso público que no existe), no la mera existencia de datos sensibles en algún lugar del sistema. "Este sistema procesa datos de envíos" no es, por sí solo, un hallazgo de Information disclosure; "este bucket no tiene bloqueo de acceso público configurado" sí lo es.

Pensar que Denial of service siempre significa un ataque de red (de expectativa). Qué pasa: alguien descarta la categoría D para un sistema sin ningún componente de cara al público en internet, asumiendo que DoS solo aplica a servidores web bajo tráfico malicioso. Cómo detectarlo: si tu análisis de D para un sistema interno se queda en blanco, "no aplica". Cómo corregirlo: la definición oficial de Microsoft es explícitamente más amplia —cualquier cosa que niegue servicio a un usuario legítimo cuenta, incluida la pérdida de un recurso crítico por un cambio de infraestructura sin control—. Vas a ver, en la lección 5, un ejemplo de D en Andes Cargo que no tiene nada que ver con tráfico de red.


Ejercicios

Ejercicio 1 — Clasifica cuatro escenarios cotidianos con la letra correcta de STRIDE. Para cada uno, nombra la categoría (o categorías) que aplica y justifica en una frase: (a) alguien usa una copia de la llave de un compañero de trabajo para entrar a la oficina fuera de horario; (b) un empleado firma un documento pero después niega haberlo hecho, y la empresa no tiene ningún registro que lo contradiga; (c) un formulario web permite que cualquier usuario autenticado edite el perfil de cualquier otro usuario, no solo el propio; (d) un servicio de streaming se cae porque un solo usuario abrió miles de conexiones simultáneas a propósito.

Ver solución

(a) Spoofing — usar la identidad (la llave) de otra persona para acceder. (b) Repudiation — la ausencia de un registro verificable permite negar la acción sin consecuencia. (c) Elevation of privilege — un usuario obtiene, sin autorización explícita, la capacidad de actuar sobre recursos que no le pertenecen (aunque también podría discutirse como una falla de autorización más amplia, la categoría central es E). (d) Denial of service — el uso legítimo (o abusivo) de una capacidad del sistema deja a otros usuarios sin servicio, el caso clásico de la categoría.

Ejercicio 2 — Explica por qué un secreto en texto plano en un repositorio Git puede clasificarse en más de una categoría de STRIDE. Usando el .secrets que ya conoces de cicd-and-gitops-on-aws-guide, explica qué categorías de STRIDE aplicarían si ese archivo, por error, terminara commiteado al historial de Git, y por qué.

Ver solución

Al menos dos categorías aplican directamente. Information disclosure: el secreto queda expuesto a cualquiera con acceso de lectura al repositorio —incluido, para siempre, el historial de Git, incluso si el archivo se borra después—, sin que existiera ningún control que lo protegiera. Spoofing: una vez expuesta, esa credencial permite que cualquiera que la lea se autentique ante AWS como si fuera el sistema legítimo que la usa —el mismo riesgo de suplantación que ya viste en el ejemplo técnico de la categoría S de esta lección—. Dependiendo de qué permisos tenga esa credencial, también podría habilitar Tampering o Elevation of privilege en cadena. La lección demuestra, con un caso concreto, por qué STRIDE no exige elegir una única categoría "correcta".

Ejercicio 3 — Aplica la pregunta de Elevation of privilege a un escenario nuevo, sin usar el ejemplo de la lección. Sin usar el ejemplo de s3:* de esta lección, describe un escenario de infraestructura cloud —cualquier servicio, no necesariamente de Andes Cargo— donde un componente tenga más privilegio del que su función real requiere, y explica cómo lo detectarías.

Ver solución

No hay una única respuesta correcta, pero un ejemplo típico: una instancia EC2 con un rol IAM que incluye permiso de iam:CreateUser o iam:AttachRolePolicy, cuando la aplicación que corre en esa instancia solo necesita leer de una cola SQS. Se detectaría comparando, línea por línea, la política de permisos adjunta al rol contra las llamadas de API que el código de la aplicación realmente ejecuta —exactamente el mismo método que vas a practicar en la lección 4 de este módulo con AppServerRole y LambdaManifestProcessorRole—. Cualquier escenario donde el permiso otorgado exceda, de forma verificable, el permiso que el código usa, es una respuesta válida.


Resumen y siguiente paso

En esta lección aprendiste el vocabulario central de esta guía: modelado de amenazas como las tres preguntas de OWASP, y STRIDE como el framework que estructura la segunda. Viste las seis categorías —Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege—, cada una con su definición oficial de Microsoft, una analogía cotidiana compartida (tu casa, su cerradura, y las formas en que esa seguridad puede fallar) y un primer ejemplo técnico. Y viste el diagrama de flujo de datos como la herramienta que ubica dónde, dentro de un sistema real, vive cada categoría.

Antes de avanzar deberías poder: nombrar las seis categorías de STRIDE de memoria, con su pregunta central, sin necesitar el acrónimo escrito enfrente; explicar por qué una sola amenaza puede caer en más de una categoría a la vez; y dibujar, de memoria, un diagrama de flujo de datos mínimo con al menos un límite de confianza señalado.

La lección 4 deja atrás los ejemplos genéricos: vas a construir el inventario real de la superficie de ataque de Andes Cargo, con los comandos exactos que un profesional de seguridad correría primero.

Recursos

  1. Microsoft Learn — Threats: Microsoft Threat Modeling Tool — la fuente oficial de las seis definiciones de STRIDE citadas literalmente en esta lección.
  2. OWASP Cheat Sheet Series — Threat Modeling Cheat Sheet — las tres preguntas del modelado de amenazas ("¿en qué estamos trabajando?", "¿qué puede salir mal?", "¿qué vamos a hacer al respecto?") y la guía completa de diagramas de flujo de datos y límites de confianza.
  3. AWS Well-Architected Framework — SEC01-BP07: Identify threats and prioritize mitigations using a threat model — la recomendación oficial de AWS de modelar amenazas como práctica de diseño, no como revisión posterior.