Skip to content

English · Español

03 — Threat modeling, con números

La matriz de amenazas no necesita LaTeX, necesita una hoja de cálculo. Para cada clase de ataque: \(R = P \cdot S \cdot (1 - D)\). \(P\) = probabilidad de intento, \(S\) = severidad (1-5), \(D\) = probabilidad de detección. Las estimaciones son honestas, no medidas — pero llenar la fila es lo que fuerza la conversación.


Por qué un número, no una sensación

Dos modos de fallo comunes en el trabajo de seguridad:

  1. Ranking solo por sensaciones. "Pickle es malo, el envenenamiento de RAG es malo, deberíamos arreglar el peor primero". ¿Cuál es el peor? La discusión es ilimitada; todos tienen una opinión.
  2. Rigor de teatro. Marcos de evaluación de riesgo de varias páginas (CVSS, DREAD) calibrados contra datasets de la industria que el equipo nunca ha visto. El esfuerzo va al marco, no a las amenazas.

El camino intermedio: asigna tres números por amenaza, multiplícalos, ordena. Los números son estimaciones. El objetivo es forzar una comparación, no pretender medir riesgo absoluto.

La fórmula

Para cada amenaza \(T\):

\[R_T = P_T \cdot S_T \cdot (1 - D_T)\]

Donde:

  • \(P_T \in [0, 1]\) — probabilidad de un intento durante la vida del sistema.
  • \(S_T \in \{1, 2, 3, 4, 5\}\) — severidad si el intento tiene éxito. (1 = molestia; 5 = compromiso completo del host.)
  • \(D_T \in [0, 1]\) — probabilidad de que las defensas actuales detecten o bloqueen el intento.

\(R_T\) es una puntuación de riesgo residual. Más alto = más importante de arreglar. La escala es arbitraria; solo importan los rangos relativos.

Por qué no solo severidad

"Ordena por severidad" es la jugada equivocada cuando la mitad de las amenazas son severidad 5 (RCE en el host, exfiltración de datos, corrupción de modelo) y la otra mitad también son 5/5. La probabilidad y la detección son lo que discrimina.

Por qué incluir detección

Un ataque de alta severidad con alta probabilidad de detección es menos urgente de mitigar que un ataque de severidad media con baja detección. El término de detección captura el valor de las defensas existentes (schema de Fase 30, sandbox de Fase 32, redactor de logs de Fase 34).

La matriz del tutor de gramática

Números concretos para el tutor de gramática de Fase 32, a la entrada de la Fase 37 (pre-mitigación):

# Amenaza \(P\) \(S\) \(D\) \(R = P \cdot S \cdot (1 - D)\)
T1 Prompt injection directa ("responde como pirata") 0.8 2 0.4 0.96
T2 Injection indirecta vía chunk de RAG envenenado 0.3 3 0.1 0.81
T3 Jailbreak (estilo DAN, trucos de codificación) 0.4 2 0.3 0.56
T4 Abuso de tools — path traversal 0.5 4 0.7 0.60
T5 Abuso de tools — command injection 0.4 5 0.7 0.60
T6 Cadena de suministro — pickle en carga de pesos 0.1 5 0.0 0.50
T7 Cadena de suministro — manipulación de chunk de KB 0.2 3 0.3 0.42
T8 Almacenamiento de trazas — payload de injection registrado 0.6 2 0.8 0.24
T9 Envenenamiento de memoria (sin memoria a largo plazo) 0.0 3 1.0 0.00

Justificaciones para las filas destacadas:

  • T1, \(P = 0.8\): cualquiera que oiga hablar del tutor probará el prompt pirata al menos una vez. Es lo primero que la gente prueba con cualquier LLM.
  • T1, \(S = 2\): el peor caso es que el tutor hable en pirata. No hay canal de contenido dañino; la severidad es "violación de integridad", no "daño al usuario".
  • T2, \(P = 0.3\): requiere acceso de escritura a la KB. Menor que T1, pero no despreciable — cualquiera con acceso al repo puede editar chunks.jsonl.
  • T2, \(D = 0.1\): ninguna defensa actual detecta chunks envenenados. Esta es la entrada de mayor residual que aún no está mitigada.
  • T6, \(P = 0.1\): solo ocurre si Borja descarga un checkpoint hostil. Entrenado a mano, así que bajo.
  • T6, \(D = 0.0\): nada comprueba actualmente los pesos — hasta que el Lab 04 entregue verify_artifacts.sh.
  • T9: el tutor de gramática no tiene memoria a largo plazo (la Fase 32 eligió explícitamente agentes sin estado para el alcance microscópico de §A13), así que esta fila existe solo para documentar la ausencia de la amenaza.

Ordenando la matriz

Ordenado por \(R\) (descendente), pre-mitigación:

  1. T1 (0.96) — prompt injection directa
  2. T2 (0.81) — indirecta vía RAG
  3. T4 (0.60) — path traversal
  4. T5 (0.60) — command injection
  5. T3 (0.56) — jailbreaks
  6. T6 (0.50) — deserialización de pickle
  7. T7 (0.42) — manipulación de KB
  8. T8 (0.24) — almacenamiento de trazas
  9. T9 (0.00) — envenenamiento de memoria (n/a)

Este orden dicta el orden de los labs:

  • Lab 00 aborda T1 (mayor-\(R\) sin mitigar).
  • Lab 01 aborda T2 (segundo-mayor).
  • Lab 02 aborda T3 (menor-\(R\) pero transferencia de técnica).
  • Lab 03 aborda T4, T5 (relacionados con tools; agrupados).
  • Lab 04 aborda T6, T7 (cadena de suministro agrupada).

Re-puntuar tras la mitigación

La misma matriz, post-mitigaciones de la Fase 37 (output schema aplicado, sandbox testeado, manifiesto comprobado):

# Amenaza \(P\) \(S\) \(D\) (post) \(R\) (post) Δ
T1 Prompt injection directa 0.8 2 0.9 0.16 −0.80
T2 Injection indirecta vía RAG 0.3 3 0.5 0.45 −0.36
T3 Jailbreak 0.4 2 0.6 0.32 −0.24
T4 Path traversal 0.5 4 0.95 0.10 −0.50
T5 Command injection 0.4 5 0.95 0.10 −0.50
T6 Deserialización de pickle 0.1 5 0.99 0.005 −0.495
T7 Manipulación de chunk de KB 0.2 3 0.9 0.06 −0.36

T2 (injection indirecta) es el mayor residual. El output schema y la higiene de KB ayudan pero no cierran la brecha — el atacante aún controla el contenido recuperado. Esto se convierte en el hallazgo destacado de experiments/37-redteam-report/findings.md.

Lo que los números no te dicen

  • Fallos correlacionados. Dos amenazas independientes cada una a \(R = 0.1\) pueden componer una cadena a \(R \gg 0.2\). La matriz es por amenaza; el riesgo de exploit encadenado es un ejercicio aparte (fuera del alcance de la Fase 37).
  • Capacidad del adversario asumida constante. La matriz asume un atacante genérico motivado. Un atacante nation-state colapsa cada \(D\) a casi cero.
  • La severidad es unidimensional. Una escala de severidad real separa confidencialidad / integridad / disponibilidad. El alcance microscópico del tutor de gramática hace que eso sea excesivo; el escalar 1–5 está bien.
  • Sin dinámicas temporales. El riesgo cambia mientras la base de código evoluciona. La matriz es una instantánea; vuelve a puntuar en refactorizaciones mayores.

Cómo usar la matriz

La matriz vive en experiments/37-redteam-report/findings.md y es el entregable primario de la Fase 37, junto con los tests de regresión. Su trabajo es:

  1. Comunicar prioridades. Cualquiera que lea el informe puede ver "T2 es el mayor residual" sin tener que inferirlo de la prosa.
  2. Justificar la asignación de tiempo. El Lab 00 toma un día; mitigación de T1 cierra 0.80 de riesgo residual. El Lab 04 toma unas horas; mitigación de T6 cierra 0.495. El Lab 02 (jailbreaks) toma más tiempo del que justifica su reducción \(R = 0.24\) — marcado en la sección "lecciones aprendidas" del informe.
  3. Llevar hacia adelante. La Fase 40 (endurecimiento / postmortem) revisita la matriz; los números cambian a medida que el sistema evoluciona.

Recapitulación en un párrafo

El threat modeling necesita números, no sensaciones. Tres estimaciones por amenaza (\(P\), \(S\), \(D\)) se multiplican para dar una puntuación de riesgo residual; ordenar por \(R\) dicta el orden de mitigación. El objetivo es el ranking comparativo, no la medición absoluta. Para el tutor de gramática, los tres primeros pre-mitigación son injection directa, injection indirecta vía RAG y caminos de abuso de tools; post-mitigación, la injection indirecta vía RAG se vuelve el mayor residual y el hallazgo destacado del informe.

Siguiente: theory/04-fuzzing-and-sandbox.md — fuzzing de argumentos de tools con Hypothesis y revisión del sandbox de Fase 32.