FixVibe

// docs / baas security / clerk hardening

Lista de comprobación de seguridad de Clerk: 20 elementos

Clerk gestiona autenticación, sesiones y organizaciones para tu aplicación — lo que significa que una integración mal configurada de Clerk es un bypass de autenticación, un vector de fijación de sesión o una ruta de fuga entre organizaciones. Esta lista de comprobación es una auditoría de 20 elementos a través de claves, configuración de sesión, webhooks, organizaciones, plantillas JWT y monitoreo continuo. Las herramientas de codificación con IA configuran Clerk rápidamente con valores predeterminados razonables; esta lista detecta los elementos que dejan sin hacer.

Para el contexto sobre por qué las configuraciones erróneas a nivel de autenticación son un punto débil de las herramientas de IA, consulta Por qué las herramientas de codificación con IA dejan huecos de seguridad. Para la lista de comprobación paralela en Auth0, consulta Lista de comprobación de seguridad de Auth0.

Claves de entorno y lista de orígenes permitidos

Clerk emite dos claves distintas por proyecto. Mezclarlas o filtrarlas es el primer modo de fallo.

  1. Usa la clave publicable (pk_live_* en producción, pk_test_* en dev) en el navegador; usa la clave secreta (sk_live_* / sk_test_*) solo en el servidor. La clave publicable es segura en NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY; la clave secreta nunca debe llevar un prefijo público de env y nunca debe aparecer en un componente cliente.
  2. Verifica que la aplicación de producción usa pk_live_*, no pk_test_*. Las instancias de prueba permiten direcciones de correo no verificadas y MFA deshabilitado — publicar en producción con el modo prueba es un bypass de autenticación.
  3. Configura los orígenes permitidos en el panel de Clerk. Configuración → Dominios → Orígenes permitidos debe listar tu dominio de producción exactamente. Listas de orígenes vacías o con comodín permiten a atacantes crear frontends fraudulentos de Clerk que hablen con tu backend.
  4. Rota la clave secreta ante cualquier salida o sospecha de fuga. Panel → Claves de API → Reset. La clave antigua queda invalidada; redespliega el código del lado del servidor con el nuevo valor antes de rotar.

Configuración de sesión

La caducidad de sesión y los tiempos de inactividad son la diferencia entre que una sesión robada sea un incidente de 10 minutos o uno de 30 días.

  1. Pon el tiempo de inactividad de sesión en 30 minutos o menos para aplicaciones SaaS que manejen datos sensibles. Panel → Sesiones → Tiempo de inactividad. Las aplicaciones tipo banca deberían usar 5-10 minutos; SaaS estándar 30-60 minutos; aplicaciones de consumo 1-7 días. El predeterminado es 7 días.
  2. Habilita la revocación de sesión al cambiar contraseña, cambiar correo y registrarse en MFA. Panel → Sesiones → Revocar al. Son eventos de seguridad iniciados por el usuario; las sesiones existentes en otros dispositivos deben ser eliminadas.
  3. Verifica las sesiones en el servidor en cada ruta protegida, no solo al iniciar sesión. En Next.js: const { userId } = await auth(); en un componente de servidor / ruta de API lee el JWT de la cookie y lo valida. Nunca confíes solo en una comprobación de cookie.
  4. Pon SameSite=Lax (predeterminado) o Strict en la cookie de sesión. Verifica en DevTools → Aplicación → Cookies. SameSite=None es un vector CSRF — nunca lo uses a menos que hayas configurado explícitamente una autenticación entre dominios.

Verificación de webhooks

Los webhooks de Clerk se disparan en eventos del ciclo de vida del usuario (creado, actualizado, eliminado, session.ended). Son el mecanismo de sincronización con tu base de datos — y un webhook falsificado es una primitiva de escritura en base de datos.

  1. Verifica la firma Svix en cada webhook. Los webhooks de Clerk los firma Svix. Usa new Webhook(secret).verify(body, headers). Rechaza con 401 si la verificación falla.
  2. Guarda el secreto del webhook en una variable de entorno, nunca en el código. El secreto rota cada vez que se regenera desde el panel — tu despliegue debe leerlo del entorno, no de una constante.
  3. Idempotencia en cada handler. Las entregas de webhooks pueden repetirse. Usa la cabecera svix-id como clave primaria en una tabla webhook_events para deduplicar. Envuelve el cambio de estado y la inserción de idempotencia en la misma transacción.
  4. En user.deleted, elimina o anonimiza el PII en menos de 24 horas. GDPR / CCPA lo requieren. Audita la ruta de borrado: ¿qué tablas tienen los datos de este usuario? Usa FK ON DELETE CASCADE donde puedas.

Organizaciones y permisos

Si usas Organizaciones de Clerk, el límite de organización es tu aislamiento de tenant. Cada consulta del lado del servidor debe filtrar por él.

  1. En cada ruta de API, lee tanto userId como orgId de auth() y filtra las consultas a la base de datos por ambos. WHERE org_id = $orgId AND user_id = $userId. Nunca confíes en un org_id del cuerpo de la solicitud.
  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. Prueba el aislamiento entre organizaciones con dos cuentas reales. Crea Org A, popula datos, inicia sesión en Org B en otro navegador, intenta leer los datos de Org A vía la API. La respuesta debe ser 403 o 404.

Plantillas JWT e integraciones externas

Las plantillas JWT empujan la identidad de Clerk a Supabase, Firebase y otros servicios downstream. Las plantillas mal configuradas comparten claims de más o exponen datos que no querías.

  1. Para cada plantilla JWT, lista cada claim y confirma que es necesario. Panel → Plantillas JWT. Una plantilla que envía email y phone a Supabase expone PII a cualquiera que lea el JWT en el navegador.
  2. Pon una caducidad corta a las plantillas JWT usadas para llamadas downstream del lado del cliente. 60 segundos para solicitudes de API downstream es el estándar. Los JWT de vida más larga se roban y reproducen.
  3. Verifica el claim de audiencia (aud) en el lado receptor. Supabase, Firebase, etc. deben comprobar que aud coincide con el identificador de servicio esperado. Sin esto, un JWT emitido para el servicio A puede autenticarse en el servicio B.

Monitoreo operativo

La autenticación es la fuente de logs de mayor señal que tienes. Vigílala.

  1. Alerta sobre picos de inicios de sesión fallidos por IP / por cuenta. Una tasa de fallo 50× la normal es un ataque de credential stuffing. Clerk emite estos eventos a webhooks; envíalos a tu SIEM.
  2. Revisa trimestralmente la deriva de los ajustes de sesión e instancia. Los valores predeterminados cambian con las actualizaciones de Clerk; las "configuraciones antiguas" se vuelven silenciosamente incorrectas con el tiempo. Compara la exportación JSON del panel con tu última copia conocida-buena.

Próximos pasos

Ejecuta un escaneo de FixVibe contra tu URL de producción — la verificación baas.clerk-auth0 marca claves publicables de Clerk, claves de prueba en producción y claves secretas incrustadas. Para la lista de comprobación equivalente en Auth0, consulta Lista de comprobación de seguridad de Auth0. Para la vista general en proveedores BaaS, lee Escáner de configuraciones erróneas de BaaS.

// escanea tu superficie de baas

Encuentra la tabla abierta antes que otra persona lo haga.

Introduce una URL de producción. FixVibe enumera los proveedores de BaaS con los que habla tu aplicación, identifica sus endpoints públicos y reporta lo que un cliente no autenticado puede leer o escribir. Gratis, sin instalación, sin tarjeta.

  • Plan gratuito — 3 escaneos al mes, sin tarjeta de registro.
  • Identificación pasiva de BaaS — no se requiere verificación de dominio.
  • Supabase, Firebase, Clerk, Auth0, Appwrite y más.
  • Prompts de corrección con IA en cada hallazgo — pégalos de vuelta en Cursor / Claude Code.
Lista de comprobación de seguridad de Clerk: 20 elementos — Docs · FixVibe