1Por qué importa
En f01-principios aprendiste a preguntar qué pasa el minuto después de
que se cruce una frontera. Esta lección responde a la versión más incómoda de esa
pregunta: ¿qué pasa cuando el atacante ya está dentro y su siguiente movimiento
no encuentra ninguna frontera más? Ese es el estado por defecto de casi
cualquier arquitectura que no lo haya decidido explícitamente, incluido el
laboratorio de este curso.
El modelo de perímetro fue razonable mientras el perímetro existía. Hoy el número de formas de llegar “dentro” ha crecido tanto —una credencial reutilizada, una dependencia con código añadido, un contenedor de un proveedor, un portátil personal— que asumir el interior como confiable es asumir el escenario que más veces ocurre. Zero Trust no dice que el interior sea hostil por dramatismo: lo dice porque la probabilidad de que haya alguien dentro dejó de ser despreciable.
La otra mitad de la lección es aún más vieja y se olvida más. La separación de responsabilidades es la idea de que ninguna identidad única debería poder completar sola una acción crítica. Aparece en contabilidad desde antes de que existieran los ordenadores, y en ingeniería se rompe todos los días de la misma forma: hay un pipeline con permisos para todo, y quien controle ese pipeline controla producción sin pasar por ninguna revisión. La verificación por petición y la separación de responsabilidades son la misma idea aplicada a máquinas y a personas, y por eso van juntas.
El entregable de esta lección es una frase que puedas decir en una reunión sin que suene a folleto: “aquí la ubicación de red no autoriza nada, y esta acción no la puede completar una sola identidad”. Si tu arquitectura no permite decir ninguna de las dos cosas, ya sabes qué diseñar el trimestre que viene.
2Conceptos
- Zero Trust: ninguna confianza implícita por ubicación de red. Cada petición se autentica, se autoriza y se registra con su propio contexto.
- Movimiento lateral: pasar de un recurso comprometido al siguiente sin volver a atravesar el perímetro. Es lo que Zero Trust ataca directamente.
- Microsegmentación: reducir las rutas de red al par exacto que necesita hablar. Es un paso hacia Zero Trust, no Zero Trust.
- Identidad de carga de trabajo: cada servicio tiene una identidad propia y verificable, no una contraseña compartida en un fichero.
- Mínimo conocimiento: cada parte recibe solo los datos que necesita para su función. Aplica a respuestas, a logs y a variables de entorno.
- Separación de responsabilidades: quien propone no aprueba, y quien aprueba no ejecuta. Ninguna identidad completa sola una acción crítica.
3Explicación profunda
Empecemos por lo que Zero Trust sustituye, porque la definición popular —“no confíes en nadie”— es inútil: sin confianza en algo no hay sistema posible. Lo que se retira es una credencial concreta y muy mala: la ubicación de red. Durante décadas, poder abrir una conexión desde cierto segmento equivalía a estar autorizado. Esa credencial no se puede rotar, no se puede revocar por usuario, no caduca, y se obtiene entera con el primer equipo comprometido de la oficina.
En su lugar, cada petición se evalúa con tres entradas: quién la hace —identidad verificable, no una dirección—, qué pide —recurso y verbo concretos— y en qué contexto —estado del dispositivo, hora, comportamiento reciente—. La decisión se toma cada vez, no una vez al entrar. Esa es toda la idea. Lo demás son detalles de implementación.
Conviene ser preciso con algo que se vende mal. Microsegmentar no es Zero Trust. Partir una red grande en veinte redes pequeñas reduce muchísimo el movimiento lateral, y merece la pena, pero sigue siendo confianza basada en ubicación: solo que la ubicación ahora es más pequeña. Zero Trust empieza cuando el servicio de destino no acepta una petición por venir de la red correcta, sino que exige una credencial de la carga de trabajo que llama y comprueba si esa identidad puede hacer eso concreto. Un sistema puede estar microsegmentado y seguir siendo un perímetro; y puede tener una red plana y ser Zero Trust, aunque sea una mala idea por otras razones.
Esto nos lleva al eslabón que sostiene el resto: la identidad de carga de
trabajo. Si todos los servicios comparten una contraseña —como pasa en el
lab-00-base, donde POSTGRES_PASSWORD es la misma para
quien la necesita y para quien no— entonces no hay nada que autorizar por petición,
porque no hay forma de saber quién llamó. Una credencial compartida convierte
cualquier política en teatro. Las propiedades que hacen útil una identidad de carga
de trabajo son cuatro: es por servicio, es de vida corta, tiene
alcance —sirve para hablar con un destino y no con todos— y es
verificable por el destino sin preguntarle a quien la presenta.
El principio de mínimo conocimiento es la versión de los datos del mínimo privilegio, y se rompe en sitios menos vigilados. Una respuesta de API que devuelve el objeto entero porque “el frontend ya filtra” está entregando datos que nadie necesitaba; un log que imprime el cuerpo completo de la petición está creando una segunda copia de datos sensibles en un sistema con controles más flojos; una variable de entorno con una contraseña presente en un contenedor que jamás se conecta a esa base de datos está regalando una credencial a quien comprometa ese contenedor. Ninguno de los tres es una vulnerabilidad en sentido estricto. Los tres aumentan enormemente el impacto de la primera que aparezca.
Y la separación de responsabilidades, que es donde este modelo toca a las personas. La regla es que ninguna identidad complete sola una acción crítica: quien escribe el cambio no lo aprueba, quien lo aprueba no lo despliega a mano, quien administra el sistema de registro no puede borrar sus propias huellas. En ingeniería moderna esto se rompe casi siempre por el mismo sitio: el pipeline. Se construye una automatización con permisos para desplegar en producción, y a partir de ese momento cualquiera que pueda modificar la definición del pipeline —normalmente cualquiera que pueda enviar código— tiene esos permisos. La separación que existía en la revisión de código desaparece por debajo, y el organigrama sigue diciendo que está todo bien.
Una opinión de diseño, marcada como tal: Zero Trust es caro y no siempre merece la pena entero. Implementar verificación por petición con identidades de vida corta en toda una organización cuesta años y consume el presupuesto que quizá hacía más falta en gestión de parches. El orden que yo defiendo es: primero cortar las rutas que nadie usa, que es barato y da la mayor parte de la reducción del movimiento lateral; después dar identidad propia a los servicios que tocan datos valiosos; y solo entonces, si el modelo de amenaza lo justifica, verificación por petición en todas partes. El contraejemplo honesto: en una organización donde el acceso inicial se da por descontado —muchos proveedores, muchos dispositivos ajenos— ese orden se invierte, porque el perímetro ya no existe ni siquiera como ficción útil.
4Ejemplo sencillo
# Dos edificios. La misma persona intentando entrar en el archivo. CASTILLO Y FOSO recepcion identificas al entrar, te dan una tarjeta pasillos nadie vuelve a preguntarte nada archivo la puerta esta abierta: estas dentro, luego puedes resultado quien entre UNA vez, entra a todo ZERO TRUST recepcion no existe como frontera; no hay "dentro" pasillos cada puerta lee tu tarjeta y consulta tu permiso archivo comprueba quien eres, que pides y desde donde, cada vez resultado quien entre una vez, ha entrado a UNA cosa # Y la separacion de responsabilidades, en el mismo archivo quien pide un expediente no es quien autoriza sacarlo quien autoriza no es quien lo saca del estante quien lleva el registro no puede borrar su propia linea
El detalle que más se olvida está en la última línea. La separación de responsabilidades incluye al registro: si el administrador de los logs puede editar los logs, la evidencia solo sirve mientras el incidente no le implique a él. Es la razón de que los registros de auditoría se escriban en un sistema con distinto dueño y sin permiso de borrado.
5Ejemplo técnico
El lab-00-base es un castillo con foso de libro de texto. El foso es
internal: true y está muy bien hecho: nada sale a internet. Dentro, sin
embargo, no hay ni una sola puerta. Cuatro contenedores comparten una red plana, y
la única credencial de la base de datos está escrita en el mismo fichero que
describe todo lo demás.
| Pregunta de Zero Trust | Respuesta del laboratorio hoy | Qué haría falta |
|---|---|---|
| ¿Quién hace esta petición? | Nadie lo sabe: no hay identidad de servicio | Credencial por servicio, no compartida |
| ¿Está autorizado a este recurso? | Sí, por estar en lab_interna | Autorización por par origen-destino |
| ¿Se verifica cada vez? | Solo la contraseña, una vez por conexión | Credencial de vida corta y con alcance |
| ¿Queda registrado quién fue? | No: postgres registra el usuario lab, que son todos | Un rol distinto por servicio y registro de conexiones |
| ¿Quién necesita esa contraseña? | Solo app; la tienen todos los que miren el compose | Mínimo conocimiento: el secreto solo donde se usa |
La consecuencia es fácil de demostrar y por eso es un buen ejercicio: desde el
contenedor atacante, que existe para simular un puesto ya comprometido,
la base de datos está a un comando de distancia. No hace falta ningún
exploit: hace falta leer un fichero y abrir una conexión.
Fíjate en el segundo comando: falla porque no hay nada escuchando, no porque algo lo impida. Esa distinción es la lección entera. En un modelo de perímetro, la superficie alcanzable la decide qué servicios se han levantado; en Zero Trust la decide una política que alguien escribió a propósito.
6Diagrama
Ver el mismo diagrama como código Mermaid (editable)
flowchart LR
subgraph PERIMETRO[perimetro]
A1[app] --- D1[db]
A1 --- M1[monitor]
X1[atacante] --- D1
X1 --- A1
M1 --- D1
end
subgraph ZEROTRUST[zero trust]
A2[app] -->|identidad| D2[db]
A2 -->|identidad| M2[monitor]
X2[atacante]
end
7Código
El primer paso, el barato, es cortar las rutas que nadie usa. En un compose eso se escribe declarando una red por par de servicios que necesita hablar, en vez de una red común para todos:
# docker-compose.yml — de una red plana a rutas declaradas networks: lab_borde: driver: bridge red_proxy_app: # el proxy habla con la app driver: bridge internal: true red_app_db: # la app habla con la base driver: bridge internal: true red_puesto: # el puesto de pruebas solo ve el proxy driver: bridge internal: true services: proxy: networks: [lab_borde, red_proxy_app, red_puesto] app: networks: [red_proxy_app, red_app_db] db: networks: [red_app_db] # ya no la alcanza nadie mas monitor: networks: [red_puesto] atacante: networks: [red_puesto] # solo llega al proxy
Eso reduce las rutas de seis a dos y se nota inmediatamente en el ejercicio de
movimiento lateral. Pero es microsegmentación, no Zero Trust: la base de datos sigue
aceptando a cualquiera que llegue por red_app_db con la contraseña
correcta. El segundo paso es darle identidad a cada servicio, y aquí lo importante
es el contrato, no el producto que lo implemente:
# contrato minimo de una identidad de carga de trabajo identidad: servicio/app emitida_por: autoridad interna, tras verificar la carga de trabajo vida: 15m # si se filtra, caduca sola audiencia: servicio/db # solo vale para hablar con la base alcance: [facturas.leer] # y solo para eso verificable: si # el destino la valida sin preguntar al emisor # Compara con lo que hay hoy en el laboratorio: # POSTGRES_PASSWORD: laboratorio_local # vida: infinita · audiencia: cualquiera · alcance: todo · quien la uso: nadie sabe
Los cuatro campos que faltan en la contraseña compartida son exactamente los cuatro
que hacen útil una identidad. vida convierte un robo en una ventana;
audiencia impide reutilizar la credencial contra otro servicio;
alcance limita el daño de un uso legítimo mal intencionado; y
verificable es lo que permite registrar quién hizo qué, que es
la carencia que arrastras desde la primera lección de esta fase.
8Qué puede salir mal
Comprar Zero Trust. Es una propiedad de la arquitectura, no un producto. Un túnel nuevo que sigue concediendo acceso a un rango de red completo tras autenticar una vez es exactamente el modelo anterior con otro nombre y otra factura.
Microsegmentar y declarar victoria. Reduce el movimiento lateral y merece la pena, pero mientras el destino autorice por origen de red sigues confiando en la ubicación. La pregunta de control es: si alguien consigue estar en la red correcta, ¿le basta con eso?
El secreto que viaja a donde no hace falta. Una variable de entorno con la contraseña de la base de datos definida a nivel global llega a contenedores que jamás la usan. Cada uno de ellos es ahora un sitio desde el que se filtra. Mínimo conocimiento se rompe casi siempre por comodidad de configuración.
El pipeline con permisos de dios. Se implanta revisión de dos personas para el código y a la vez existe una automatización que despliega a producción y cuya definición vive en el mismo repositorio. Quien pueda modificar esa definición ha saltado la revisión sin tocarla. La separación de responsabilidades se mide por el camino más corto, no por el previsto.
9Cómo lo abusaría un atacante
El primer acceso casi nunca cae donde está el valor. Cae en un servicio secundario, un contenedor auxiliar, el portátil de alguien de soporte. Todo el trabajo real está en el segundo movimiento, y en un modelo de perímetro ese movimiento es gratis: la credencial que hace falta —estar dentro— ya la tiene por haber entrado. Por eso los informes de intrusión miden el tiempo entre el acceso inicial y el primer salto, y por eso ese número es tan corto.
La segunda cosa que busca es una credencial reutilizable. Una contraseña compartida sin caducidad ni destino es el objeto más valioso de cualquier sistema, porque funciona desde cualquier sitio, sirve contra todos los destinos y no deja constancia de quién la usó. Que esté en un fichero de configuración del repositorio, en una variable de entorno o en la memoria de un proceso solo cambia cuánto tarda en encontrarla.
Y el tercer objetivo, cuando el atacante es paciente, es el camino que salta la separación de responsabilidades. No hace falta convencer a nadie de aprobar un cambio malicioso: basta con modificar la parte del proceso que se ejecuta sin revisión —un script de compilación, una dependencia de desarrollo, una acción del pipeline referenciada por una etiqueta móvil— y esperar a que la organización despliegue el cambio por ti, con sus propias credenciales y con todos los formularios firmados.
10Cómo defenderlo
- Empieza por cortar rutas: enumera qué par de servicios necesita hablar y borra todo lo demás. Es lo más barato y lo que más movimiento lateral elimina.
- Sustituye las credenciales compartidas por una identidad por servicio, aunque al principio sea solo un usuario distinto por cada uno en la base de datos.
- Exige a cada credencial vida corta, audiencia y alcance. Sin los tres campos, una política de autorización no puede ser algo más que un adorno.
- Aplica mínimo conocimiento a tres sitios concretos: la respuesta de la API, lo que se escribe en los logs y las variables de entorno de cada contenedor.
- Comprueba la separación de responsabilidades por el camino más corto: pregunta qué identidad podría llevar un cambio a producción sin que otra persona lo mire.
- Registra la identidad de quien llama en cada salto. Sin eso no hay detección posible de movimiento lateral, solo una lista de conexiones anónimas.
11Laboratorio
Última vuelta al mismo laboratorio. Aquí lo vas a usar en dos tiempos: primero medir cuánto vale estar dentro, y después quitarle ese valor.
cd cursos/seguridad/labs/lab-00-base
docker compose up -d
docker compose exec atacante sh -c "nmap -sT -p 80,5432 app db proxy monitor"
Ese barrido es el mapa de rutas del modelo de perímetro. Ahora usa la credencial que está escrita en el compose, desde el puesto que no debería tenerla:
Segundo tiempo. Aplica el bloque de redes de la sección de código al compose, recrea el laboratorio y vuelve a medir. La misma orden que antes devolvía “ruta abierta” debe fallar ahora, y la aplicación debe seguir funcionando:
docker compose up -d --force-recreate
docker compose exec atacante sh -c "nc -z -w 3 db 5432 || echo sin ruta, correcto"
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/
Si lo segundo imprime el mensaje y lo tercero devuelve 200, has
eliminado cuatro rutas de movimiento lateral sin coste funcional. Revierte el
compose y destruye el laboratorio:
docker compose down -v
12Ejercicios
Perímetro o Zero Trust
Clasifica cada afirmación y justifica en una línea: (1) “La base de datos solo acepta conexiones desde la red de aplicaciones”; (2) “Cada servicio presenta un certificado propio y el destino comprueba a qué puede llamar”; (3) “Una vez que entras por el túnel corporativo, alcanzas todos los sistemas internos”; (4) “Cada petición al panel de administración revalida la sesión y el estado del dispositivo”; (5) “Partimos la red en veinte segmentos”; (6) “Los tokens de servicio caducan a los quince minutos y sirven para un solo destino”.
Perímetro: (1), porque la autorización es la red de origen; (3), que es el caso puro; y (5), que es microsegmentación —mejor que una red plana, pero sigue autorizando por ubicación—. Zero Trust: (2), porque hay identidad verificable y política por destino; (4), porque revalida por petición e incorpora contexto; y (6), porque la credencial tiene vida y audiencia.
Clave: 3 y 3. La frase que separa a la gente que ha entendido la lección de la que no es la (5): es una mejora real y no es Zero Trust, y las dos cosas son ciertas a la vez.
Corta las rutas y mide la diferencia
Aplica al lab-00-base el esquema de redes por par de la sección de
código. Antes y después, ejecuta el mismo barrido desde atacante y
guarda las dos salidas. Escribe la tabla de rutas antes y después, di cuántas
eliminaste, y responde a la pregunta importante: ¿qué sigue pudiendo hacer el
puesto comprometido y por qué eso todavía no es Zero Trust? Revierte al terminar.
Antes hay seis rutas entre los cuatro servicios internos; después quedan dos
declaradas más la del puesto al proxy. El nombre db deja de
resolverse desde atacante, así que ni siquiera hay que llegar al
intento de conexión. La aplicación sigue funcionando porque su ruta a la base
está declarada.
Lo que sigue pudiendo hacer el puesto es hablar con el proxy, y el proxy le atiende sin preguntarle nada: no hay identidad, no hay política, solo hay ruta. Por eso esto es microsegmentación. Sería Zero Trust cuando el proxy exigiera una credencial verificable de quien llama y comprobara si esa identidad puede pedir ese recurso concreto.
Clave: el entregable son las dos salidas del barrido y la frase que explica el hueco restante. Si tu conclusión fue “ya está segmentado, ya es Zero Trust”, vuelve a la sección de explicación.
Qué ata una identidad de carga de trabajo
Investiga fuera de esta lección un mecanismo real de identidad de carga de trabajo: cómo se le entrega la primera credencial a un proceso que aún no tiene ninguna, y qué impide que otro proceso de la misma máquina pida la suya haciéndose pasar por él. Explica después qué campos de la credencial hacen que robarla sirva de poco, y cuál es el problema que ese diseño no resuelve.
La primera credencial no se le da al proceso: se le da a algo que la plataforma puede verificar por su cuenta —qué imagen corre, en qué nodo, bajo qué cuenta de servicio— y a partir de esa atestación se emite una credencial de vida corta. Lo que impide la suplantación no es un secreto compartido, sino que el emisor comprueba propiedades que el solicitante no controla. Los campos que hacen que robarla sirva de poco son la caducidad corta, la audiencia —solo vale contra el destino declarado— y el alcance.
Lo que ese diseño no resuelve: si el proceso legítimo está comprometido, la credencial legítima se usa de forma ilegítima y ninguna cantidad de criptografía lo distingue. La identidad de carga de trabajo reduce el radio y la duración del daño; no impide el abuso desde dentro del propio servicio. Ahí es donde vuelven a hacer falta el alcance y la detección.
Clave: la respuesta tiene que nombrar el problema del primer secreto y terminar con la limitación. Una descripción que solo diga “cada servicio tiene su certificado” se ha saltado la pregunta.
Red Team · muévete lateralmente hasta los datos
Dentro del lab-00-base, y solo dentro de él: partiendo del
contenedor atacante como único punto de control, llega hasta el
contenido de la base de datos. Documenta cada salto y, para cada uno, escribe qué
te lo permitió: una ruta, una credencial o la ausencia de una comprobación.
Después mide cuántos de esos saltos sobreviven al esquema de redes por par.
nc -z, después consigue un cliente, y usa las credenciales tal cual están en el compose.
Salto 1: atacante resuelve el nombre db y alcanza su
puerto. Lo permite una ruta que existe por omisión. Salto 2:
autenticarse con el usuario y la contraseña del compose. Lo permite una
credencial compartida, sin audiencia ni caducidad. Salto 3: leer y
escribir sin restricción una vez dentro. Lo permite la ausencia de
comprobación: un único rol con todos los permisos sobre todo.
Con el esquema de redes por par, el salto 1 desaparece y con él los otros
dos, sin haber tocado la contraseña. Ese es el argumento a favor de empezar
por cortar rutas: es el cambio más barato y el que invalida la cadena entera.
Pero fíjate en que la credencial sigue siendo igual de mala, y que
app —que sí conserva la ruta— la sigue usando: si el
comprometido hubiera sido app, la segmentación no habría
cambiado nada.
Clave: el entregable es la tabla salto → qué lo permitió. Y la conclusión honesta: segmentar salva del puesto lateral, no del servicio legítimo comprometido.
Blue Team · ¿quién se conectó a la base de datos?
Reproduce el movimiento lateral del ejercicio anterior y después intenta responder, únicamente con los logs del laboratorio, a tres preguntas: qué sesiones hubo, cuáles eran de la aplicación y cuál era del puesto comprometido. Enumera qué falta para poder distinguirlas y propón el cambio mínimo —sin añadir ninguna herramienta nueva— que lo haría posible.
docker compose logs db. Compara con lo que necesitarías saber.Por defecto no hay forma de responder: las conexiones ni siquiera se registran, y aunque se registraran, todas llegarían como el mismo usuario desde direcciones que cambian en cada recreación del laboratorio. Falta lo de siempre: identidad. Es exactamente la misma carencia que anotaste en la primera lección de esta fase, ahora en otra capa.
Cambio mínimo, en dos mitades. Primera: un rol distinto por servicio, con los permisos que cada uno necesita y ninguno más —la aplicación no necesita crear tablas—. Segunda: activar el registro de conexiones y desconexiones e incluir usuario y origen en el formato de línea. Con las dos, una sesión del puesto comprometido aparece como un rol que no debería estar conectándose, y eso sí es una regla de detección escribible.
Clave: el entregable es la lista de lo que falta más las dos mitades del cambio. Si tu propuesta solo toca el formato del log, no has resuelto el problema: has mejorado la descripción de algo que sigue siendo anónimo.
Architecture Challenge · un despliegue que nadie pueda completar solo
Diseña la separación de responsabilidades de un pipeline que despliega a producción. Define quién puede proponer, quién aprueba, qué identidad ejecuta el despliegue y de dónde saca sus credenciales. Enumera después los caminos que saltarían tu diseño —modificar la definición del pipeline, una dependencia de compilación, un acceso administrativo directo al proveedor— y di cómo los cierras. Termina diseñando el camino de emergencia: cómo se despliega a las tres de la madrugada con una sola persona disponible.
Una propuesta razonable: la definición del pipeline vive en un lugar que la rama propuesta no puede modificar, o al menos el trabajo con permisos de producción solo se ejecuta desde la rama principal ya fusionada. Las credenciales de despliegue no las tiene ninguna persona: las obtiene la automatización mediante una identidad de vida corta, ligada al repositorio y al entorno concreto. La aprobación es de una persona distinta de quien propone, y el despliegue lo ejecuta la automatización, no un humano con acceso directo.
Caminos que lo saltan y sus cierres: dependencias de compilación, fijadas por huella y no por etiqueta móvil; acceso administrativo directo al proveedor, retirado por completo y sustituido por el camino de emergencia; y el propio registro, escrito en un sistema donde ni quien despliega ni quien administra pueden borrar. El camino de emergencia: una identidad de un solo uso que se activa dejando constancia, caduca en horas, notifica en el momento a un canal que no controla quien la usa, y obliga a una revisión posterior con nombre y fecha.
Clave: no hay una única respuesta. Se evalúa que el camino de emergencia exista y sea ruidoso, que las credenciales de producción no estén en manos de personas, y que hayas nombrado al menos un camino que salta tu propio diseño.
13Preguntas de comprensión
Dentro de lab_interna, cualquier contenedor alcanza a db y le basta la contraseña del compose. ¿Qué modelo describe eso?
Una contraseña compartida por todos no identifica a nadie. El único requisito real para llegar a la base es estar en la red correcta.
¿Qué sustituye Zero Trust por verificación en cada petición?
La ubicación es una credencial que no caduca, no se revoca por usuario y se obtiene entera con el primer equipo comprometido.
Todos los servicios comparten la misma contraseña de la base de datos. ¿Qué se rompe antes que ninguna otra cosa?
Sin identidad no hay autorización por petición ni detección posible: solo una lista de conexiones anónimas indistinguibles.
¿Qué garantiza la separación de responsabilidades en un pipeline de despliegue?
Y se mide por el camino más corto: si modificar la definición del pipeline salta la revisión, la separación no existe aunque esté en el organigrama.
14Reto adicional
Aplica mínimo conocimiento a tres sitios a la vez
Toma un endpoint que devuelve el perfil de un usuario con todos sus campos —incluidos correo, teléfono, dirección, identificador interno y marca de administrador— y que además registra el cuerpo completo de cada petición. Rediseña las tres capas: qué devuelve la respuesta, qué se escribe en el log y qué variables de entorno tiene el contenedor que lo sirve. Para cada decisión, escribe qué ataque concreto encarece.
Respuesta: solo los campos que consume quien llama, y por vista, no un objeto único reutilizado en todas partes. Fuera el identificador interno secuencial, que permite enumerar usuarios, y fuera la marca de administrador, que le ahorra al atacante elegir a quién atacar primero. Eso encarece la enumeración y la selección de objetivo, que son los dos pasos previos a casi cualquier ataque dirigido.
Log: identificador de correlación, identidad de quien llama, recurso y resultado de la autorización; nunca el cuerpo. Un log con cuerpos completos es una segunda base de datos de datos personales, guardada en un sistema con menos controles y más lectores. Entorno: solo los secretos que ese contenedor usa de verdad; los demás se quitan, porque cada uno multiplica lo que se filtra el día que ese proceso caiga.
Clave: lo que se evalúa es que cada decisión venga con el ataque que encarece. “Devolver menos campos” sin decir qué ataque dificulta es higiene, no diseño.
15Resumen
- Zero Trust retira una credencial concreta y muy mala: la ubicación de red, que no caduca, no se revoca y se obtiene entera con el primer equipo comprometido.
- Cada petición se decide con tres entradas: quién, qué pide y en qué contexto. Cada vez, no una vez al entrar.
- Microsegmentar no es Zero Trust: reduce el movimiento lateral y sigue autorizando por ubicación, solo que la ubicación es más pequeña.
- Sin identidad de carga de trabajo no hay política posible: una credencial compartida convierte cualquier autorización en teatro.
- Las cuatro propiedades que hacen útil una identidad: por servicio, vida corta, audiencia y alcance, verificable por el destino.
- Mínimo conocimiento se rompe en tres sitios poco vigilados: la respuesta de la API, el log y las variables de entorno.
- La separación de responsabilidades se mide por el camino más corto a producción, y ese camino casi siempre pasa por el pipeline.
16Mis notas
Estas notas se guardan solo en este navegador. No se envían a ningún servidor. Expórtalas desde el panel de progreso si cambias de máquina.
17Recursos
Los comentarios se cargan solo si los pides, desde GitHub Discussions. No se carga nada de terceros mientras no pulses.