FixVibe

// docs / baas security / clerk hardening

Чек-лист безопасности Clerk: 20 пунктов

Clerk управляет аутентификацией, сеансами и организациями для вашего приложения — это означает, что неправильно настроенная интеграция Clerk — это обход аутентификации, вектор фиксации сеанса или путь утечки организации. Этот чек-лист — это аудит из 20 пунктов по ключам, конфигурации сеанса, webhook, организациям, JWT-шаблонам и текущему мониторингу. ИИ-инструменты кодирования быстро настраивают Clerk с разумными значениями по умолчанию; этот список ловит пункты, которые они оставляют на столе.

О том, почему неправильные настройки на уровне аутентификации являются слабым местом для ИИ-инструментов, см. Почему ИИ-инструменты кодирования оставляют пробелы в безопасности. О параллельном чек-листе для Auth0 см. Чек-лист безопасности Auth0.

Ключи окружения и список разрешённых источников

Clerk выдаёт два разных ключа на проект. Их смешивание или утечка — это первый режим отказа.

  1. Используйте публикуемый ключ (pk_live_* в продакшене, pk_test_* в разработке) в браузере; используйте секретный ключ (sk_live_* / sk_test_*) только на сервере. Публикуемый ключ безопасен в NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY; секретный ключ никогда не должен иметь публичного env-префикса и никогда не должен появляться в клиентском компоненте.
  2. Убедитесь, что производственное приложение использует pk_live_*, а не pk_test_*. Тестовые экземпляры позволяют непроверенные адреса электронной почты и отключённый MFA — выпуск тестового режима в продакшен — это обход аутентификации.
  3. Настройте разрешённые источники в Панели Clerk. Settings → Domains → Allowed origins должны точно перечислять ваш производственный домен. Пустые списки или списки с подстановочными источниками позволяют злоумышленникам создавать мошеннические интерфейсы Clerk, которые общаются с вашим бэкендом.
  4. Ротируйте секретный ключ при любом уходе или подозрении на утечку. Панель → API Keys → Reset. Старый ключ недействителен; перед ротацией повторно разверните серверный код с новым значением.

Конфигурация сеанса

Срок действия сеанса и тайм-аут бездействия — это разница между тем, что украденный сеанс является инцидентом на 10 минут, а не на 30 дней.

  1. Установите тайм-аут бездействия сеанса 30 минут или меньше для SaaS-приложений, обрабатывающих конфиденциальные данные. Панель → Sessions → Inactivity timeout. Приложения банковского класса должны использовать 5-10 минут; стандартные SaaS 30-60 минут; потребительские приложения 1-7 дней. По умолчанию 7 дней.
  2. Включите отзыв сеанса при изменении пароля, изменении электронной почты и регистрации MFA. Панель → Sessions → Revoke on. Это инициированные пользователем события безопасности; существующие сеансы на других устройствах должны быть прекращены.
  3. Проверяйте сеансы на стороне сервера в каждом защищённом маршруте, а не только при входе. В Next.js: const { userId } = await auth(); в серверном компоненте / маршруте API читает JWT из cookie и проверяет его. Никогда не доверяйте проверке только cookie.
  4. Установите SameSite=Lax (по умолчанию) или Strict на cookie сеанса. Проверьте в DevTools → Application → Cookies. SameSite=None — это вектор CSRF — никогда не используйте его, если только вы явно не настроили кросс-доменную аутентификацию.

Проверка webhook

Webhook-и Clerk срабатывают на событиях жизненного цикла пользователя (created, updated, deleted, session.ended). Они являются механизмом синхронизации для вашей базы данных — а поддельный webhook — это примитив записи в базу данных.

  1. Проверяйте подпись Svix на каждом webhook. Webhook-и Clerk подписаны Svix. Используйте new Webhook(secret).verify(body, headers). Отклоняйте с 401, если проверка не удалась.
  2. Храните секрет webhook в переменной окружения, никогда в коде. Секрет ротируется при каждой повторной генерации в Панели — ваше развёртывание должно читать его из env, а не из константы.
  3. Идемпотентность на каждом обработчике. Доставка webhook может повторяться. Используйте заголовок svix-id как первичный ключ в таблице webhook_events для дедупликации. Оберните изменение состояния и вставку идемпотентности в одну и ту же транзакцию.
  4. На user.deleted жёстко удаляйте или анонимизируйте PII в течение 24 часов. GDPR / CCPA требуют этого. Проверьте путь удаления: какие таблицы содержат данные этого пользователя? Используйте FK ON DELETE CASCADE, где можете.

Организации и разрешения

Если вы используете Clerk Organizations, граница организации — это ваша изоляция арендаторов. Каждый серверный запрос должен фильтроваться по ней.

  1. В каждом маршруте API читайте и userId, и orgId из auth() и фильтруйте запросы базы данных по обоим. WHERE org_id = $orgId AND user_id = $userId. Никогда не доверяйте org_id из тела запроса.
  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. Протестируйте кросс-организационную изоляцию с двумя реальными аккаунтами организаций. Создайте организацию A, заполните данные, войдите в организацию B в другом браузере, попытайтесь прочитать данные организации A через API. Ответ должен быть 403 или 404.

JWT-шаблоны и внешние интеграции

JWT-шаблоны передают идентификацию Clerk в Supabase, Firebase и другие нижестоящие сервисы. Неправильно настроенные шаблоны чрезмерно делятся утверждениями или раскрывают данные, которые вы не хотели.

  1. Для каждого JWT-шаблона перечислите каждое утверждение и подтвердите, что оно необходимо. Панель → JWT Templates. Шаблон, который отправляет email и phone в Supabase, раскрывает PII любому, кто читает JWT в браузере.
  2. Установите короткий срок действия на JWT-шаблонах, используемых для клиентских нижестоящих вызовов. 60 секунд для запросов нижестоящего API — это стандарт. Долговечные JWT крадутся и повторно воспроизводятся.
  3. Проверяйте утверждение audience (aud) на принимающей стороне. Supabase, Firebase и т. д. должны проверять, что aud соответствует ожидаемому идентификатору сервиса. Без этого JWT, выданный для сервиса A, может аутентифицироваться в сервисе B.

Операционный мониторинг

Аутентификация — это самый высокосигнальный источник журналов, который у вас есть. Наблюдайте за ней.

  1. Предупреждайте о всплесках неудачных входов на IP / аккаунт. Скорость отказов в 50 раз нормальной — это атака подстановки учётных данных. Clerk испускает эти события в webhook; направляйте их в ваш SIEM.
  2. Ежеквартальный обзор смещения настроек сеанса и экземпляра. Значения по умолчанию меняются по мере обновления Clerk; «старые конфигурации» тихо становятся неправильными со временем. Сравните JSON-экспорт Панели с вашей последней известной хорошей копией.

Следующие шаги

Запустите сканирование FixVibe против вашего производственного URL — проверка baas.clerk-auth0 помечает публикуемые ключи Clerk, тестовые ключи в продакшене и пакетные секретные ключи. Об эквивалентном чек-листе для Auth0 см. Чек-лист безопасности Auth0. Для общего обзора поставщиков BaaS прочитайте Сканер неправильных настроек BaaS.

// сканируйте вашу baas-поверхность

Найдите открытую таблицу раньше, чем это сделает кто-то другой.

Введите производственный URL. FixVibe перечислит поставщиков BaaS, с которыми взаимодействует ваше приложение, снимет отпечатки с их публичных конечных точек и сообщит, что неавторизованный клиент может прочитать или записать. Бесплатно, без установки, без карты.

  • Бесплатный тариф — 3 сканирования в месяц, без карты при регистрации.
  • Пассивное снятие отпечатков BaaS — не требуется проверка владения доменом.
  • Supabase, Firebase, Clerk, Auth0, Appwrite и другие.
  • Подсказки исправления ИИ для каждой находки — вставьте обратно в Cursor / Claude Code.
Чек-лист безопасности Clerk: 20 пунктов — Docs · FixVibe