Para: operadores de sites cuja busca ou recurso semelhante chama uma API externa. Este artigo generaliza algo que de fato aconteceu em um site operado pelo operador deste site. Não nomeia o site nem o serviço externo, e não informa limites ou datas exatos. Não aborda procedimentos de ataque.
O que aconteceu
Em um site operado pelo operador deste site, o recurso de busca chamava uma API externa a cada pesquisa. Em poucos dias, o tráfego de busca subiu para cerca de 20 vezes o normal. A API externa tinha um limite de concorrência, e a grande maioria das buscas (mais de 90%) retornou 503.
A primeira suposição era de que um limite por IP (N por minuto) conteria o problema. Estava errada.
O tráfego de busca subiu cerca de 20 vezes em poucos dias
O limite de concorrência da API externa foi atingido e quase todas as buscas retornaram 503. Nesse momento, parecia apenas mais erros.
Primeira suposição: um limite por IP conteria o problema (errada)
Contar por minuto e por IP pegaria alguns IPs fazendo um número muito grande de chamadas. Este não era esse tipo de tráfego.
O que a medição mostrou
As cerca de 60.000 buscas de um dia vieram de cerca de 60.000 IPs distintos, aproximadamente uma requisição por IP. O padrão lembrava uma rede de proxies residenciais. O user agent era um navegador comum, o Referer era o próprio site e as consultas eram nomes reais de produtos. A coleta de preços era a finalidade provável.
A cota diária da API externa acabou cedo no dia
As buscas do bot consumiram a cota logo cedo, e visitantes comuns não conseguiram buscar durante a maior parte do dia.
Por que não parecia ser o problema real
A cota estava protegida, então a API externa parecia saudável e o site via apenas mais erros. Proteger a cota e permitir que os usuários usem o recurso acabaram sendo coisas diferentes.
O esperado: poucos IPs fazendo muitas chamadas
Atinge o limite por IP → bloqueado ✓
O que aconteceu: cerca de 60.000 IPs, uma requisição cada
Nenhum IP atinge o limite → apenas a cota da API externa se esgota
= enquanto a unidade de contagem for o IP, esse padrão fica invisível
Uma cota de upstream protegida não significa que os usuários podem usar o recurso
Tudo o que protege a cota ou a concorrência de uma API externa existe para evitar que essa API quebre. Enquanto funciona, o upstream não mostra erros. O custo recai sobre quem perdeu a cota: os seus próprios visitantes.
O fato de a proteção estar funcionando é o que tornou o problema difícil de perceber. O que deve ser observado é a taxa de sucesso que os visitantes reais obtêm ao buscar.
Como foi contido
O desenho que não impediu o problema
Qualquer requisição de busca de qualquer pessoa chama a API externa. O único limite é uma contagem por IP. Tráfego distribuído mantém a contagem de cada IP baixa, então nunca aciona o limite.
O desenho que funcionou
A API externa só é chamada para buscas que trazem um token assinado (cookie) emitido pela própria página do site. Sem token, retorna-se uma página leve ou 403. Além disso, há limites horários globais e por token.
- Token assinado
- Um token emitido pela própria página do site passou a ser a condição para chamar a API externa. Sem ele, uma página leve ou 403
- Proteção dos agregados
- Buscas sem token foram excluídas do ranking de buscas populares, que as consultas do bot haviam inflado
- Limites horários
- Tanto um limite global quanto um limite por token
Logo após a liberação, os 503 caíram para zero. Cerca de 100.000 requisições sem token por dia agora recebem um 403, e as buscas normais passam.
Lições
- Um limite por IP não funciona contra um bot distribuído. Uma requisição por IP não barra nada, por mais baixo que seja o limite.
- Uma cota de upstream protegida não é o mesmo que os usuários conseguirem usar o recurso. A proteção pode esconder o problema.
- Agregados, como rankings, ficam contaminados. Além de proteger a API externa, restrinja o que alimenta esses agregados.
O que fazer do seu lado
A ordem abaixo é um conselho deste site, não uma declaração das fontes citadas.
Verifique um token emitido pelo site antes de qualquer etapa cara
Antes de uma etapa que consome custo ou cota, como uma chamada a uma API externa, verifique um token assinado emitido pela sua própria página. Defina uma validade para o token e verifique-o no servidor. Se estiver ausente, não prossiga; retorne uma página leve ou 403.
Mantenha o tráfego sem token fora dos agregados
Monte buscas populares, estatísticas de consultas e recomendações apenas a partir de buscas com token, para que as consultas de um bot não se infiltrem no que o seu site exibe.
Defina limites globais e por token
Use um limite horário global e um limite por token, em vez de uma contagem por IP. O limite global é a última barreira que impede o esgotamento da cota da API externa.
Adicione cache de resultados e filas
Sirva consultas repetidas a partir de um cache, sem chamar a API externa novamente, e enfileire requisições quando o sistema estiver ocupado. Quando uma medida for contornada, é menos provável que a cota desapareça de uma só vez.
Observe a taxa de sucesso que os visitantes veem
Registre a parcela de visitantes reais cujas buscas dão certo, não apenas a taxa de erro da API externa, e emita um alerta quando ela cair. Este é o estado de "conseguir perceber que algo está errado" descrito em a linha de base de segurança organizacional.
Um token não é autenticação; ele aumenta o custo do atacante
Um token não é autenticação. O que um token oferece é uma barreira ao tráfego que simplesmente bombardeia a URL de busca; não é uma defesa completa.
Por isso ele é combinado com cache, filas e limites por token. Na visão deste site, limites por token não ajudam se um bot buscar um token novo a cada vez, então sempre os combine com um limite global e com cache. A visão deste site, como em Limitação de taxa e controle de abuso, é tornar o abuso não compensador, em vez de reduzir a taxa de sucesso dele a zero.
Fontes (primárias)
- OWASP API Security Top 10 2023, "API4:2023 Unrestricted Resource Consumption" — api-security.owasp.org (limitar a frequência com que um cliente interage com a API em um intervalo de tempo; configurar limites de gastos para serviços externos)
- OWASP Automated Threats, "OAT-011 Scraping" — owasp.github.io (define scraping como a coleta de conteúdo ou dados para uso em outro lugar, como a fixação de preços; dados que não exigem autenticação podem ser alvo)
Leia em seguida
- Design: Limitação de taxa e controle de abuso: como projetar limites que barram força bruta e custos descontrolados
- Pré-requisito: Falsificação de X-Forwarded-For e proxies confiáveis (a base para contar por IP)
- Operações: A linha de base de segurança organizacional (como perceber que algo está errado)