// docs / baas security / clerk hardening
רשימת בדיקה לאבטחת Clerk: 20 פריטים
Clerk מטפל באימות, sessions, וארגונים עבור האפליקציה שלך — מה שאומר שאינטגרציית Clerk שגויה היא עקיפת אימות, וקטור session-fixation, או נתיב הדלפת ארגון. הרשימה הזו היא audit של 20 פריטים על פני מפתחות, תצורת session, webhooks, ארגונים, תבניות JWT, וניטור שוטף. כלי קוד מבוססי-AI מחברים את Clerk במהירות עם ברירות מחדל הגיוניות; הרשימה הזו תופסת את הפריטים שהם משאירים על השולחן.
לרקע על מדוע תצורות שגויות של שכבת אימות הן נקודת חולשה של כלי AI, ראה מדוע כלי קוד מבוססי-AI משאירים פערי אבטחה. לרשימת הבדיקה המקבילה ב-Auth0, ראה רשימת בדיקה לאבטחת Auth0.
מפתחות סביבה ורשימת היתר של מקורות
Clerk מנפיק שני מפתחות שונים לכל פרויקט. ערבוב או הדלפה שלהם הוא מצב הכשל הראשון.
- השתמש במפתח publishable (
pk_live_*בייצור,pk_test_*בפיתוח) בדפדפן; השתמש במפתח הסוד (sk_live_*/sk_test_*) בשרת בלבד. מפתח ה-publishable בטוח ב-NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY; מפתח הסוד לעולם לא חייב לשאת קידומת env ציבורית ולעולם לא חייב להופיע ברכיב לקוח. - אמת שאפליקציית הייצור משתמשת ב-
pk_live_*, לא ב-pk_test_*. מופעי בדיקה מתירים כתובות אימייל לא-מאומתות ו-MFA מושבת — משלוח מצב בדיקה לייצור הוא עקיפת אימות. - הגדר את המקורות המותרים ב-Dashboard של Clerk. Settings → Domains → Allowed origins חייב לרשום את דומיין הייצור שלך במדויק. רשימות מקור ריקות או עם wildcard מאפשרות לתוקפים ליצור frontends של Clerk סוררים שמדברים עם ה-backend שלך.
- סבב את מפתח הסוד בכל עזיבה או חשד בהדלפה. Dashboard → API Keys → Reset. המפתח הישן מבוטל; פרוס מחדש קוד צד-שרת עם הערך החדש לפני הסבב.
תצורת session
תפוגות session ו-timeouts של חוסר פעילות הם ההבדל בין session גנוב שהוא תקרית של 10 דקות לבין תקרית של 30 ימים.
- הגדר timeout של חוסר פעילות session ל-30 דקות או פחות עבור אפליקציות SaaS שמטפלות בנתונים רגישים. Dashboard → Sessions → Inactivity timeout. אפליקציות בדרגת בנקאות צריכות להשתמש ב-5-10 דקות; SaaS סטנדרטי 30-60 דקות; אפליקציות צרכניות 1-7 ימים. ברירת המחדל היא 7 ימים.
- הפעל ביטול session בשינוי סיסמה, שינוי אימייל, ורישום MFA. Dashboard → Sessions → Revoke on. אלה אירועי אבטחה שיזמו המשתמשים; sessions קיימים במכשירים אחרים צריכים להיהרג.
- אמת sessions בצד-שרת על כל נתיב מוגן, לא רק בכניסה. ב-Next.js:
const { userId } = await auth();ברכיב שרת / נתיב API קורא את ה-JWT מה-cookie ומאמת אותו. לעולם אל תסמוך על בדיקת cookie-בלבד. - הגדר
SameSite=Lax(ברירת מחדל) אוStrictב-cookie של ה-session. אמת ב-DevTools → Application → Cookies.SameSite=Noneהוא וקטור CSRF — לעולם אל תשתמש בו אלא אם הגדרת במפורש הגדרת אימות חוצת-דומיינים.
אימות webhook
Webhooks של Clerk מופעלים באירועי מחזור-חיים של משתמש (created, updated, deleted, session.ended). הם מנגנון הסנכרון עבור מסד הנתונים שלך — ו-webhook מזויף הוא פרימיטיב לכתיבה למסד נתונים.
- אמת את חתימת ה-Svix על כל webhook. Webhooks של Clerk חתומים על-ידי Svix. השתמש ב-
new Webhook(secret).verify(body, headers). דחה עם401אם האימות נכשל. - אחסן את סוד ה-webhook במשתנה סביבה, לעולם לא בקוד. הסוד מסתובב בכל יצירה מחדש ב-Dashboard — ה-deploy שלך חייב לקרוא אותו מ-env, לא מקבוע.
- אידמפוטנטיות על כל handler. משלוחי webhook יכולים לחזור. השתמש ב-header
svix-idכמפתח ראשי בטבלתwebhook_eventsכדי לבצע dedupe. עטוף את שינוי המצב ואת הוספת האידמפוטנטיות באותה טרנזקציה. - ב-
user.deleted, מחק קשיח או הפוך לאנונימי PII תוך 24 שעות. GDPR / CCPA דורשים זאת. בצע audit לנתיב המחיקה: אילו טבלאות מחזיקות את נתוני המשתמש הזה? השתמש ב-FK ON DELETE CASCADE היכן שאפשר.
ארגונים והרשאות
אם אתה משתמש ב-Clerk Organizations, גבול הארגון הוא בידוד הדייר שלך. כל שאילתה בצד-שרת חייבת לסנן לפיו.
- על כל נתיב API, קרא גם
userIdוגםorgIdמ-auth()וסנן שאילתות מסד נתונים לפי שניהם.WHERE org_id = $orgId AND user_id = $userId. לעולם אל תסמוך עלorg_idמגוף הבקשה. - <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.
- בדוק בידוד בין-ארגוני עם שני חשבונות ארגון אמיתיים. צור ארגון A, אכלס נתונים, היכנס לארגון B בדפדפן אחר, נסה לקרוא נתונים של ארגון A דרך ה-API. התגובה חייבת להיות
403או404.
תבניות JWT ואינטגרציות חיצוניות
תבניות JWT דוחפות זהות Clerk לתוך Supabase, Firebase, ושירותים אחרים במורד הזרם. תבניות מוגדרות שגוי משתפות יותר מדי claims או חושפות נתונים שלא התכוונת.
- עבור כל תבנית JWT, רשום כל claim ואשר שהוא נחוץ. Dashboard → JWT Templates. תבנית ששולחת
emailו-phoneל-Supabase חושפת PII לכל מי שקורא את ה-JWT בדפדפן. - הגדר תפוגה קצרה על תבניות JWT שמשמשות לקריאות במורד הזרם בצד-לקוח. 60 שניות עבור בקשות API במורד הזרם הוא הסטנדרט. JWTs ארוכי-חיים נגנבים ומשוחזרים.
- אמת את ה-claim של ה-audience (
aud) בצד המקבל. Supabase, Firebase וכו' צריכים לבדוק ש-audתואם למזהה השירות הצפוי. בלי זה, JWT שהונפק עבור שירות A יכול לאמת לשירות B.
ניטור תפעולי
אימות הוא מקור היומן בעל-האות הגבוה ביותר שיש לך. צפה בו.
- התרע על קפיצות-כניסה-כושלות לפי IP / לפי חשבון. פי 50 משיעור הכשל הרגיל הוא התקפת credential-stuffing. Clerk שולח את האירועים האלה ל-webhooks; נתב אותם ל-SIEM שלך.
- סקירה רבעונית של סחיפת הגדרות session ומופע. ברירות מחדל משתנות ככל ש-Clerk מתעדכן; "תצורות ישנות" הופכות בשקט לשגויות עם הזמן. בצע diff של ייצוא ה-JSON של ה-Dashboard מול העותק האחרון הידוע-כטוב שלך.
צעדים הבאים
הרץ סריקת FixVibe מול URL הייצור שלך — בדיקת baas.clerk-auth0 מסמנת מפתחות Clerk publishable, מפתחות בדיקה בייצור, ומפתחות סוד מצורפים. לרשימת הבדיקה המקבילה ב-Auth0, ראה רשימת בדיקה לאבטחת Auth0. לתצוגה מקיפה על פני ספקי BaaS, קרא סורק תצורות שגויות של BaaS.
