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. Используйте проверки ролей Clerk для привилегированных операций, а не булевы проверки на объекте пользователя. has({ role: 'org:admin' }) читает роль из проверенного JWT. Пользователь может подделать булево значение на устаревшем клиентском объекте; он не может подделать утверждение JWT.
  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-экспорт Панели с вашей последней известной хорошей копией.

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

Run a FixVibe scan against your production URL — it flags Clerk test keys in production and secret keys bundled into JavaScript. For the equivalent checklist on Auth0, see Auth0 security checklist. For the umbrella view across BaaS providers, read BaaS misconfiguration scanner.

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

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

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

  • Бесплатный тариф — 3 сканирования в месяц, без карты при регистрации.
  • Пассивное снятие отпечатков BaaS — не требуется проверка владения доменом.
  • Supabase, Firebase, Clerk, Auth0, Appwrite и другие.
  • Coding-agent prompts where code/config applies, plus provider-console steps for hosted BaaS fixes.
Чек-лист безопасности Clerk: 20 пунктов · FixVibe