Como Proteger seus Webhooks no N8N com Métodos de Autenticação

Olá pessoal, tudo certo?

No post de hoje eu resolvi trazer uma prática muito importante para quem utiliza fluxos de automações no N8N com gatilhos de Webhooks, que é a preocupação e priorização com a parte de segurança na hora de implementá-los em seus fluxos.

As ferramentas de low-code e no-code são muito boas e interessantes para tirar a fricção de conhecimentos técnicos muito avançados em programação e desenvolvimento de software e permitem com que várias pessoas com pouco (ou nenhum) conhecimento da área consiga desenvolver soluções inovadoras e incríveis, apenas “arrastando” e configurando componentes. Por outro lado, essa falta de conhecimento e experiência, pode levar a problemas seríssimos de segurança e gerar prejuízos incalculáveis – tanto na questão de vazamento de dados indesejados, quanto financeiros (direta ou indiretamente).

Simulação de um Caso Real

Imagine a seguinte situação:

  1. Desenvolvemos uma integração com o N8N, que receba uma requisição via Webhook para iniciar um Fluxo de Automação
  2. Ao executar o Fluxo, um dos passos do N8N será utilizar um node de AI Agent, que irá simplesmente receber uma instrução fixa e retornar uma poesia ou a geração de algum conteúdo pré-determinado (por exemplo).

O nosso Webhook em questão está configurado da seguinte maneira:

HTTP Method: POST
Authentication: None
Respond: Immediately

Dessa forma, basta um bot executar N vezes a chamada para esse Webhook e nosso Fluxo de Automação iniciará, chamando N vezes o AI Agent configurado e consumindo deliberadamente muitos tokens.

Um simples script em Python é capaz de realizar essa ação:

import requests
import sys

def main():
  if len(sys.argv) < 3:
    print("Usage: python attack.py <number_of_requests> <url>")
    sys.exit(1)

  try:
    num_requests = int(sys.argv[1])
  except ValueError:
    print("Please provide a valid integer for the number of requests.")
    sys.exit(1)

  url = str(sys.argv[2])
  execute_attack(num_requests, url)


def execute_attack(num_requests, url):
  print(f"--- Starting attack on {url} with {num_requests} requests ---")

  headers = {"Content-Type": "application/json"}
  payload = {"message": "This is a test attack"}

  for i in range(num_requests):
    print(f"Sending request {i + 1}...")

    try:
      response = requests.post(url, json=payload, headers=headers, timeout=10)
      print(f"Request {i + 1}/{num_requests} - Status: {response.status_code}")
      try:
        print(f"Response: {response.json()}")
      except ValueError:
        print("Response is not in JSON format.")
    except requests.RequestException as e:
      print(f"Request {i + 1} failed: {e}")

if __name__ == "__main__":
  main()
python attack.py 30 https://n8n.progtech.com.br/webhook-test/0e6ed732-f3ed-42ae-a26d-ca61d2a7e68a

Ao executar o script, imediatamente o Fluxo de Automação será “disparado” 30 vezes seguidamente, sem nenhum tipo de impedimento.

E analisando as requisições que foram feitas para a API do Google Gemini, utilizando minhas credenciais, temos o seguinte gráfico:

A quantidade de tokens utilizada nessas 30 chamadas estão na imagem abaixo também:

No caso do exemplo acima, estou utilizando um modelo gratuito do Google Gemini, coloquei uma quantidade máxima de tokens gerados por execução do Fluxo e rodei “apenas” um bot para realizar 30 execuções.

Consegue visualizar claramente o risco e o prejuízo que isso poderia ocasionar com um sistema em produção?

Tipos de Autenticação de Webhooks no N8N

Abaixo, explico um pouco melhor sobre os 3 (três) tipos de autenticação suportados pelos webhooks do N8N, os prós e contras de cada um deles e situações em que são melhor aplicados.

Basic Auth

O que é:

Usuário e senha codificados em Base64 no header Authorization com o esquema Basic.

Authorization: Basic base64(username:password)
Pra que serve:

Controlar acesso simples entre sistemas quando você confia no cliente e quer algo rápido e fácil de implementar.

Prós

  • Simples (suporte nativo em quase todo cliente/servidor HTTP).
  • Bom para cenários internos/legados (painéis administrativos, ferramentas internas).

Contras

  • Credenciais “long lived” (se vazar, acesso total).
  • Ruim para rotacionar/escopar permissões.
  • Em webhooks, não autentica conteúdo e nem previne replays.

Use quando

  • Trafega sempre via HTTPS.
  • Integrações internas/low-risk onde é aceitável armazenar usuário/senha (recomendado uso de Vault para isso).
  • Endpoints protegidos por gateway ou VPN.

Como implementar no N8N

  • Escolher o tipo de autenticação como: Basic Auth.
  • Criar uma credencial e preencher a informação de User e Password.

Pronto. Agora basta utilizar a autenticação correta no seu client que estiver chamando o Webhook.

Header Auth (API Key / Token no Header)

O que é:

Enviar um token secreto (chave de API ou bearer token opaco) num header da requisição – padronizado com Authorization: Bearer <token> ou personalizado, ex: X-API-Key: <token>.

Authorization: Bearer sk_live_abc123...

# ou

X-API-Key: abc123...
Pra que serve:

Dar acesso com um segredo único por cliente/integração, geralmente com escopos e limitações.

Prós

  • Rotação fácil (regerar a chave resolve).
  • Pode ter escopos/quotas por chave.
  • Mais prático do que usuário/senha.

Contras

  • Ainda é um segredo compartilhado (se vazar, acesso total até revogar).
  • Não traz verificação de integridade do payload (a não ser que você assine à parte).

Use quando

  • APIs entre serviços/terceiros com múltiplas integrações (uma chave por cliente).
  • Você precisa revogar/rotacionar frequentemente.
  • Combine com HMAC de payload para webhooks.

Como implementar no N8N

  • Escolher o tipo de autenticação como: Header Auth.
  • Criar uma credencial e preencher os dados de Name e Value. Exemplo:
    Name: X-API-Key
    Value: abc123

Pronto. Agora basta utilizar a autenticação correta no seu client que estiver chamando o Webhook, passando o dados da no header (cabeçalho) da requisição.

JWT Auth (JSON Web Token Authentication)

O que é:

Um token assinado (HS256 com segredo ou RS256 com par de chaves) que carrega claims (sub, exp, scope, etc). Vai no header da requisição Authorization: Bearer <jwt>.

Authorization: Bearer eyJhGciOiJSUzI1nR5cCI6IkpxVxCJ9...
Pra que serve:

Autenticação stateless com expiração embutida e metadados do usuário/app. O servidor valida assinatura e claims sem precisar buscar estado no banco de dados.

Prós

  • Expiração (exp) e escopos no próprio token.
  • Stateless (menos hits em banco/cache para sessão).
  • Com RS256, você pode distribuir a chave pública e girar chaves com JWKS.

Contras

  • Mais complexo (giro de chaves, relógio/clock skew, validação de audience/issuer).
  • Se assinado com segredo compartilhado (HS256), todos que têm o segredo conseguem emitir tokens (prefira RS256 entre organizações).
  • Revogação antes do exp exige lista de revogação/short TTL.

Use quando

  • Serviços multi-tenant/federados e SSO (IdP -> API).
  • Precisa escopos finos e TTL curto sem state no servidor.
  • Comunicação entre microsserviços via gateway/IdP (OAuth2/OIDC issuing JWTs).

Como implementar no N8N

  • Escolher o tipo de autenticação como: JWT Auth.
  • Criar uma credencial e preencher os dados de Secret. Esse valor deve ser o mesmo que foi usado para a geração do JWT com o payload das informações.

Pronto. Agora basta utilizar a autenticação correta no seu client que estiver chamando o Webhook, passando o dados da no header (cabeçalho) da requisição.

Bom, é isso. Essas configurações descritas acima já basta para que você tenha um pouco mais de segurança nos seus fluxos de automação. Mas não se limite apenas a elas, existem várias outras formas de melhorar a segurança dos seus endpoints dos Webhooks e todas elas sempre são bem-vindas para evitar surpresas desagradáveis no seu sistema.

Como boas práticas extras, deixo abaixo um checklist rápido:

  • Sempre utilizar HTTPS;
  • Rotacione segredos/chaves de tempos em tempos;
  • Prefira TTL curto para os tokens expirarem;
  • Em JWT: valide assinatura, iss, aud, exp, nbf; para clock skew, aceita +ou- 1 a 2 minutos;
  • Guarde segredos em um vault (Secrets Manager, KMS, etc);
  • Rate limit + idempotency keys em endpoints que criam recursos;
  • Para webhooks: verifique assinatura no corpo bruto, cheque timestamp, dedupe por event_id/jti.
  • Observabilidade: logue kid, iss, aud e o fingerprint do token, nunca o token inteiro.

Use e abuse de práticas de segurança.

Abraço,
Até a próxima.

Previous Article

YouTube - (Bonus) Adicionar o EvolutionAPI via Docker para funcionar nas automações N8N

Write a Comment

Leave a Comment

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Receba Nossa Newsletter

Assine nossa newsletter por e-mail para receber as postagens mais recentes diretamente na sua caixa de entrada.
Inspiração pura, zero spam ✨