Ir para o conteúdo

API4:2023 Unrestricted Resource Consumption

Agentes Ameaça/Vetores Ataque Falha Segurança Impactos
Específico da API : Abuso Moderado Prevalência Predominante : Deteção Fácil Técnico Grave : Específico Negócio
A exploração requer pedidos simples de API. Múltiplos pedidos concorrentes podem ser feitos a partir de um único computador local ou utilizando recursos de computação em nuvem. A maioria das ferramentas automatizadas disponíveis são projetadas para causar DoS (Negação de Serviço) através de altas cargas de tráfego, afetando a taxa de serviço das APIs. É comum encontrar APIs que não limitam as interações do cliente ou o consumo de recursos. Pedidos de API elaborados, como aqueles que incluem parâmetros que controlam o número de recursos a serem retornados e realizam análises de estado/tempo/comprimento de resposta, devem permitir a identificação do problema. O mesmo vale para operações em quantidade. Embora os agentes maliciosos não tenham visibilidade sobre o impacto nos custos, isso pode ser inferido com base no modelo de negócios/preços dos fornecedores de serviços (e.g. fornecedor de nuvem). A exploração pode levar a uma Negação de Serviço (DoS) devido à escassez de recursos, mas também pode resultar num aumento dos custos operacionais, como os relacionados à infraestrutura devido à maior exigência de CPU, aumento das necessidades de armazenamento em nuvem, etc.

A API é vulnerável?

Para atender aos pedidos feitos à API, são necessários recursos como largura de banda de rede, CPU, memória e armazenamento. Às vezes, os recursos necessários são disponibilizados por provedores de serviços por meio de integrações de API e são pagos por pedido, como o envio de emails/SMS/chamadas telefónicas, validação biométrica, etc.

Uma API é vulnerável se pelo menos um dos seguintes limites estiver ausente ou definido inadequadamente (e.g. muito baixo/alto):

  • Tempos limite de execução
  • Memória máxima alocável
  • Número máximo de descritores de ficheiro
  • Número máximo de processos
  • Tamanho máximo de upload de ficheiro
  • Número de operações a serem realizadas num único pedido do cliente da API (e.g. agrupamento GraphQL)
  • Número de registros por página a serem retornados num único pedido-resposta
  • Limite de gastos de provedores de serviços terceiros

Exemplos de Cenários de Ataque

Cenário #1

Uma rede social implementou um mecanismo de "recuperar senha" através da verificação por SMS, permitindo que o utilizador receba um token de uso único via SMS para redefinir a sua senha.

Uma vez que o utilizador clica em "recuperar senha", é feita uma chamada API a partir do navegador do utilizador para a API de back-end:

POST /initiate_forgot_password

{
  "step": 1,
  "user_number": "6501113434"
}

Em seguida, nos bastidores, é feita uma chamada API do back-end para uma API de terceiros que se encarrega da entrega do SMS:

POST /sms/send_reset_pass_code

Host: willyo.net

{
  "phone_number": "6501113434"
}

O fornecedor de terceiros, Willyo, cobra $0.05 por este tipo de chamada.

Um atacante escreve código que envia a primeira chamada API dezenas de milhares de vezes. O back-end prossegue e solicita à Willyo que envie dezenas de milhares de mensagens de texto, levando a empresa a perder milhares de dólares em questão de minutos.

Cenário #2

Um endpoint de API GraphQL permite que o utilizador carregue uma foto de perfil.

POST /graphql

{
  "query": "mutation {
    uploadPic(name: \"pic1\", base64_pic: \"R0FOIEFOR0xJVA…\") {
      url
    }
  }"
}

Uma vez concluído o carregamento, a API gera múltiplas miniaturas com diferentes tamanhos com base na imagem carregada. Esta operação gráfica consome muita memória do servidor.

A API implementa uma proteção tradicional de limitação de quantidade de pedidos - um utilizador não pode aceder ao endpoint GraphQL demasiadas vezes num curto período de tempo. A API também verifica o tamanho da imagem carregada antes de gerar as miniaturas para evitar o processamento de imagens demasiado grandes.

Um atacante pode facilmente contornar esses mecanismos, aproveitando a natureza flexível do GraphQL:

POST /graphql

[
  {"query": "mutation {uploadPic(name: \"pic1\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
  {"query": "mutation {uploadPic(name: \"pic2\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
  ...
  {"query": "mutation {uploadPic(name: \"pic999\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
}

Como a API não limita o número de vezes que a operação uploadPic pode ser tentada, a chamada levará ao esgotamento da memória do servidor e à negação de serviço (Denial of Service).

Cenário #3

Um prestador de serviços permite que os clientes descarreguem ficheiros arbitrariamente grandes através da sua API. Estes ficheiros são mantidos em armazenamento de objetos na nuvem e não mudam com frequência. O prestador de serviços depende de um serviço de cache para melhorar a velocidade do serviço e manter o consumo de largura de banda baixo. O serviço de cache apenas armazena ficheiros até 15GB.

Quando um dos ficheiros é atualizado, o seu tamanho aumenta para 18GB. Todos os clientes do serviço começam imediatamente a descarregar a nova versão. Como não havia alertas de custo de consumo, nem um limite máximo de custo para o serviço de nuvem, a fatura mensal seguinte aumenta de 13 dólares, em média, para 8 mil dólares.

Como Prevenir

  • Utilize uma solução que facilite a limitação de memória, CPU, número de reinícios, descritores de ficheiros e processos, como Containers / Código Serverless (e.g. Lambdas).
  • Defina e force um tamanho máximo de dados em todos os parâmetros e conteúdos de entrada, como comprimento máximo para strings, número máximo de elementos em arrays e tamanho máximo de ficheiro para upload (independentemente de ser armazenado localmente ou na nuvem).
  • Implemente um limite de frequência com que um cliente pode interagir com a API dentro de um período temporal definido (rate limiting).
  • A limitação de pedidos deve ser ajustada com base nas necessidades do negócio. Alguns endpoints da API podem exigir políticas mais rigorosas.
  • Limite/controle quantas vezes ou com que frequência um único cliente/utilizador da API pode executar uma única operação (e.g. validar um OTP ou solicitar a recuperação de senha sem visitar o URL de uso único).
  • Adicione validação adequada no lado do servidor para parâmetros da query string e do corpo do pedido, especificamente aqueles que controlam o número de resultados a serem retornados na resposta.
  • Configure limites de gastos para todos os fornecedores de serviços/integrações de API. Quando não for possível definir limites de gastos, devem ser configurados alertas de faturamento.

Referências

OWASP

Externas