// docs / baas security / clerk hardening
Clerk-Sicherheits-Checkliste: 20 Punkte
Clerk handhabt Auth, Sessions und Organisationen für deine App — was bedeutet, dass eine falsch konfigurierte Clerk-Integration ein Auth-Bypass, ein Session-Fixierungs-Vektor oder ein Org-Leakage-Pfad ist. Diese Checkliste ist ein 20-Punkte-Audit über Keys, Session-Konfig, Webhooks, Organisationen, JWT-Templates und laufendes Monitoring. KI-Coding-Tools verdrahten Clerk schnell mit vernünftigen Defaults; diese Liste fängt die Punkte, die sie auf dem Tisch liegen lassen.
Für Hintergrund, warum Fehlkonfigurationen auf Auth-Ebene eine Schwäche von KI-Tooling sind, siehe Warum KI-Coding-Tools Sicherheitslücken hinterlassen. Für die parallele Checkliste zu Auth0 siehe Auth0-Sicherheits-Checkliste.
Umgebungs-Keys und Origin-Allowlist
Clerk stellt zwei verschiedene Keys pro Projekt aus. Sie zu verwechseln oder zu leaken ist der erste Fehlermodus.
- Verwende den Publishable-Key (
pk_live_*in Produktion,pk_test_*in Dev) im Browser; verwende den Secret-Key (sk_live_*/sk_test_*) nur auf dem Server. Der Publishable-Key ist inNEXT_PUBLIC_CLERK_PUBLISHABLE_KEYsicher; der Secret-Key darf niemals ein öffentliches Env-Präfix tragen und niemals in einer Client-Komponente erscheinen. - Verifiziere, dass die Produktions-App
pk_live_*verwendet, nichtpk_test_*. Test-Instanzen erlauben unverifizierte E-Mail-Adressen und deaktiviertes MFA — Test-Mode in Produktion auszuliefern ist ein Auth-Bypass. - Konfiguriere die erlaubten Origins im Clerk-Dashboard. Settings → Domains → Allowed origins muss deine Produktionsdomain exakt listen. Leere oder Wildcard-Origin-Listen erlauben Angreifern, betrügerische Clerk-Frontends zu bauen, die mit deinem Backend sprechen.
- Rotiere den Secret-Key bei jedem Abgang oder Verdacht auf Leak. Dashboard → API Keys → Reset. Alter Key wird invalidiert; deploye serverseitigen Code mit dem neuen Wert vor der Rotation.
Session-Konfiguration
Session-Ablauf und Idle-Timeouts sind der Unterschied zwischen einer gestohlenen Session als 10-Minuten-Vorfall und einem 30-Tage-Vorfall.
- Setze den Session-Inaktivitäts-Timeout auf 30 Minuten oder weniger für SaaS-Apps, die sensible Daten verarbeiten. Dashboard → Sessions → Inactivity timeout. Bank-Tier-Apps sollten 5-10 Minuten verwenden; Standard-SaaS 30-60 Minuten; Consumer-Apps 1-7 Tage. Default ist 7 Tage.
- Aktiviere Session-Widerruf bei Passwortänderung, E-Mail-Änderung und MFA-Anmeldung. Dashboard → Sessions → Revoke on. Das sind nutzerinitiierte Sicherheitsereignisse; bestehende Sessions auf anderen Geräten sollten beendet werden.
- Verifiziere Sessions serverseitig auf jeder geschützten Route, nicht nur beim Sign-in. In Next.js:
const { userId } = await auth();in einer Server-Komponente / API-Route liest das JWT aus dem Cookie und validiert es. Vertraue niemals einer reinen Cookie-Prüfung. - Setze
SameSite=Lax(Default) oderStrictauf dem Session-Cookie. Verifiziere in DevTools → Application → Cookies.SameSite=Noneist ein CSRF-Vektor — verwende es nie, sofern du nicht explizit ein domainübergreifendes Auth-Setup konfiguriert hast.
Webhook-Verifizierung
Clerk-Webhooks feuern bei Lifecycle-Ereignissen des Nutzers (created, updated, deleted, session.ended). Sie sind der Synchronisierungsmechanismus für deine Datenbank — und ein gefälschter Webhook ist eine Schreib-Primitive für die Datenbank.
- Verifiziere die Svix-Signatur bei jedem Webhook. Clerk-Webhooks werden von Svix signiert. Nutze
new Webhook(secret).verify(body, headers). Lehne mit401ab, wenn die Verifizierung fehlschlägt. - Speichere das Webhook-Secret in einer Umgebungsvariablen, niemals im Code. Das Secret rotiert bei jeder Dashboard-Regeneration — dein Deploy muss es aus Env lesen, nicht aus einer Konstanten.
- Idempotenz in jedem Handler. Webhook-Zustellungen können sich wiederholen. Verwende den
svix-id-Header als Primärschlüssel in einerwebhook_events-Tabelle zur Deduplizierung. Wickle die Zustandsänderung und das Idempotenz-Insert in derselben Transaktion ab. - Bei
user.deletedPII binnen 24 Stunden hart löschen oder anonymisieren. GDPR / CCPA verlangen es. Auditiere den Löschpfad: welche Tabellen halten die Daten dieses Nutzers? Verwende FK ON DELETE CASCADE, wo möglich.
Organisationen und Berechtigungen
Wenn du Clerk Organizations nutzt, ist die Org-Grenze deine Tenant-Isolation. Jede serverseitige Query muss danach filtern.
- Lies auf jeder API-Route sowohl
userIdals auchorgIdausauth()und filtere Datenbank-Queries nach beidem.WHERE org_id = $orgId AND user_id = $userId. Vertraue nie einerorg_idaus dem Request-Body. - <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.
- Teste die Cross-Org-Isolation mit zwei echten Org-Konten. Erstelle Org A, befülle Daten, melde dich in Org B in einem anderen Browser an, versuche, die Daten von Org A über die API zu lesen. Antwort muss
403oder404sein.
JWT-Templates und externe Integrationen
JWT-Templates schieben Clerk-Identität in Supabase, Firebase und andere nachgelagerte Dienste. Falsch konfigurierte Templates teilen Claims über das Nötige hinaus oder legen Daten offen, die du nicht meintest.
- Liste für jedes JWT-Template jeden Claim auf und bestätige, dass er notwendig ist. Dashboard → JWT Templates. Ein Template, das
emailundphonean Supabase sendet, legt PII jedem offen, der das JWT im Browser liest. - Setze eine kurze Ablaufzeit auf JWT-Templates, die für clientseitige Downstream-Calls verwendet werden. 60 Sekunden für Downstream-API-Requests ist Standard. Längerlebige JWTs werden gestohlen und replayed.
- Verifiziere den Audience-Claim (
aud) auf der empfangenden Seite. Supabase, Firebase, etc. sollten prüfen, dassauddem erwarteten Service-Identifier entspricht. Ohne das kann ein für Service A ausgestelltes JWT sich gegen Service B authentifizieren.
Operatives Monitoring
Auth ist die signalstärkste Log-Quelle, die du hast. Beobachte sie.
- Alarmiere bei Spikes fehlgeschlagener Logins pro IP / pro Konto. Eine 50× normale Fehlerrate ist ein Credential-Stuffing-Angriff. Clerk emittiert diese Ereignisse an Webhooks; route sie an dein SIEM.
- Quartalsweise Überprüfung der Drift von Session- und Instance-Einstellungen. Defaults ändern sich mit Clerk-Updates; „alte Konfigurationen" werden mit der Zeit lautlos falsch. Vergleiche den JSON-Export des Dashboards mit deiner letzten bekannt-guten Kopie.
Nächste Schritte
Lass einen FixVibe-Scan gegen deine Produktions-URL laufen — der baas.clerk-auth0-Check markiert Clerk-Publishable-Keys, Test-Keys in Produktion und gebündelte Secret-Keys. Für die äquivalente Checkliste zu Auth0 siehe Auth0-Sicherheits-Checkliste. Für den Gesamtüberblick über BaaS-Anbieter lies BaaS-Fehlkonfigurations-Scanner.
