FixVibe

// docs / baas security / clerk hardening

Checklist de segurança Clerk: 20 itens

O Clerk lida com auth, sessões e organizações para seu app — o que significa que uma integração Clerk mal configurada é um bypass de auth, um vetor de fixação de sessão ou um caminho de vazamento entre orgs. Este checklist é uma auditoria de 20 itens através de chaves, configuração de sessão, webhooks, organizações, templates JWT e monitoramento contínuo. Ferramentas de codificação com IA fazem o cabeamento do Clerk rapidamente com padrões sensatos; esta lista pega os itens que deixam na mesa.

Para contexto sobre por que configurações incorretas em nível de auth são um ponto fraco das ferramentas de IA, veja Por que ferramentas de codificação com IA deixam lacunas de segurança. Para o checklist paralelo no Auth0, veja Checklist de segurança Auth0.

Chaves de ambiente e allowlist de origem

O Clerk emite duas chaves distintas por projeto. Misturá-las ou vazá-las é o primeiro modo de falha.

  1. Use a chave publicável (pk_live_* em produção, pk_test_* em dev) no navegador; use a chave secreta (sk_live_* / sk_test_*) apenas no servidor. A chave publicável é segura em NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY; a chave secreta nunca pode carregar um prefixo env público e nunca pode aparecer em um componente cliente.
  2. Verifique que o app de produção usa pk_live_*, não pk_test_*. Instâncias de teste permitem endereços de e-mail não verificados e MFA desabilitado — publicar modo de teste em produção é um bypass de auth.
  3. Configure as origens permitidas no painel do Clerk. Settings → Domains → Allowed origins deve listar seu domínio de produção exatamente. Listas de origens vazias ou com wildcard deixam atacantes criar frontends Clerk falsos que falam com seu backend.
  4. Rotacione a chave secreta em qualquer saída ou vazamento suspeito. Painel → API Keys → Reset. Chave antiga é invalidada; republique o código do lado do servidor com o novo valor antes de rotacionar.

Configuração de sessão

Expiração de sessão e timeouts de inatividade são a diferença entre uma sessão roubada ser um incidente de 10 minutos e um de 30 dias.

  1. Defina timeout de inatividade de sessão em 30 minutos ou menos para apps SaaS que lidam com dados sensíveis. Painel → Sessions → Inactivity timeout. Apps de nível bancário devem usar 5-10 minutos; SaaS padrão 30-60 minutos; apps de consumo 1-7 dias. Padrão é 7 dias.
  2. Habilite revogação de sessão em mudança de senha, mudança de e-mail e inscrição em MFA. Painel → Sessions → Revoke on. São eventos de segurança iniciados pelo usuário; sessões existentes em outros dispositivos devem ser mortas.
  3. Verifique sessões do lado do servidor em cada rota protegida, não apenas no sign-in. No Next.js: const { userId } = await auth(); em um componente de servidor / rota de API lê o JWT do cookie e o valida. Nunca confie em uma verificação só de cookie.
  4. Defina SameSite=Lax (padrão) ou Strict no cookie de sessão. Verifique em DevTools → Application → Cookies. SameSite=None é um vetor CSRF — nunca use a menos que você tenha explicitamente configurado uma auth entre domínios.

Verificação de webhooks

Webhooks do Clerk disparam em eventos de ciclo de vida de usuário (criado, atualizado, deletado, session.ended). São o mecanismo de sincronização para seu banco — e um webhook forjado é uma primitiva de escrita em banco.

  1. Verifique a assinatura Svix em cada webhook. Webhooks do Clerk são assinados pelo Svix. Use new Webhook(secret).verify(body, headers). Rejeite com 401 se a verificação falhar.
  2. Armazene o segredo do webhook em uma variável de ambiente, nunca no código. O segredo é rotacionado a cada regeneração no painel — seu deploy deve lê-lo do env, não de uma constante.
  3. Idempotência em cada handler. Entregas de webhook podem se repetir. Use o cabeçalho svix-id como chave primária em uma tabela webhook_events para deduplicar. Envolva a mudança de estado e o insert de idempotência na mesma transação.
  4. Em user.deleted, delete ou anonimize PII em 24 horas. LGPD/GDPR / CCPA exigem. Audite o caminho de exclusão: quais tabelas têm os dados deste usuário? Use FK ON DELETE CASCADE onde puder.

Organizações e permissões

Se você usa Clerk Organizations, a fronteira de org é seu isolamento de tenant. Cada consulta do lado do servidor deve filtrar por ela.

  1. Em cada rota de API, leia tanto userId quanto orgId de auth() e filtre consultas de banco por ambos. WHERE org_id = $orgId AND user_id = $userId. Nunca confie em um org_id do corpo da requisição.
  2. <strong>Use Clerk role checks for privileged operations, not boolean checks against the user object.</strong> <code>has({ role: 'org:admin' })</code> reads the role from the verified JWT. A user can spoof a boolean on a stale client object; they cannot spoof a JWT claim.
  3. Teste isolamento entre orgs com duas contas de org reais. Crie Org A, popule dados, entre na Org B em outro navegador, tente ler os dados da Org A via API. A resposta deve ser 403 ou 404.

Templates JWT e integrações externas

Templates JWT empurram identidade Clerk para Supabase, Firebase e outros serviços downstream. Templates mal configurados compartilham claims demais ou expõem dados que você não queria.

  1. Para cada template JWT, liste cada claim e confirme que é necessário. Painel → JWT Templates. Um template que envia email e phone para o Supabase expõe PII a qualquer um que ler o JWT no navegador.
  2. Defina expiração curta em templates JWT usados para chamadas downstream do lado do cliente. 60 segundos para requisições de API downstream é o padrão. JWTs de vida mais longa são roubados e reproduzidos.
  3. Verifique o claim de audiência (aud) no lado receptor. Supabase, Firebase, etc. devem verificar que aud corresponde ao identificador de serviço esperado. Sem isso, um JWT emitido para o serviço A pode se autenticar no serviço B.

Monitoramento operacional

Auth é a fonte de logs de maior sinal que você tem. Observe-a.

  1. Alerte em picos de logins falhos por IP / por conta. Uma taxa de falha 50× a normal é um ataque de credential stuffing. O Clerk emite esses eventos para webhooks; roteie para seu SIEM.
  2. Revisão trimestral da deriva de configurações de sessão e instância. Padrões mudam à medida que o Clerk atualiza; "configurações antigas" se tornam silenciosamente erradas com o tempo. Compare a exportação JSON do painel com sua última cópia conhecida-boa.

Próximos passos

Rode uma varredura do FixVibe contra sua URL de produção — a verificação baas.clerk-auth0 sinaliza chaves publicáveis do Clerk, chaves de teste em produção e chaves secretas no bundle. Para o checklist equivalente no Auth0, veja Checklist de segurança Auth0. Para a visão geral sobre provedores BaaS, leia Scanner de configurações incorretas de BaaS.

// varra sua superfície baas

Encontre a tabela aberta antes que outra pessoa o faça.

Coloque uma URL de produção. O FixVibe enumera os provedores BaaS com que seu app conversa, identifica seus endpoints públicos e relata o que um cliente não autenticado pode ler ou escrever. Grátis, sem instalação, sem cartão.

  • Plano gratuito — 3 varreduras/mês, sem cartão de cadastro.
  • Identificação BaaS passiva — sem necessidade de verificação de domínio.
  • Supabase, Firebase, Clerk, Auth0, Appwrite e mais.
  • Prompts de correção com IA em cada achado — cole de volta no Cursor / Claude Code.
Rodar varredura BaaS gratuita

sem necessidade de cadastro

Checklist de segurança Clerk: 20 itens — Docs · FixVibe