OWASP: A06 2025 - Insecure Design


¿Qué es Insecure Design?

Insecure Design agrupa debilidades cuyo origen se encuentra en el diseño o arquitectura de una aplicación. El problema aparece cuando un control de seguridad necesario no existe, resulta insuficiente o el sistema se apoya en supuestos que un atacante puede romper.

Debe diferenciarse de un fallo de implementación. Una aplicación puede ejecutar exactamente aquello para lo que fue diseñada y continuar siendo insegura si el diseño nunca contempló determinados escenarios de ataque.

Desde un punto de vista de Red Team, el objetivo no es validar que todos los procesos del negocio funcionen correctamente, sino identificar decisiones de diseño que permitan ampliar la superficie de ataque, superar límites de confianza, abusar de funcionalidades sensibles o alcanzar estados que proporcionen una ventaja ofensiva.

En este artículo analizamos las siguientes áreas:

Límites de confianza
Controles de seguridad ausentes o insuficientes
Confianza en el cliente
Flujos sensibles y rutas alternativas
Segregación de entornos y tenants
Automatización y abuso de recursos
Race Conditions
Procesamiento de contenido no confiable


Límites de confianza

Una parte importante del análisis consiste en identificar dónde el sistema cambia de contexto de confianza.

Por ejemplo:

Internet -> Aplicación
Frontend -> Backend
Aplicación -> Servicio interno
Aplicación -> Worker
Usuario -> Función administrativa
Tenant A -> Infraestructura compartida
Sistema externo -> Backend

Un diseño inseguro puede asumir que determinados datos o peticiones son confiables únicamente porque proceden de otro componente interno.

Durante el reconocimiento presta atención a:

  • APIs internas accesibles indirectamente desde funcionalidades públicas.
  • Servicios que confían en cabeceras añadidas por proxies.
  • Workers que procesan datos introducidos por usuarios.
  • Sistemas administrativos que confían en la red de origen.
  • Integraciones que aceptan eventos o callbacks sin verificar suficientemente su procedencia.
  • Componentes internos que no aplican controles porque esperan ser inaccesibles desde Internet.

La pregunta relevante es:

¿Puede un atacante controlar información que atraviesa un límite de confianza y conseguir que el siguiente componente la trate como confiable?

Validación

Si una aplicación utiliza una cabecera para identificar que una petición procede de infraestructura interna:

X-Internal-Request: true

comprueba si el cliente puede proporcionarla directamente y si modifica el comportamiento del backend.

El hallazgo se confirma cuando una decisión de seguridad depende de información que puede ser controlada desde un contexto menos confiable.

Controles de seguridad ausentes o insuficientes

Insecure Design incluye situaciones donde una funcionalidad sensible carece de un control que debería formar parte del propio diseño.

Por ejemplo:

  • Una operación crítica no requiere reautenticación.
  • No existe separación entre una acción ordinaria y una acción especialmente sensible.
  • Una funcionalidad peligrosa puede utilizarse sin límites razonables.
  • No existe un mecanismo para evitar automatización cuando esta genera un impacto relevante.
  • El sistema permite alcanzar directamente un estado que debería depender de una comprobación previa.

Durante un pentest no es necesario revisar todas las reglas del negocio.

Concéntrate en controles cuya ausencia permita:

  • Obtener acceso.
  • Mantener persistencia.
  • Escalar privilegios.
  • Acceder a otros sistemas.
  • Aumentar el impacto de otra vulnerabilidad.
  • Evadir una medida defensiva.
  • Consumir recursos hasta afectar al servicio.
  • Abusar de una operación sensible.

Ejemplo

Supón que una aplicación permite cambiar el correo asociado a una cuenta:

POST /api/account/change-email HTTP/1.1
Cookie: session=...

{
  "email": "new@example.com"
}

Si una operación de este tipo no requiere ninguna verificación adicional, analiza si una sesión comprometida sería suficiente para cambiar permanentemente el mecanismo de recuperación de la cuenta.

El problema no está necesariamente en el endpoint, sino en que el diseño puede no haber considerado una barrera adicional para una modificación especialmente sensible.

Confianza en el cliente

Un patrón frecuente consiste en permitir que el cliente proporcione información que posteriormente se utiliza para tomar decisiones que deberían depender del servidor.

Por ejemplo:

{
  "user": "sam",
  "role": "user",
  "verified": true
}

o:

{
  "step": "mfa_completed"
}

Durante las pruebas identifica campos relacionados con:

  • Roles.
  • Permisos.
  • Estado de autenticación.
  • Estado de verificaciones.
  • Tenant u organización.
  • Límites de uso.
  • Estado del flujo.
  • Tipo de cuenta.
  • Flags internos.
  • Resultado de comprobaciones previas.

Modifica un único valor y observa si el backend lo recalcula o simplemente confía en él.

La vulnerabilidad se confirma cuando información controlada por el cliente permite influir en una decisión de seguridad que debería proceder de una fuente confiable.

Estado almacenado en el cliente

Presta atención a:

  • Cookies.
  • Campos ocultos.
  • Parámetros.
  • JSON.
  • Local storage.
  • Tokens únicamente codificados.
  • Valores enviados entre distintas etapas de un flujo.

Por ejemplo:

mfa=false

que pueda modificarse a:

mfa=true

Si el servidor utiliza ese valor para considerar completada una comprobación, existe un fallo grave de diseño o implementación.

Flujos sensibles y rutas alternativas

Los procesos de autenticación, recuperación y administración suelen disponer de varias rutas para alcanzar el mismo resultado.

Un control puede ser robusto en el flujo principal y mucho más débil en una ruta alternativa.

Compara especialmente:

Login normal
Recuperación de contraseña
Cambio de contraseña
Cambio de correo
Desactivación de MFA
Códigos de recuperación
Soporte técnico
Invitaciones
Registro
Aplicación móvil
API
Flujos legacy

El objetivo es identificar si existe un camino con requisitos de seguridad inferiores.

Ejemplo

Cambio de contraseña:
password actual + MFA

Recuperación:
pregunta de seguridad

Aunque el flujo principal sea robusto, el mecanismo de recuperación puede reducir todo el modelo de seguridad a una comprobación considerablemente más débil.

OWASP utiliza precisamente los mecanismos de recuperación basados en preguntas de seguridad como ejemplo de un diseño que puede resultar insuficiente.

Validación

No es necesario tomar control de una cuenta real.

En una cuenta controlada, determina si el flujo alternativo permite alcanzar la misma operación sensible utilizando factores o evidencias más débiles.

Red Team OPSEC

Realiza estas comprobaciones únicamente sobre cuentas controladas y evita modificar los mecanismos de recuperación o MFA de usuarios reales.

Segregación de entornos y tenants

Los límites entre organizaciones, entornos y componentes son especialmente interesantes desde una perspectiva ofensiva.

Busca separaciones como:

Tenant A / Tenant B
Producción / Staging
Usuario / Administración
Internet / Red interna
Aplicación / Plataforma de gestión
Frontend / Backend

Durante el reconocimiento comprueba si el aislamiento depende únicamente de convenciones lógicas como:

tenant_id
organization_id
workspace_id
environment

o de elementos controlables como:

  • Subdominios.
  • Cabeceras.
  • Parámetros.
  • Cookies.
  • Tokens.
  • Rutas.

La separación debe mantenerse también en servicios secundarios:

  • Almacenamiento.
  • Buscadores.
  • Colas.
  • Cachés.
  • Sistemas de logs.
  • APIs internas.
  • Jobs y workers.

Validación

Si una misma petición contiene:

{
  "organization_id": "acme"
}

comprueba con organizaciones controladas si cambiar ese contexto modifica el ámbito real de la operación.

Este escenario puede terminar manifestándose como Broken Access Control, pero Insecure Design resulta especialmente relevante cuando la propia arquitectura no establece un aislamiento consistente entre los dominios de confianza.

Red Team OPSEC

Utiliza tenants o entornos proporcionados para la evaluación. No accedas deliberadamente a información real de terceros si puedes demostrar la falta de aislamiento mediante recursos controlados.

Automatización y abuso de recursos

Una funcionalidad puede ser segura durante un uso normal pero volverse peligrosa cuando puede automatizarse sin límites.

OWASP contempla escenarios donde bots pueden consumir rápidamente recursos limitados o realizar operaciones a una escala que el diseño no tuvo en cuenta.

Desde Red Team interesa especialmente cuando el abuso permite:

  • Agotar un recurso.
  • Generar un coste económico.
  • Provocar un DoS lógico.
  • Crear grandes cantidades de objetos.
  • Enviar mensajes o notificaciones.
  • Reservar recursos limitados.
  • Generar tokens o códigos.
  • Facilitar enumeración o credential attacks.
  • Aumentar el impacto de otro vector.

La ausencia de rate limiting por sí sola no es suficiente.

Debe existir una funcionalidad donde la automatización genere un efecto de seguridad relevante.

Validación

Si una operación crea un recurso costoso:

POST /api/export HTTP/1.1

realiza un número reducido de solicitudes y comprueba si:

  • Existen límites.
  • Se crean procesos simultáneos.
  • El backend impone cuotas.
  • El coste de procesamiento crece con cada solicitud.

No es necesario consumir todos los recursos disponibles.

Red Team OPSEC

No reproduzcas a escala completa escenarios de agotamiento.

Demuestra que el control puede superarse con el mínimo número de peticiones necesario y detén la prueba antes de afectar a la disponibilidad.

Race Conditions

Una Race Condition aparece cuando la seguridad de una operación depende de que varias acciones se ejecuten en un orden determinado, pero el sistema no mantiene esa propiedad ante solicitudes concurrentes.

Desde Red Team son especialmente interesantes cuando permiten:

  • Reutilizar tokens de un solo uso.
  • Ejecutar varias veces una acción limitada.
  • Saltar comprobaciones.
  • Consumir el mismo recurso varias veces.
  • Generar estados incompatibles.
  • Evitar una transición de seguridad.

Por ejemplo:

1. Comprobar que token.used == false
2. Ejecutar operación
3. Marcar token.used = true

Si dos solicitudes alcanzan el primer paso simultáneamente, ambas podrían considerar válido el token.

Validación

Utiliza un recurso controlado y envía únicamente unas pocas peticiones concurrentes.

Después comprueba el estado final.

La vulnerabilidad se confirma si una propiedad que debería mantenerse de forma atómica puede romperse mediante concurrencia.

Red Team OPSEC

Las pruebas de concurrencia pueden disparar múltiples operaciones reales en milisegundos.

Utiliza recursos de prueba y limita la concurrencia a la mínima necesaria para demostrar el fallo.

Procesamiento de contenido no confiable

También conviene analizar funcionalidades donde el sistema acepta contenido controlado por un usuario y posteriormente lo entrega a componentes con capacidades adicionales.

Algunos ejemplos:

Usuario -> Procesador de documentos
Usuario -> Conversor de imágenes
Usuario -> Motor de plantillas
Usuario -> Worker
Usuario -> Pipeline de importación
Usuario -> Servicio interno

La cuestión de diseño es qué nivel de confianza se concede al contenido y qué aislamiento existe durante su procesamiento.

Durante el reconocimiento pregunta:

  • ¿El componente necesita realmente todas las capacidades que posee?
  • ¿Puede acceder a red interna?
  • ¿Puede acceder al sistema de archivos?
  • ¿Utiliza credenciales privilegiadas?
  • ¿Comparte entorno con la aplicación principal?
  • ¿El resultado se sirve desde un origen confiable?

Un fallo en esta separación puede convertir una vulnerabilidad aparentemente limitada en un punto de entrada hacia otros componentes.

Subida de archivos

En funcionalidades de upload, determina:

  • Qué contenido acepta el sistema.
  • Dónde se almacena.
  • Qué componente lo procesa.
  • Desde qué dominio se sirve.
  • Qué permisos posee el proceso que lo analiza.
  • Si el contenido queda accesible a otros usuarios.

No es necesario subir una webshell para evaluar el diseño.

Un archivo inocuo puede ser suficiente para determinar si el contenido termina en una ubicación o contexto que proporciona capacidades no previstas.

Threat Modeling desde Red Team

OWASP recomienda threat modeling, patrones de diseño seguro y una metodología de desarrollo segura para prevenir este tipo de fallos.

Durante un Red Team normalmente no vas a realizar el threat modeling completo de la aplicación.

Sin embargo, puedes utilizar una versión simplificada durante el reconocimiento:

¿Qué componentes existen?
¿Qué componente confía en cuál?
¿Qué datos puede controlar un usuario?
¿Qué procesos tienen más privilegios?
¿Qué controles separan una zona de otra?
¿Qué ocurre si alcanzo una funcionalidad por una ruta diferente?
¿Qué asume el sistema que un atacante no puede hacer?

Estas preguntas permiten descubrir decisiones de diseño potencialmente explotables sin necesidad de validar toda la lógica funcional de la aplicación.

Diferenciar Insecure Design de otros hallazgos

Insecure Design puede terminar manifestándose mediante categorías más concretas.

Por ejemplo, una arquitectura multi-tenant que no defina correctamente el aislamiento puede terminar manifestándose como un Broken Access Control cuando un usuario accede a objetos pertenecientes a otra organización.

De forma similar, un procesador de archivos con acceso innecesario a la red interna puede aumentar considerablemente el impacto de una SSRF si algún parámetro permite controlar el destino de sus conexiones.

En una operación ofensiva suele ser más útil documentar la vulnerabilidad concreta que permite la explotación y utilizar Insecure Design para describir la causa raíz arquitectónica cuando resulte relevante.

Consideraciones generales durante las pruebas

Insecure Design es una categoría amplia y no dispone de un payload universal.

Para Red Team resulta especialmente útil durante el reconocimiento y durante el análisis de cadenas de ataque.

Busca principalmente:

Confianza implícita entre componentes.
Controles importantes que simplemente no existen.
Rutas alternativas más débiles.
Información de seguridad controlada por el cliente.
Separaciones lógicas que puedan romperse.
Procesos con privilegios excesivos.
Funcionalidades automatizables con impacto.
Estados que dependan de operaciones no atómicas.

No es necesario demostrar que el negocio completo puede utilizarse de una forma inesperada.

El objetivo es identificar si una decisión de diseño proporciona una capacidad útil al atacante y validar esa capacidad con la mínima interacción necesaria.

Red Team OPSEC

Los fallos de diseño pueden permitir abusos de gran escala aunque una única petición parezca legítima.

Demuestra la propiedad insegura con recursos controlados y evita escalar innecesariamente pruebas relacionadas con disponibilidad, costes, tenants de terceros, comunicaciones o procesos sensibles.