Pular para o conteúdo principal
BlogComputaçãoDefesa contra um ataque de força bruta à API de login

Defesa contra um ataque de força bruta à API de login

Um símbolo de bloco vermelho com o seguinte texto: "Defesa contra um ataque de força bruta à API de login: Porque cortar caminho pode deixá-lo incapacitado"

Sejamos realistas: quando você está correndo para cumprir o prazo de um grande lançamento, você acaba tomando atalhos. Sua cobertura de teste fica irregular, seu código não é tão DRY e seu tratamento de exceções é enviado para o cemitério de dívidas tecnológicas, ou seja, para o backlog. Todos nós já passamos por isso.

Mas, quando chegar a hora de cortar caminho, não deixe de implementar a proteção "tentativa máxima de login com falha". Se a sua API de login não tiver as devidas proteções, obter acesso a uma conta de usuário por meio de força bruta é relativamente fácil de ser feito hoje em dia.

Nesta publicação, mostraremos como um invasor pode aplicar força bruta em uma API de login. Em seguida, discutiremos as contramedidas que você pode colocar em prática para defender seus sistemas.

Um exemplo de API de login

Para demonstrar, criamos um servidor de API muito básico usando Node.js e Express. Ele escuta solicitações POST em um único ponto de extremidade, /login. Espera-se que o corpo da solicitação tenha um username e um password. Quando as credenciais são fornecidas com êxito, a API retorna 200 OK. Caso contrário, ele retorna 401 UNAUTHORIZED.

Aqui está o código do nosso servidor Express simples:

const express = require('express');
const users = require('./users.json');

const app = express();
const PORT = 3000;

// Middleware to parse JSON bodies
app.use(express.json());

app.post('/login', (req, res) => {
    const { username, password } = req.body;

    // Check if the username exists and the password matches
    if (users[username] && users[username] === password) {
        return res.status(200).send('OK');
    } else {
        return res.status(401).send('UNAUTHORIZED');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server is listening on port ${PORT}`);
});

Para esta demonstração simples, mantemos a lista de nomes de usuário e senhas em um arquivo chamado users.json.

Implementamos nosso servidor em um Linode, escutando na porta 3000. Vamos testar uma solicitação:

~$ curl -i \        -X POST \        --header "Content-type:application/json" \        --data '{"username":"user08","password":"testpassword"}' \         172.233.153.34:3000/login

HTTP/1.1 401 UnauthorizedX-Powered-By: ExpressContent-Type: text/html; charset=utf-8Content-Length: 12ETag: W/"c-MvHJP5yPj49I/9tX+wGrvHWbTRk"Date: Sat, 25 May 2024 19:17:34 GMTConnection: keep-aliveKeep-Alive: timeout=5
UNAUTHORIZED

Nossa API de login está em funcionamento!

Agora, se quisermos usar força bruta em nossa API, podemos escrever um script como este:

#!/bin/sh

API_ENDPOINT="http://172.233.153.34:3000/login"

USERNAME="user5"

echo "Attempting to login at $API_ENDPOINT as \"$USERNAME\""

for i in {1..8}
do
  PASS="password${i}"
  RESULT=$(curl --silent -X POST --header "Content-type:application/json" --data "{\"username\":\"$USERNAME\",\"password\":\"$PASS\"}" $API_ENDPOINT)
  echo "\"$PASS\": $RESULT"

  if [[ $RESULT == 'OK' ]]; then
    echo "!!! Password for \"$USERNAME\" found: \"$PASS\""
    break
  else
    sleep 1
  fi
done

Quando executamos nosso script rudimentar de força bruta, o resultado é o seguinte:

$ source bruteforce.sh
Attempting to login at http://172.233.153.34:3000/login as "user5"
"password1": UNAUTHORIZED
"password2": UNAUTHORIZED
"password3": UNAUTHORIZED
"password4": UNAUTHORIZED
"password5": OK
!!! Password for user5 found: "password5"

Um invasor pode realmente adivinhar uma senha?

Portanto, vimos como é fácil escrever um script que pode, pelo menos, percorrer algumas senhas para um determinado nome de usuário. Você pode dizer: "Ok, esse é um exemplo interessante e artificial. Mas será que um invasor pode realmente adivinhar uma senha?"

Aqui está uma lista das 10.000 senhas mais comuns. Esse é um bom começo para qualquer invasor. Pense nisso: você já se deparou com alguém que usa "password123" ou "qwerty"? Pode até ser você!

Se um invasor conhecesse alguns nomes de usuário do seu sistema e executasse um script para percorrer essas senhas comuns, ele poderia obter um resultado.

A cada tentativa permitida de combinação de nome de usuário e senha, aumentam as chances de violação de uma conta.

Esse é um caso clássico de autenticação interrompida, que está em segundo lugar na lista dos 10 principais riscos de segurança de API da OWASP. Se o seu aplicativo não protege adequadamente contra ataques automatizados, você está pedindo para ter problemas. Sem proteções, as contas dos seus usuários correm um risco significativo.

As senhas geralmente são o elo mais fraco na segurança de um sistema:

  • Os usuários reutilizam senhas em vários sites.
  • Os usuários escolhem senhas fáceis de lembrar (e fáceis de adivinhar).
  • Os usuários raramente atualizam suas senhas.

Todos esses fatores tornam os ataques de força bruta assustadoramente eficazes.

Então, vamos voltar à nossa pergunta: Um invasor pode realmente adivinhar uma senha? Com certeza. E se você não estiver tomando as precauções corretas, isso pode acontecer mais cedo do que você imagina.

Como posso proteger minha API?

Há várias maneiras de se defender contra um ataque de força bruta em sua API de login.

Estabelecer um número máximo de tentativas de login com falha

Defina um limite para o número de tentativas de login com falha que você permitirá para cada usuário. À medida que ocorrerem tentativas de login para um usuário, mantenha uma contagem contínua das falhas de login. Se você atingir esse limite, bloqueie a conta temporariamente ou bloqueie as solicitações subsequentes do endereço IP do remetente. Isso dificulta muito a entrada de um invasor por meio de força bruta.

Use um firewall de aplicativo da Web (WAF)

Um WAF pode ajudar a proteger sua API, detectando e bloqueando atividades mal-intencionadas.

  • Atividade de bots: Um bom WAF pode distinguir entre usuários legítimos e bots, bloqueando ataques automatizados de força bruta.
  • Solicitações de login suspeitas por trás do Tor: Muitos invasores usam a rede Tor para ocultar sua identidade. O bloqueio ou o desafio de solicitações de nós do Tor pode reduzir o risco de ataques.

O Haltdos, que é um WAF disponível no Linode Marketplace, oferece essas proteções e muito mais. Ao integrar essas ferramentas, você pode reforçar significativamente as defesas de sua API.

Implementar limitação de taxa

Limite o número de solicitações de API de um único endereço IP em um determinado período de tempo. Isso reduz a velocidade dos ataques de força bruta e os torna menos viáveis. A limitação de taxa é uma boa prática para todas as suas APIs e pontos de extremidade, não apenas para a API de login.

Ativar a autenticação multifatorial (MFA)

Se você adicionar uma camada extra de segurança, como a MFA, poderá impedir ataques de força bruta mesmo quando o invasor adivinhar a senha corretamente. Passar com sucesso por todo o fluxo de autenticação requer algo que o usuário saiba (senha) e algo que ele tenha (um telefone ou token de hardware).

Monitorar e analisar tentativas de login

Configure uma solução de monitoramento de solicitações de API para ficar de olho nas tentativas de login. Procure padrões que possam indicar um ataque. Isso pode ajudá-lo a responder rapidamente a atividades suspeitas.

A implementação dessas medidas pode ajudar a proteger sua API contra ataques de força bruta e manter as contas dos usuários seguras.

Conclusão

É fundamental proteger sua API de login contra ataques de força bruta. Adivinhar uma senha não é tão difícil quanto você imagina, e automatizar as adivinhações é uma brincadeira de criança. Seu sistema está vulnerável? Abordamos várias coisas que você pode fazer para proteger seus sistemas. Essas etapas aumentarão significativamente sua postura de segurança.

Na correria frenética da criação de aplicativos e APIs, nós o perdoaremos se você cortar alguns cantos aqui e ali. Todo mundo faz isso. Mas não deixe sua API de login desprotegida! Não espere até que ocorra um ataque - tome medidas agora para proteger seu sistema e seus usuários. Para obter orientações mais detalhadas sobre registro e monitoramento do sistema, consulte os documentos da Linode. Se você planeja usar o Apache para atender aos seus aplicativos, consulte este guia sobre como configurar o mod_evasive para ajudar seu servidor a sobreviver a ataques DoS/DDoS.

Fique em segurança!

Comentários

Deixe uma resposta

Seu endereço de e-mail não será publicado. Os campos obrigatórios estão marcados com *