Marcio Cunha

Cómo blindar APIs REST contra fuerza bruta con Redis

Proteja su API REST contra ataques de fuerza bruta implementando limitación de tasa token bucket en Redis y bloqueo dinámico de IPs maliciosas.

Marcio Cunha•4 min
También disponible en:PortuguêsEnglish
Resumen
  • El algoritmo token bucket permite picos de tráfico controlados sin penalizar solicitudes legítimas
  • Redis garantiza recuentos atómicos en milisegundos para evitar condiciones de carrera en entornos distribuidos
  • Los scripts en Lua ejecutados dentro del servidor Redis reducen saltos de red y garantizan operaciones seguras
  • El bloqueo dinámico basado en fallos consecutivos aísla direcciones IP sospechosas de forma automatizada
  • La combinación de caché rápido y expiración TTL protege la infraestructura sin consumo excesivo de memoria

Por qué las APIs REST son blancos fáciles para ataques de fuerza bruta

Los ataques de fuerza bruta ocurren cuando bots prueban miles de combinaciones de contraseñas o claves en segundos para vulnerar sistemas. En una API REST abierta, esto consume recursos preciosos de CPU y base de datos, pudiendo colapsar todo el servidor. En la práctica, esto significa que sin una barrera inteligente, cualquier aplicación web queda vulnerable a caídas y robos de datos. Para mitigar este problema, necesitamos mecanismos automatizados que reconozcan y bloqueen comportamientos abusivos antes de que ocurra el daño.

Qué es el algoritmo Token Bucket y cómo funciona

El token bucket, o cubo de fichas, es un modelo matemático elegante para controlar la velocidad de tráfico. Imagine un cubo que recibe gotas de agua a un ritmo constante hasta llenarse; cada solicitud gasta una gota para pasar. Si el cubo está vacío, la solicitud es rechazada o puesta en espera hasta que caigan nuevas gotas. En la práctica, esto permite que un usuario legítimo haga algunas solicitudes rápidas en secuencia —como cargar varias imágenes de una página—, pero impide que los bots envíen miles de llamadas por segundo. Se trata de un sistema flexible que diferencia picos normales de tráfico de ataques deliberados.

Por qué utilizar Redis para el control de tasa de solicitudes

Redis es una base de datos en memoria extremadamente rápida, que opera con claves y valores en la memoria RAM del ordenador. Cuando usamos múltiples servidores en la nube para ejecutar una aplicación, almacenar el control de solicitudes en la memoria local de cada máquina falla porque los datos no se comunican entre sí. En la práctica, esto significa que Redis actúa como un panel centralizado y compartido donde todas las instancias de la API consultan el saldo de tokens al instante. Además, las operaciones atómicas evitan que dos accesos simultáneos corrompan el conteo de accesos permitidos. Para quienes buscan optimizar el rendimiento, vale la pena revisar cómo se estructuró la API lenta en NestJS con caché distribuida en Redis para comprender otros usos de esta herramienta.

Implementando Token Bucket con scripts Lua en Redis

Para garantizar que la verificación y actualización del saldo de tokens ocurran en un solo paso sin interferencias, utilizamos scripts en el lenguaje Lua ejecutados directamente dentro de Redis. En la práctica, esto evita que solicitudes paralelas lean valores desactualizados mientras se recalcula el cubo. A continuación se muestra un ejemplo funcional de un script Lua que calcula el tiempo transcurrido, repone fichas y descuenta la solicitud actual de forma segura:

local key = KEYS[1]local capacity = tonumber(ARGV[1])local refill_rate = tonumber(ARGV[2])local now = tonumber(ARGV[3])local requested = tonumber(ARGV[4])local state = redis.call('HMGET', key, 'tokens', 'last_updated')local tokens = tonumber(state[1])local last_updated = tonumber(state[2])if not tokens then    tokens = capacity    last_updated = nowelse    local delta = math.max(0, now - last_updated)    tokens = math.min(capacity, tokens + (delta * refill_rate))endlocal allowed = 0if tokens >= requested then    tokens = tokens - requested    allowed = 1endredis.call('HMSET', key, 'tokens', tokens, 'last_updated', now)redis.call('EXPIRE', key, math.ceil(capacity / refill_rate))return {allowed, tokens}

Este script se ejecuta directamente en el motor de la base de datos, garantizando la máxima velocidad y la total integridad de los datos bajo alta concurrencia.

Estrategia de bloqueo dinámico para IPs maliciosas

Solo limitar la cantidad de solicitudes puede no ser suficiente para detener bots persistentes que rotan patrones de acceso. El mejor enfoque complementario es el bloqueo dinámico, que monitorea fallas consecutivas o desbordamientos repetidos del cubo de tokens. En la práctica, si una dirección IP excede el límite tres veces en menos de cinco minutos, nuestro sistema coloca esa IP en una lista de bloqueo temporal durante una hora. Esto ahorra un valioso poder de procesamiento, ya que las solicitudes provenientes de allí son rechazadas instantáneamente en el borde de la aplicación sin llegar siquiera a los controladores de la API. Para complementar esta implementación en entornos de producción, consulte también nuestros análisis técnicos sobre Cómo hallar cortocircuitos en placas con cámara térmica y Cómo configurar el programador Cron en Linux sin errores.

Consideraciones finales sobre resiliencia y seguridad en APIs

Blindar una API REST requiere combinar arquitecturas eficientes en memoria, como Redis, con algoritmos inteligentes de control de flujo y aislamiento de tráfico sospechoso. La implementación del token bucket equilibra perfectamente la experiencia del usuario legítimo con la rigidez necesaria contra ataques automatizados de fuerza bruta. Al adoptar estas prácticas, su infraestructura gana estabilidad operativa, previene fraudes y protege datos confidenciales frente a constantes intentos maliciosos en internet.