Introducción
El modelado de amenazas es una forma práctica de reflexionar sobre qué podría salir mal antes de que un sistema sea atacado. En lugar de empezar por las herramientas, primero identificas qué necesita protección, dónde cruzan los datos los límites de confianza, cómo podría moverse un atacante a través del sistema y qué controles reducen el riesgo.
En este laboratorio, inspeccionarás un pequeño servicio de inicio de sesión local y completarás un modelo de amenazas estructurado en security-model.json. El modelo no es un informe de formato libre: cada paso añade entradas JSON específicas que pueden ser verificadas por un script de validación.
Inspeccionar el servicio de inicio de sesión
En este paso, inspeccionarás el pequeño servicio que vas a modelar. Un modelo de amenazas comienza a partir del comportamiento observable del sistema: qué hace la aplicación, qué archivos utiliza y qué información podría ser relevante para un atacante.
Primero, dirígete al directorio del proyecto:
cd /home/labex/project
Lista los archivos preparados:
ls -l
Deberías ver archivos como app.py, users.json, sessions.json, security-model.json y el directorio uploads.
Ahora, solicita a la aplicación de demostración que muestre sus rutas. Una ruta es un punto de entrada de la aplicación que acepta algún tipo de solicitud:
python3 app.py routes
La salida debería mostrar cuatro rutas:
/login - acepta un nombre de usuario y contraseña, luego crea un token de sesión
/files - lista los archivos que pertenecen al usuario que ha iniciado sesión
/download - lee un nombre de archivo solicitado desde el directorio uploads
/admin - muestra registros de cuentas solo a los administradores
Finalmente, ejecuta el verificador de modelos actual. Informará que faltan secciones porque el modelo está vacío intencionalmente:
python3 model-check.py all
Deberías ver mensajes indicando que a cada sección le faltan entradas requeridas. Este es el punto de partida para el resto del laboratorio.
Identificar los activos
En este paso, añadirás activos al modelo. En el modelado de amenazas, un activo es cualquier cosa que el sistema deba proteger. Para este servicio de inicio de sesión, los activos importantes no son solo archivos; también incluyen datos de autenticación y el estado de la sesión.
Usa cat para inspeccionar la base de datos de usuarios:
cat users.json
El archivo contiene nombres de usuario, contraseñas y roles. Eso convierte a user_credentials y admin_records en activos importantes.
Inspecciona el archivo de sesiones y el directorio de subidas:
cat sessions.json
ls -l uploads
El archivo de sesión puede contener tokens de inicio de sesión, y el directorio uploads contiene contenido privado del usuario. Estos se mapean a session_tokens y private_uploads.
Ahora actualiza el array assets en security-model.json. El siguiente comando utiliza un "here-document" de Python. Un "here-document" envía las líneas entre los marcadores PY a python3 como un script corto:
python3 - <<'PY'
import json
from pathlib import Path
path = Path("security-model.json")
model = json.loads(path.read_text())
model["assets"] = [
"user_credentials",
"session_tokens",
"private_uploads",
"admin_records",
]
path.write_text(json.dumps(model, indent=2) + "\n")
PY
Verifica solo la sección de activos:
python3 model-check.py assets
El resultado esperado es:
assets: complete
Mapear los límites de confianza
En este paso, añadirás límites de confianza. Un límite de confianza es un lugar donde los datos se mueven entre áreas con diferentes niveles de control o confianza. Los límites son útiles porque muchos ataques ocurren cuando una entrada no confiable cruza hacia código, archivos o funciones privilegiadas confiables.
Observa de nuevo la lista de rutas:
python3 app.py routes
Las rutas /login, /files y /download reciben entradas desde el lado del usuario y las pasan a la lógica del servidor. Ese es el límite browser_to_server en este pequeño modelo.
La ruta /download lee nombres de la solicitud y luego accede al directorio uploads. Eso crea un límite server_to_filesystem. La ruta /admin separa a los usuarios normales de los datos exclusivos para administradores, por lo que crea un límite user_to_admin_area.
Añade estos límites al modelo:
python3 - <<'PY'
import json
from pathlib import Path
path = Path("security-model.json")
model = json.loads(path.read_text())
model["trust_boundaries"] = [
"browser_to_server",
"server_to_filesystem",
"user_to_admin_area",
]
path.write_text(json.dumps(model, indent=2) + "\n")
PY
Verifica la sección de límites de confianza:
python3 model-check.py trust_boundaries
El resultado esperado es:
trust_boundaries: complete
Añadir rutas de ataque
En este paso, añadirás rutas de ataque. Una ruta de ataque es una forma concreta en la que un atacante podría moverse desde un punto de entrada hacia un activo. Este es el núcleo del modelado de amenazas: conectar activos y límites con el comportamiento realista de un atacante.
Intenta un inicio de sesión con las credenciales de demostración:
python3 app.py login alice wonderland
La salida es un token de sesión:
session-alice-demo
Este comportamiento muestra por qué las contraseñas y los tokens de sesión son importantes. Una contraseña débil podría permitir credential_guessing (adivinación de credenciales), y un token robado podría permitir session_token_theft (robo de token de sesión).
La ruta /download acepta un nombre de archivo solicitado, por lo que una implementación descuidada podría permitir path_traversal (recorrido de rutas). La ruta /admin protege los registros de administrador, por lo que la falta de comprobaciones de roles podría permitir admin_area_abuse (abuso del área de administración).
Añade estas rutas de ataque al modelo:
python3 - <<'PY'
import json
from pathlib import Path
path = Path("security-model.json")
model = json.loads(path.read_text())
model["attack_paths"] = [
"credential_guessing",
"session_token_theft",
"path_traversal",
"admin_area_abuse",
]
path.write_text(json.dumps(model, indent=2) + "\n")
PY
Verifica la sección de rutas de ataque:
python3 model-check.py attack_paths
El resultado esperado es:
attack_paths: complete
Elegir mitigaciones
En este paso, terminarás el modelo añadiendo mitigaciones. Una mitigación es un control que reduce la probabilidad o el impacto de una ruta de ataque. Los buenos modelos de amenazas emparejan cada ruta de ataque importante con al menos un control práctico.
Utiliza estos emparejamientos para el pequeño servicio de inicio de sesión:
credential_guessingpuede reducirse medianterate_limit_login.session_token_theftpuede reducirse medianteprotect_session_tokens.path_traversalpuede reducirse mediantevalidate_download_paths.admin_area_abusepuede reducirse medianteenforce_admin_authorization.
Añade las mitigaciones al modelo:
python3 - <<'PY'
import json
from pathlib import Path
path = Path("security-model.json")
model = json.loads(path.read_text())
model["mitigations"] = [
"rate_limit_login",
"protect_session_tokens",
"validate_download_paths",
"enforce_admin_authorization",
]
path.write_text(json.dumps(model, indent=2) + "\n")
PY
Ahora ejecuta la verificación completa del modelo:
python3 model-check.py all
Cada sección debería estar completa:
assets: complete
trust_boundaries: complete
attack_paths: complete
mitigations: complete
También puedes ver el modelo estructurado final:
cat security-model.json
El resultado importante es que el modelo ahora conecta los activos protegidos, los límites de confianza, las rutas de ataque y las mitigaciones para el mismo pequeño servicio.
Resumen
Has practicado un flujo de trabajo práctico de modelado de amenazas en un pequeño servicio de inicio de sesión. Inspeccionaste el servicio, identificaste activos, mapeaste límites de confianza, añadiste rutas de ataque y emparejaste esas rutas con mitigaciones en un modelo JSON estructurado.
Este flujo de trabajo ayuda a conectar el pensamiento de seguridad con el comportamiento observable del sistema, en lugar de tratar el modelado de amenazas como un informe escrito por separado.



