FixVibe

// docs / security guides / pre-ship checklist

Чек-лист безопасности vibe coding: 51 пункта перед запуском

Практичный, поэтапный контрольный список для приложений, созданных с помощью Cursor, Claude Code, Lovable, Bolt, v0, Replit и Windsurf. Каждый пункт можно выполнить менее чем за пять минут. Проходите его перед запуском в производство, а затем еще раз перед каждым крупным выпуском. Элементы сгруппированы в семь категорий — секреты, база данных, аутентификация, заголовки, сторонние, развертывание, мониторинг — и помечены фазой развертывания, к которой они относятся.

PRE = pre-deploy (audit your source). DEPLOY = at deploy time. POST = post-deploy verification.

Секреты и ключи API (8 шт.)

Жестко закодированные клавиши — самая распространенная находка в приложениях с Vibe-кодом. Восемь вещей, которые помогут их избежать:

  1. PRE — Audit NEXT_PUBLIC_ env vars. Все, что имеет префикс NEXT_PUBLIC_, поставляется в составе клиентских пакетов. Если это ключ Supabase service_role (декодируется в JWT с "role":"service_role"), удалите его и направьте через серверный клиент (src/lib/supabase/service.ts с import 'server-only').
  2. PRE — Grep for hardcoded provider keys. Источник поиска для sk_live_, pk_live_, STRIPE_SECRET, sk-ant-, sk-, AIza, AKIA и JWT-ищущих строк (eyJ). Переместите каждое попадание в .env.local и используйте ссылку только через process.env.* на стороне сервера.
  3. PRE — Verify .gitignore. Подтвердите .env*.local, .npmrc, .yarnrc, и все файлы учетных данных, относящиеся к конкретному поставщику, игнорируются. Запустите git ls-files по шаблонам вашего провайдера, чтобы найти что-нибудь уже зафиксированное.
  4. PRE — Scan the built bundle. Запустите npm run build, затем grep .next/static и любые выходные данные dist/ для тех же шаблонов. Если ключ достигает пакета, у разработчика никогда не было четкого разделения окружения.
  5. DEPLOY — Set secrets per environment. Vercel: Настройки → Переменные среды, область действия каждой — Production/Предварительный просмотр/Разработка. Никогда не делитесь sk_live_* с помощью среды предварительного просмотра. Используйте зашифрованное хранилище env-var Vercel, а не встроенные секреты рабочего процесса.
  6. DEPLOY — Disable build-log secret echo. Некоторые CI конфиги echo переменные окружения во время сборки. Проверьте свои рабочие процессы vercel.json, GitHub Actions или Cloudflare Pages на наличие любых echo $SECRET, которые могут отправить значение в общедоступные журналы сборки.
  7. POST — Run a passive scan. FixVibe Free уровня охватывает это: вставьте развернутый URL, подождите ~20 секунд, найдите результаты secrets.*. Проверка Secrets in JavaScript Bundles выявляет ключи, которые попали в localStorage или sessionStorage из-за неправильного использования SDK.
  8. POST — Rotate any key that ever shipped. Если ключ находился в общедоступном пакете хотя бы несколько минут, считайте его скомпрометированным. Ротация ключей сервисной роли Supabase через панель управления, повторное создание ограниченных ключей Stripe, отзыв ключей Anthropic/OpenAI/Google через их консоли.

Контроль доступа к базе данных: правила RLS и Firestore (6 шт.)

BaaS значения по умолчанию намеренно являются разрешающими, поэтому первое руководство работает. Production требует четкой политики.

  1. PRE — Enable RLS on every public.* table. In Supabase: each table needs ALTER TABLE ... ENABLE ROW LEVEL SECURITY plus explicit policies for each role. RLS is what stops the anon and authenticated API roles; FORCE ROW LEVEL SECURITY only extends it to the table owner and is optional defence in depth.
  2. PRE — Write a policy per (table, role, action). Минимум: политика SELECT, которая присоединяется auth.uid(). Лучше: отдельные политики INSERT / UPDATE / DELETE, чтобы UPDATE не мог переправить user_id изменения, которые перенаправляют владельца.
  3. PRE — Replace default Firebase rules. Правила тестового режима по умолчанию читаются как allow read, write: if true;. Замените правилами с привязкой к аутентификации для каждой коллекции: match /users/{userId} на allow read, write: if request.auth.uid == userId;.
  4. PRE — Lint migrations in CI. Перед слиянием запустите supabase db lint или его эквивалент. CI должен завершить сборку неудачно, если у какого-либо CREATE TABLE public.* отсутствует соответствующая политика RLS.
  5. DEPLOY — Confirm RLS survived deploy. Повторно проверьте в Supabase Studio после развертывания: Таблицы → каждая строка → переключатель RLS — ON. Production базы данных иногда опережает миграцию файлов политик; убедитесь, что политика активна.
  6. POST — Run an active scan against a verified domain. Активная проверка Supabase Row-Level Security записывает в крошечную начальную строку с помощью ключа anon и сообщает, если запись прошла успешно — i.e. RLS на самом деле не обеспечивает соблюдения.

Аутентификация и сеансы (7 позиций)

Ошибки аутентификации в приложениях с кодом AI-, как правило, незаметны: ошибка при проверке токена на единицу, пропущенный флаг HttpOnly, getSession() там, где должен быть getUser().

  1. PRE — Replace getSession() with getUser(). getSession() читает файл cookie и доверяет ему; getUser() проверяет серверную часть Supabase. На маршрутах сервера всегда используйте getUser().
  2. PRE — Confirm token expiry. Токены Magic-link, токены сброса пароля и проверки электронной почты должны иметь срок действия, определяемый сервером. Срок действия магических ссылок Supabase по умолчанию истекает через 1 час — не заменяйте это значение на большее число без реальной причины.
  3. PRE — Verify JWT aud and exp. Если вы где-либо декодируете токены вручную, проверьте оба утверждения. Лучше: используйте getUser() SDK, который сделает это за вас.
  4. PRE — Audit cookie flags. Пользовательские файлы cookie сеанса должны иметь номер Secure; HttpOnly; SameSite=Lax (или Strict для потоков, отличных от OAuth). В localStorage нет материалов сессии.
  5. PRE — Validate the next redirect param. Параметр запроса next после входа в систему должен начинаться с /, а не // (открыть перенаправление на attacker.example). Отклонить все остальное на стороне сервера.
  6. POST — Test logout. Войдите, выйдите из системы, проверьте файлы cookie (Инструменты разработчика → Приложение → Файлы cookie). Файл cookie сеанса должен быть удален в том же ответе. Если это сохраняется, обработчик выхода из системы фактически не разрушает состояние на стороне сервера.
  7. POST — Active probe. Auth Flow Defects и Account Enumeration проверяют нарушенные границы аутентификации — разные ответы на «пользователь существует» и «неправильный пароль», отсутствие ограничения скорости при входе в систему, неподписанные токены сброса.

HTTP заголовки безопасности и политика безопасности контента (6 элементов)

Заголовки — это самая дешевая защита во всем конвейере, и они чаще всего пропускаются кодегеном.

  1. PRE — Ship a real CSP. Минимум: script-src 'nonce-{NONCE}' 'strict-dynamic'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'. Нет 'unsafe-inline' в script-src. Next.js автоматически применяет nonce, когда промежуточное ПО устанавливает заголовок запроса x-nonce.
  2. PRE — Add the legacy three. X-Content-Type-Options: nosniff, X-Frame-Options: DENY (или полагаться только на CSP frame-ancestors), Strict-Transport-Security: max-age=31536000; includeSubDomains.
  3. PRE — Tighten Referrer-Policy. Значение по умолчанию strict-origin-when-cross-origin подходит для большинства приложений. Не отправляйте unsafe-url или вообще не отправляйте заголовок.
  4. PRE — Replace Access-Control-Allow-Origin: *. Ждем этого. Замените явным списком разрешений происхождения. Где бы это ни было * рядом с credentials: include, браузер отклонит запрос, но это не защита от неправильно настроенного бэкэнда.
  5. DEPLOY — Verify headers post-deploy. Откройте DevTools → Сеть → щелкните корневой документ → вкладка «Заголовки». CSP, HSTS, X-Frame-Options, X-Content-Type-Options должны присутствовать. CSP не должно содержать 'unsafe-inline' в script-src.
  6. POST — Run HTTP Security Headers. Пассивная проверка заголовка сообщает о каждом отсутствующем заголовке с инструкциями по исправлению на платформе развертывания (Vercel vercel.json, Cloudflare Pages _headers, Netlify _headers, Next.js промежуточное программное обеспечение).

Сторонние интеграции и APIs (5 шт.)

Каждый сценарий, который вы включаете, представляет собой исключение CSP и потенциальную возможность использования в цепочке поставок. Относитесь к третьим лицам как к границе вашего доверия.

  1. PRE — Reverse-proxy analytics where possible. PostHog, Правдоподобно, все умами поддерживают проксирование через ваш собственный домен (e.g. /api/posthog). Это сохраняет connect-src того же источника и выдерживает блокировку рекламы.
  2. PRE — CSP-allowlist the rest. Для Google Analytics, Stripe.js, Sentry, Intercom, GTM и т. д. добавьте происхождение каждого поставщика в соответствующую директиву CSP (script-src для загрузчиков, connect-src для телеметрии, frame-src для iframe, img-src для пикселей).
  3. PRE — Use Stripe Checkout, not raw card forms. Stripe Checkout — это перенаправление верхнего уровня; для сценария не требуется запись CSP. Хостинговая поверхность PCI полностью находится в домене Stripe. Делайте свой собственный только в том случае, если у вас есть веская причина.
  4. PRE — Lock package-lock.json in CI. Запускайте npm ci (не npm install) в производственных сборках. Проверяйте зависимости с помощью npm audit или Snyk перед каждым выпуском.
  5. POST — Watch Technology Fingerprinting. Пассивное обнаружение технологического стека обнаруживает версии библиотеки, видимые сканеру. Если вы отправляете EOL React, jQuery или Bootstrap, FixVibe помечает его и ссылается на известные CVE.

Гигиена развертывания и инфраструктура (8 позиций)

То, как вы развертываете, имеет такое же значение, как и то, что вы развертываете. AI-приложения с кодом особенно выигрывают от явного усиления защиты при развертывании.

  1. PRE — Disable x-powered-by. В next.config.js: poweredByHeader: false. Удаляет бесплатный сигнал раскрытия версии.
  2. PRE — Confirm middleware lives at src/middleware.ts. В структуре каталога src/ Next.js игнорирует корневой уровень middleware.ts. Неуместное промежуточное программное обеспечение молча не может установить CSP/заголовки аутентификации/ограничения скорости.
  3. PRE — Sanity-check Vercel deployment protection. Proвыпуск должен быть публичным; Предварительный просмотр должен быть защищен паролем или доступен только членам организации. Vercel-Specific Exposure сообщает о поверхности.
  4. PRE — Block dotfile and config probes at the edge. Добавьте правило перезаписи или запрета для шаблонов /.env, /.git/*, /.aws/*, /.next/trace. Vercel по умолчанию возвращает 403 для многих из них; перекрестная проверка.
  5. DEPLOY — Separate environments. Production, Предварительный просмотр, Разработка. У каждого свой набор секретов. Живые ключи никогда не достигают предварительного просмотра, тестовый режим Stripe никогда не достигает Production.
  6. Планы DEPLOY — Enable Vercel Web Application Firewall. Pro и Enterprise включают WAF с управляемыми правилами. Cloudflare Pages имеет режим боя с ботами. И то, и другое снижает злоупотребление автоматическим сканером и нагрузку на распыление паролей.
  7. POST — Verify TLS configuration. SSL Labs или testssl.sh против вашего производственного домена. Минимум TLS 1.2, предпочтительнее TLS 1.3, без слабых шифров, возможна предварительная загрузка HSTS.
  8. POST — Confirm health-check endpoints are minimal. /api/health должен возвращать 200 OK без тела. Не повторяйте среду, не создавайте хэш и не развертывайте временную метку без аутентификации.

Постоянный мониторинг и повторное сканирование (4 объекта)

Безопасность — это не разовая проверка перед отправкой. Дрифт происходит при каждом развертывании.

  1. Verify your production domain in FixVibe. Dashboard → Domains → DNS TXT or HTTP file verification. Active scans require Hobby or above, scheduled scans require Pro or Unlimited, and live threat monitoring requires Unlimited.
  2. Schedule passive re-scans on Pro or Unlimited. Choose an available cadence for your verified domain. Scheduled runs share your scan allowance; enable completion notifications and signed webhooks as needed. A scheduled scan observes the app at run time, not continuously.
  3. Wire outbound webhooks. Account → Webhooks → добавьте конечную точку HTTPS, подпишитесь на scan.completed + finding.created + scan.active_api.first_used. Рутируем в Slack/Discord/PagerDuty.
  4. Enable live threat monitoring on Unlimited. Periodic certificate, DNS, bundle, and threat-intelligence checks can surface changes between scheduled scans. Coverage and alert timing depend on the signal and successful polling.

Replit Agent

If you build with Replit Agent, also check:

  1. Don't paste keys into the Agent prompt. Add them in Secrets and give the Agent the variable name instead, so the value never appears in generated code or chat history.
  2. Test CORS on the production domain. The preview pane and your deployed URL are different origins. Check your CORS allowlist against the domain users actually load.
  3. Replit Agent sometimes hardcodes test values. Агент может генерировать код с API_URL = 'http://localhost:5000</code>. Перед отправкой замените на <code>os.environ[API_URL'].

Firebase Studio

If you build with Firebase Studio, also check:

  1. Test-mode rules are temporary by intent, not by default. Test mode lets anyone read and overwrite data. If the generated rule carries a date cutoff, client access stops on that date; if not, the database stays open. Replace test rules before launch either way.
  2. Security rules protect data, not Hosting. Firestore and Storage rules don't govern what Firebase Hosting serves: everything in the public directory is public. Keep exports, backups and admin pages out of it.

Claude Code

If you build with Claude Code, also check:

  1. PRE — Keep personal Claude Code settings out of git. Commit .claude/settings.json for shared project settings, but keep .claude/settings.local.json out of the repo: Claude Code excludes it from git when it creates the file, so check it if you created it by hand. Session history lives in ~/.claude, outside the project (Claude Code docs).
  2. Bash operations are unverified. Claude Code выполняет команды bash напрямую. git commit -m "fix" удобно, но если в рабочем каталоге есть файл .env и он включается в glob, он фиксируется. Всегда проверяйте git diff --cached перед тем, как Claude Code примет решение.

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

Хотите получить образовательную информацию о том, почему эти предметы важны? Прочтите AI-generated code security scanning. Хотите конкретные фрагменты кода для каждого этапа повышения безопасности? См. How to secure an app built with AI coding tools.

// scan your app

Хватит читать. Найдите бреши в своём приложении.

Drop in a URL — FixVibe runs every passive check from this guide plus the rest of its 230+ passive checks, usually in under a minute. Free, no install, no card.

  • Free уровень — 3 скана/месяц, без карты.
  • Пассивное сканирование любых URL — проверка домена не требуется.
  • Настроен на Cursor, Claude Code, Lovable, Bolt, v0, Replit.
  • Coding-agent prompts for code/config findings, plus operator steps for DNS/provider fixes.
Чек-лист безопасности vibe coding: 51 пункта перед запуском · FixVibe