Como blindar APIs REST contra força bruta com Redis
Proteja sua API REST contra ataques de força bruta implementando rate limiting por token bucket no Redis e bloqueio dinâmico de IPs maliciosos.
Resumo
- O algoritmo token bucket permite picos controlados de tráfego sem penalizar requisições legítimas
- O Redis garante contagens atômicas em milissegundos para evitar condições de corrida em ambiente distribuído
- Scripts em Lua executados no servidor Redis reduzem saltos de rede e garantem operações seguras
- O bloqueio dinâmico baseado em falhas consecutivas isola endereços IP suspeitos de forma automatizada
- A combinação de cache rápido e expiração TTL protege a infraestrutura sem consumir memória excessiva
Por que APIs REST são alvos fáceis para ataques de força bruta
Ataques de força bruta ocorrem quando robôs testam milhares de combinações de senhas ou chaves em segundos para invadir sistemas. Em uma API REST aberta, isso consome recursos preciosos de CPU e banco de dados, podendo derrubar o servidor inteiro. Na prática, isso significa que sem uma barreira inteligente, qualquer aplicação web está vulnerável a indisponibilidades e roubo de dados. Para mitigar esse problema, precisamos de mecanismos automatizados que reconheçam e barrem o comportamento abusivo antes que o estrago aconteça.
O que é o algoritmo Token Bucket e como ele funciona
O token bucket, ou balde de tokens, é um modelo matemático elegante para controlar a velocidade de tráfego. Imagine um balde que recebe gotas de água a uma taxa constante até encher; cada requisição gasta uma gota para passar. Se o balde estiver vazio, a requisição é rejeitada ou colocada em espera até que novas gotas caiam. Na prática, isso permite que um usuário legítimo faça algumas requisições rápidas em sequência — como carregar várias imagens de uma página —, mas impede que robôs enviem milhares de chamadas por segundo. Trata-se de um sistema flexível que diferencia picos normais de tráfego de ataques deliberados.
Por que utilizar o Redis para controle de taxa de requisições
O Redis é um banco de dados em memória extremamente rápido, operando com chaves e valores na RAM do computador. Quando usamos servidores múltiplos em nuvem para rodar uma aplicação, armazenar o controle de requisições na memória local de cada máquina falha porque os dados não se conversam. Na prática, isso significa que o Redis atua como um painel centralizado e compartilhado onde todas as instâncias da API consultam o saldo de tokens instantaneamente. Além disso, operações atômicas evitam que dois acessos simultâneos corrompam a contagem de acessos permitidos. Para quem busca otimizar desempenho, vale conferir também como foi estruturada a API lenta no NestJS com cache distribuído em Redis para entender outras aplicações dessa ferramenta.
Implementando o Token Bucket com scripts Lua no Redis
Para garantir que a verificação e a atualização do saldo de tokens ocorram em uma única etapa sem interferências, utilizamos scripts na linguagem Lua executados diretamente dentro do Redis. Na prática, isso evita que requisições paralelas leiam valores desatualizados enquanto o balde está sendo recalculado. Abaixo está um exemplo funcional de script Lua que calcula o tempo decorrido, repõe os tokens e desconta a requisição atual 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}Esse script roda diretamente no motor do banco de dados, garantindo velocidade máxima e integridade total dos dados sob alta concorrência.
Estratégia de bloqueio dinâmico para IPs maliciosos
Apenas limitar a quantidade de requisições pode não ser suficiente para conter robôs persistentes que alternam padrões de acesso. A melhor abordagem complementar é o bloqueio dinâmico, que monitora falhas consecutivas ou estouros repetidos do balde de tokens. Na prática, se um endereço IP estourar o limite três vezes em menos de cinco minutos, nosso sistema insere esse IP em uma lista temporária de bloqueio por uma hora. Isso poupa processamento valioso, pois requisições vindas dali são rejeitadas instantaneamente logo na borda da aplicação, sem sequer chegar aos controladores da API. Para complementar essa implementação em produção, vale conferir também nossas análises técnicas sobre Como achar curtos em placas com câmera térmica sem erro e Como configurar o agendador Cron no Linux sem errar.
Considerações finais sobre resiliência e segurança em APIs
Blindar uma API REST exige combinar arquiteturas eficientes em memória, como o Redis, com algoritmos inteligentes de controle de fluxo e isolamento de tráfego suspeito. A implementação do token bucket equilibra perfeitamente a experiência do usuário legítimo com a rigidez necessária contra ataques automatizados de força bruta. Ao adotar essas práticas, sua infraestrutura ganha estabilidade operacional, previne fraudes e protege dados sensíveis contra investidas maliciosas constantes na internet.