Lección 5 de 613 min
Proteger la infraestructura y el acceso
Rate limiting, WAF, protección DDoS, control de acceso RBAC y ABAC, y el modelo Zero Trust.
Tu aplicación puede estar bien escrita y aun así caer. Un bot prueba diez mil contraseñas por minuto en tu login, alguien lanza miles de búsquedas pesadas para agotar tu base de datos, o una red de dispositivos infectados envía más tráfico del que cabe en tu conexión. Nada de eso explota un error en tu código: explota que estás expuesto a Internet.
En esta lección verás las capas que se ponen delante de la aplicación para frenar ese tráfico (rate limiting, WAF y protección DDoS) y cómo decidir quién puede hacer qué una vez dentro: los modelos RBAC y ABAC y el enfoque Zero Trust.
En el borde de la red
Cada capa mira una cosa distinta: el rate limiting cuenta peticiones, el WAF inspecciona su contenido y la protección DDoS absorbe el volumen. Ninguna sustituye a las demás.
Rate limiting
Limitar cuántas peticiones puede hacer cada cliente en un periodo de tiempo.
- Respuesta:
- 429 + Retry-After
- Algoritmos:
- Ventanas, token bucket
El rate limiting cuenta las peticiones de cada cliente, identificado por su IP, su usuario o su clave de API, y rechaza las que superan el límite con un 429 Too Many Requests y una cabecera Retry-After que indica cuándo puede volver a intentarlo.
Hay varios algoritmos. La ventana fija cuenta por minutos de reloj y es muy simple, pero permite ráfagas dobles en el cambio de minuto. La ventana deslizante mira siempre los últimos 60 segundos y lo evita. El token bucket (cubo de fichas) da a cada cliente un cubo que se rellena a ritmo constante; cada petición gasta una ficha, así que admite ráfagas cortas sin superar la media.
Úsalo cuando
En el login, el registro, la recuperación de contraseña, las búsquedas costosas y cualquier API pública. Pon límites más estrictos donde una petición sea cara o sensible.
Ten en cuenta
Si tienes varias instancias, los contadores deben estar en un almacén compartido como Redis, o cada una aplicará su propio límite. Y limitar solo por IP castiga a quienes comparten conexión, como una oficina entera.
// Token bucket: ráfagas de hasta 10 peticiones, 1 ficha nueva por segundo
const CAPACIDAD = 10;
const RECARGA_POR_SEGUNDO = 1;
const cubos = new Map<string, { fichas: number; ultima: number }>();
function permitir(cliente: string): boolean {
const ahora = Date.now() / 1000;
const cubo = cubos.get(cliente) ?? { fichas: CAPACIDAD, ultima: ahora };
cubo.fichas = Math.min(CAPACIDAD, cubo.fichas + (ahora - cubo.ultima) * RECARGA_POR_SEGUNDO);
cubo.ultima = ahora;
cubos.set(cliente, cubo);
if (cubo.fichas < 1) return false;
cubo.fichas -= 1;
return true;
}
app.post("/login", (req, res, next) => {
if (permitir(req.ip)) return next();
res.set("Retry-After", "1").status(429).json({ error: "Demasiados intentos" });
});WAF
Un cortafuegos que inspecciona cada petición HTTP en busca de ataques conocidos.
- Capa:
- 7 (HTTP)
- Reglas abiertas:
- OWASP CRS
Un WAF (Web Application Firewall) se coloca delante de tu aplicación y compara cada petición con un conjunto de reglas: patrones de inyección SQL, de XSS, intentos de leer archivos del sistema, herramientas de escaneo conocidas. Trabaja en la capa de aplicación, así que entiende de URLs, cabeceras y cuerpos, no solo de IPs y puertos.
El conjunto de reglas abierto más usado es el OWASP Core Rule Set (CRS), compatible con motores como ModSecurity o Coraza, y en el que se basan muchos WAF comerciales. Suma una puntuación de anomalía por cada indicio y bloquea cuando supera un umbral; su nivel de «paranoia» decide cuántas reglas aplica.
Todo WAF tiene dos modos: detección, en el que solo registra lo que habría bloqueado, y bloqueo, en el que rechaza la petición.
Úsalo cuando
Delante de cualquier aplicación expuesta, y sobre todo de las que no puedes parchear rápido. Te da tiempo cuando aparece una vulnerabilidad nueva en una librería que usas.
Ten en cuenta
Los falsos positivos son el gran coste: un foro de programadores en el que alguien pega una consulta SQL parecerá un ataque. Empieza en modo detección, revisa los registros y crea excepciones concretas. Y no confíes solo en él: es un parche, no un sustituto de corregir el código.
# Primero, solo registrar: así descubres los falsos positivos
SecRuleEngine DetectionOnly
# Carga el OWASP Core Rule Set
Include /etc/modsecurity/crs/crs-setup.conf
Include /etc/modsecurity/crs/rules/*.conf
# Excepción concreta: el editor de artículos envía HTML legítimo
SecRule REQUEST_URI "@beginsWith /admin/articulos" \
"id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=941100"Cloudflare WAF
Un WAF gestionado en el borde de Cloudflare: reglas listas, reglas propias y límites.
- Piezas:
- Gestionadas, personalizadas, rate limiting
Si tu tráfico ya pasa por Cloudflare, como viste en el módulo de cloud, su WAF filtra las peticiones antes de que lleguen a tu servidor. Tiene tres piezas. Las reglas gestionadas: conjuntos que mantiene Cloudflare, incluida su versión del OWASP Core Rule Set, y que se actualizan cuando aparece una vulnerabilidad sonada.
Las reglas personalizadas: expresiones sobre la petición (ruta, método, país, IP, cabeceras) con una acción, como bloquear, registrar o mostrar un desafío que los navegadores reales superan y los bots no. Y las reglas de rate limiting: cuentan peticiones por IP u otras características en un periodo y actúan al superar el límite.
Úsalo cuando
Cuando tu web ya está detrás de Cloudflare y quieres protección sin instalar nada en tu servidor, o reaccionar en minutos ante un ataque desde el panel.
Ten en cuenta
Qué conjuntos de reglas, cuántas reglas propias y qué periodos de rate limiting tienes depende de tu plan, y las condiciones cambian; consúltalo en la documentación. Y solo protege el tráfico que pasa por Cloudflare: si tu servidor acepta conexiones directas, se lo pueden saltar.
# Regla personalizada: el panel solo desde la oficina
Expresión: starts_with(http.request.uri.path, "/admin")
and not ip.src in {203.0.113.0/24}
Acción: Block
# Regla de rate limiting: frenar la fuerza bruta en el login
Expresión: http.request.uri.path eq "/login" and http.request.method eq "POST"
Contar por: IP
Límite: 5 peticiones por minuto
Acción: Managed Challenge durante 10 minutosProtección DDoS
Absorber en el borde un tráfico masivo y repartido que ningún servidor aguantaría solo.
- Volumétrico:
- Capas 3 y 4
- Aplicación:
- Capa 7
- Defensa clave:
- Anycast
Un ataque DDoS (denegación de servicio distribuida) usa miles de máquinas, a menudo dispositivos infectados, para saturarte. Los volumétricos atacan las capas 3 y 4 (red y transporte): inundaciones de paquetes UDP o de inicios de conexión TCP que llenan tu conexión antes de llegar a tu aplicación. Los de capa 7 envían peticiones HTTP que parecen normales, pero en tal cantidad, o tan caras de procesar, que agotan tu servidor.
Contra los volumétricos no hay servidor que valga: hace falta una red más grande que el ataque. Los proveedores de protección, como Cloudflare, AWS Shield o Google Cloud Armor, usan anycast: anuncian la misma IP desde muchos centros de datos, así que el tráfico de cada atacante llega al más cercano y el ataque se reparte y se absorbe por todo el mundo. Los de capa 7 se frenan con rate limiting, desafíos y reglas del WAF.
Úsalo cuando
En cualquier servicio cuya caída cueste dinero o reputación. En la nube, una protección básica suele venir incluida (AWS Shield Standard, por ejemplo); los niveles avanzados se contratan aparte.
Ten en cuenta
Si los atacantes descubren la IP real de tu servidor, lo atacan directamente y se saltan toda la protección. Haz que el origen solo acepte tráfico de tu proveedor y no expongas esa IP en registros DNS antiguos ni en cabeceras.
# Solo se acepta tráfico de la red del proveedor de protección.
# Usa los rangos que publica tu proveedor; estos son de ejemplo.
allow 198.51.100.0/24;
allow 203.0.113.0/24;
deny all;Nota
Una regla práctica para repartir el trabajo: la red del proveedor absorbe el volumen, el WAF filtra lo que parece un ataque, el rate limiting frena a quien abusa, y tu aplicación solo ve lo que ha superado esas tres capas.
Quién puede hacer qué
Una vez que el usuario está dentro, queda la pregunta más importante: ¿puede hacer esto? El control de acceso roto encabeza el OWASP Top 10 en sus ediciones recientes, y casi siempre se debe a una comprobación que falta en el servidor.
RBAC
Control de acceso basado en roles: los permisos se asignan a roles y los roles a personas.
- Decide por:
- El rol
En RBAC (Role-Based Access Control) defines roles como «lector», «editor» o «administrador», cada uno con una lista de permisos, y asignas uno o varios roles a cada usuario. Para saber si alguien puede borrar un artículo, miras si alguno de sus roles tiene ese permiso.
Es fácil de entender, de auditar y de explicar: «los editores pueden publicar». Por eso es el modelo de casi todos los paneles de administración, de los grupos de Microsoft Entra ID o de los roles de una base de datos.
Úsalo cuando
Cuando los permisos dependen sobre todo del puesto de cada persona y cambian poco. Aplica el mínimo privilegio: cada rol, solo lo que necesita.
Ten en cuenta
Los roles no responden a «¿es su pedido?»: comprobar el rol no basta si un cliente puede ver el pedido de otro cambiando el número de la URL. Y si cada excepción se convierte en un rol nuevo, acabarás con cientos de roles imposibles de gestionar.
type Rol = "lector" | "editor" | "admin";
type Permiso = "articulo:leer" | "articulo:editar" | "articulo:borrar";
const PERMISOS: Record<Rol, Permiso[]> = {
lector: ["articulo:leer"],
editor: ["articulo:leer", "articulo:editar"],
admin: ["articulo:leer", "articulo:editar", "articulo:borrar"],
};
function puede(usuario: { roles: Rol[] }, permiso: Permiso) {
return usuario.roles.some((rol) => PERMISOS[rol].includes(permiso));
}
// En el servidor y en cada petición: ocultar el botón no basta
if (!puede(req.usuario, "articulo:borrar")) return res.status(403).end();ABAC
Control de acceso basado en atributos del usuario, del recurso y del contexto.
- Decide por:
- Atributos y contexto
En ABAC (Attribute-Based Access Control), la decisión sale de una política que combina atributos: del usuario (departamento, nivel), del recurso (propietario, confidencialidad), de la acción y del contexto (hora, red, dispositivo). Por ejemplo: «un médico puede ver un historial si es de su hospital y está de guardia».
Es mucho más expresivo que RBAC y evita la explosión de roles. En AWS, IAM permite políticas que comparan etiquetas del usuario y del recurso, y existen motores dedicados, como Open Policy Agent o Cedar, que evalúan políticas escritas aparte del código.
Úsalo cuando
Cuando la respuesta depende de a quién pertenece el recurso, de dónde viene la petición o de cuándo se hace, y los roles se quedan cortos. En la práctica se combina con RBAC: el rol como un atributo más.
Ten en cuenta
Es más difícil de auditar: «¿quién puede ver este historial?» ya no se responde mirando una lista. Prueba las políticas como pruebas el código y registra cada decisión.
// Política: atributos del usuario, del recurso y del contexto
function puedeVerHistorial(
usuario: { puesto: string; hospitalId: string; deGuardia: boolean },
historial: { hospitalId: string },
contexto: { red: "hospital" | "externa" },
) {
return (
usuario.puesto === "medico" &&
usuario.hospitalId === historial.hospitalId &&
usuario.deGuardia &&
contexto.red === "hospital"
);
}Zero Trust
«Nunca confíes, verifica siempre»: estar en la red interna no da acceso a nada.
- Referencia:
- NIST SP 800-207
- Ejemplo pionero:
- Google BeyondCorp
El modelo clásico es un castillo con foso: fuera todo es hostil, dentro todo es de confianza, y la VPN es el puente levadizo. El problema es que, si un atacante entra con un portátil robado o una contraseña filtrada, se mueve a sus anchas por la red interna.
Zero Trust elimina esa confianza implícita. Cada acceso a cada aplicación se verifica por separado, combinando la identidad (quién eres, con MFA), el dispositivo (si es de la empresa, si está actualizado y cifrado) y el contexto (desde dónde, a qué hora, con qué riesgo). Y cada acceso concede solo lo mínimo necesario.
Úsalo cuando
Para dar acceso a herramientas internas sin VPN, a empleados que trabajan desde cualquier sitio, y entre microservicios, que deben autenticarse entre ellos aunque estén en la misma red.
Ten en cuenta
No es un producto que se compra, sino un enfoque que se adopta poco a poco: empieza por las aplicaciones más sensibles. Y depende de tener una identidad sólida: si tu proveedor de identidad falla, falla todo.
Aplicación: panel.tienda.com
Permitir si se cumple todo:
identidad correo @tienda.com, verificado por el IdP con MFA
dispositivo portátil de la empresa, disco cifrado, sistema al día
contexto riesgo del inicio de sesión: bajo
Se verifica en cada petición; la sesión dura 8 horas como máximoInteractivo
Tres capas contra el tráfico abusivo
Activa o desactiva opciones para compararlas cara a cara.
| Característica | Rate limiting | WAF | Protección DDoS |
|---|---|---|---|
| Qué mira | Cuántas peticiones hace cada cliente | El contenido de cada petición | El volumen total de tráfico |
| Frena | Fuerza bruta, scraping, abuso de la API | Inyecciones, exploits conocidos, escáneres | Inundaciones de red y de peticiones |
| No frena | Un ataque lento o repartido entre miles de IPs | Fallos de lógica de tu aplicación | Ataques que no buscan tumbarte |
| Dónde vive | Tu servidor, el proxy o la CDN | Delante de la aplicación: CDN, balanceador o proxy | La red del proveedor, en el borde |
| Riesgo típico | Castigar a muchos usuarios tras una misma IP | Falsos positivos | Que ataquen directamente la IP de tu origen |
Ponlo en práctica
Saber qué es cada cosa es la mitad del trabajo. La otra mitad es reconocer cuándo usarla.
Interactivo
¿Qué usarías?
Lee cada situación y elige la opción que mejor la resuelve. Fallar aquí no cuenta: es para practicar.
Los registros muestran que una misma IP prueba cientos de combinaciones de usuario y contraseña por minuto contra tu /login.
Para recordar
- El rate limiting frena el abuso contando peticiones por cliente y responde con
429yRetry-After. - Un WAF inspecciona el contenido de las peticiones; empieza en modo detección para domar los falsos positivos.
- Contra un DDoS volumétrico hace falta una red más grande que el ataque, y que tu origen solo acepte tráfico de ella.
- RBAC decide por roles y ABAC por atributos; los dos se comprueban en el servidor, en cada petición, con el mínimo privilegio.
- Zero Trust no regala confianza por estar en la red interna: verifica identidad, dispositivo y contexto en cada acceso.
Comprueba lo aprendido
Cuestionario
Responde las 5 preguntas para completar la lección.
1.Limitas a 100 peticiones por minuto con una ventana fija. ¿Cuántas puede enviar un cliente en apenas dos segundos?
2.¿Qué debería devolver tu API a un cliente que ha superado el límite de peticiones?
3.¿Por qué se suele activar un WAF primero en modo detección?
4.Tu web está detrás de un proveedor anti-DDoS, pero tu servidor de origen acepta conexiones de cualquier IP. ¿Qué riesgo corres?
5.En un modelo Zero Trust, ¿qué te da estar conectado a la red interna de la oficina?