Recuerdo un proyecto en el que, al cabo de un año, reapareció una vulnerabilidad que, sin embargo, habíamos identificado claramente en nuestro taller inicial. ¿Por qué? Porque nuestro modelo de amenazas se había quedado en una instantánea, sin seguimiento.
Fue entonces cuando comprendí la importancia de un modelo de amenazas continuo. No solo un taller al principio, sino un proceso dinámico, integrado en el ciclo de desarrollo, que evoluciona con el proyecto.
Incorporar el modelado de amenazas a la rutina diaria
15 minutos para validar una historia de usuario
La integración de CI/CD es fundamental para detectar regresiones, pero la mejor defensa sigue siendo evitar introducir el fallo desde el principio.
Antes de empezar a programar una nueva funcionalidad (por ejemplo, una exportación de datos de usuario), dedica 15 minutos a reunirte con el Product Owner y un desarrollador para hacer una «mini-TM». No hace falta ninguna herramienta compleja ni diagramas UML: basta con una pizarra blanca o una hoja de papel.
Trazá rápidamente el flujo de datos y planteate tres preguntas sencillas, inspiradas en STRIDE:
- Suplantación de identidad (spoofing): ¿Quién puede iniciar esta exportación? ¿Se comprueba esto en el back-end?
- Manipulación (Tampering): ¿Se pueden manipular los parámetros de la exportación a través de la URL o del cuerpo de la solicitud?
- Divulgación de información (Information Disclosure): ¿Qué datos se exportan, adónde se envían y quién puede verlos?
Este ritual permite identificar desde el principio requisitos de seguridad concretos, como:
- El ID del usuario debe proceder de su token de sesión, no de un parámetro del cliente.
- La exportación debe registrarse y validarse en el servidor.
- Si se trata de datos confidenciales, es necesario aplicar un filtro a las columnas o ocultarlas.
Este enfoque evita depender exclusivamente de las pruebas realizadas al final del proceso. Y, sobre todo, hace que el equipo de producto se responsabilice de la identificación temprana de los riesgos.
El modelo de amenazas no sirve de nada si no da lugar a requisitos verificables, y esto también permite integrarlo en el día a día de los desarrolladores, en las revisiones de código y en los procesos de CI/CD. Por ejemplo, utilizando herramientas como Semgrep o Checkov para detectar automáticamente los patrones de código de riesgo identificados durante el taller inicial.
Tomemos como ejemplo un contexto normativo exigente: **una aplicación web/API en un entorno PCI-DSS**, con pagos en línea, gestión de tarjetas y una interfaz Angular accesible al público.
A continuación se enumeran algunos requisitos derivados del modelo de amenazas que se pueden verificar automáticamente:
| Amenaza identificada | Requisito | Implementación técnica |
| Fuga del PAN (número de cuenta principal) en los registros de la aplicación | Ocultación sistemática de los datos confidenciales en los registros | Regla Semgrep para logger.*(".*[0-9]{13,16}.*"), prueba de integración + registros simulados en CI |
| Escasa segregación de funciones en las API de reembolso | Control estricto de RBAC/API Gateway en operaciones críticas | Escaneo de la infraestructura con Checkov + prueba de llamada POST a /api/refund como usuario de nivel estándar |
| Falta de verificación del cumplimiento de los encabezados de seguridad HTTP (CSP, HSTS, X-Frame-Options) | Es obligatorio incluir un conjunto completo de encabezados de seguridad en todas las respuestas HTTP públicas | Prueba en el proceso de CI/CD con `curl -I` + script de validación de los encabezados críticos esperados |
| Llamadas salientes no filtradas desde contenedores de aplicaciones | Detección y restricción de las comunicaciones salientes innecesarias | Análisis del archivo manifest de K8s con OPA + prueba en tiempo de ejecución a través de un proxy de salida en modo de auditoría |
Y en cuanto al código, podría quedar así:
Comprobación de los encabezados HTTP (fragmento de .gitlab-ci.yml)
security_headers_check:
image: curlimages/curl:latest
script:
- |
curl -I https://monapp.exemple.com > headers.txt
grep -q "Strict-Transport-Security" headers.txt || (echo "Falta HSTS" && exit 1)
grep -q "Content-Security-Policy" headers.txt || (echo "Falta CSP" && exit 1)
grep -q "X-Frame-Options" headers.txt || (echo "Falta X-Frame-Options" && exit 1)
only:
- merge_requests
Prueba de Semgrep en los registros confidenciales
# .semgrep.yml
rules:
- id: log-pan-detection
patterns:
- pattern: logger.$METHOD("$MSG")
- pattern-regex: ".*[0-9]{13,16}.*"
message: "PAN potentiellement loggé"
languages: [python, java, javascript]
severity: ERROR
Y en preparación:
semgrep:
imagen: returntocorp/semgrep
script:
- semgrep --config .semgrep.yml
allow_failure: false
Es como tener un recordatorio constante: «Oye, recuerda que esta parte del código es sensible, ten cuidado». Y si se identifica una nueva amenaza, actualizamos las reglas, adaptamos las herramientas y seguimos aprendiendo y mejorando.
Gobernanza y cumplimiento normativo: una ventaja nada desdeñable
Este modelo se ajusta perfectamente al **OWASP SAMM (Diseño/Evaluación de amenazas)** y también cumple con los requisitos de las normas **ISO 27001 / PCI-DSS / RGPD**. Cada control automatizado se convierte en una prueba, un indicador y una garantía de madurez.
No hace falta defender tu modelo en la próxima revisión de seguridad. Mostrar los registros. Demostrar que está en proceso. Demostrar que funciona.
Conclusión
El modelado de amenazas no debe ser un elemento estático que se deja de lado. Es una herramienta estratégica, una guía para las decisiones de arquitectura y un puente entre el negocio, la tecnología y la seguridad.
Al volver a integrarlo en el día a día de los servicios de reparto —mediante controles automatizados, reglas dinámicas y una vigilancia constante—, le devuelves el papel que le corresponde: el de copiloto. Discreto, pero esencial.
*Referencias:*
- OWASP Threat Modeling: https://owasp.org/www-community/Threat_Modeling
- SAMM: https://owaspsamm.org/model/design/threat-assessment/
- Gitleaks: https://github.com/gitleaks/gitleaks
- Checkov: https://www.checkov.io/
- Semgrep: https://semgrep.dev/
- PCI-DSS v4.0: https://www.pcisecuritystandards.org/


