FixVibe

// docs / security guides / cursor checklist

Чек-лист безопасности Cursor: 28 пунктов перед запуском

Building with Cursor? Cursor's autocomplete, Composer mode, and Agent features are exceptionally powerful — and create predictable security blind spots. This checklist targets Cursor-specific patterns: service-role key inlining, Composer-generated whole files without review, Agent-mode terminal commands, and the <code>.cursorrules</code> file as your first security guardrail. 28 items across secrets, database, auth, headers, deployment, and Cursor-specific gotchas.

PRE = pre-deploy (audit your source). DEPLOY = at deploy time. POST = post-deploy verification. Items reference FixVibe check IDs in category.check-id form where relevant.

Secrets and API keys (5 items)

Cursor's autocomplete is trained on open-source code where secrets are common. The model suggests them freely, especially after a failed auth attempt.

  1. PRE — Write security rules into .cursorrules. Add a line: "Never inline SUPABASE_SERVICE_ROLE_KEY, sk_live_*, or any env var starting with a provider acronym into client-side code. Always use server-only imports." Cursor reads .cursorrules and factors it into every suggestion.
  2. PRE — Audit Composer-generated files. When Cursor's Composer creates a whole file (especially auth handlers), review it line-by-line. Composer sometimes inlines env vars that should stay server-only. Look for NEXT_PUBLIC_ or direct references to service keys in component imports.
  3. PRE — Reject auto-imports of service clients into client components. If Composer imports import { supabase } from '@/lib/supabase/service' into a React file, delete it immediately and route through an API endpoint instead. Server-only imports are explicitly marked — don't skip them.
  4. PRE — Scan Agent-mode commits. Agent mode runs terminal commands and can commit directly. Audit git log --oneline -20 and git diff HEAD~5 to ensure no secret-looking strings were committed during an Agent run.
  5. POST — Run secrets.browser-storage. Passive scan on the deployed URL. If a service key appears in the JS bundle, rotate it immediately — Cursor's autocomplete probably inlined it.

Database access control (4 items)

Composer often generates working auth code but skips RLS — the "it works" moment blinds people to the missing policy enforcement.

  1. PRE — Force Cursor to generate migrations with RLS. In .cursorrules: "Every CREATE TABLE public.* migration must include ALTER TABLE ... ENABLE ROW LEVEL SECURITY and FORCE ROW LEVEL SECURITY." Then ask Composer to generate the migration.
  2. PRE — Review Composer-generated policies. Composer sometimes writes policies without checking auth.uid(). Policies like allow select on public.items without a using clause are dangerously wide. Require user_id matching.
  3. DEPLOY — Confirm FORCE ROW LEVEL SECURITY is live. Open Supabase Studio, check each table's RLS toggle. If Composer's migration had ENABLE but forgot FORCE, table owners (your migrations) bypass RLS. This is a real gap.
  4. POST — Run the baas.supabase-rls active check. It tries a write with the anon key. If it succeeds, RLS isn't actually enforcing — likely missing the FORCE keyword.

Authentication and sessions (4 items)

Cursor generates auth flows quickly but often misses the subtle server-side validation that keeps tokens safe.

  1. PRE — Ensure all auth routes use getUser(). Search for getSession() in your API routes and replace with await supabase.auth.getUser(). getSession() reads an unverified cookie; getUser() validates with Supabase backend.
  2. PRE — Check Composer auth handlers for token expiry. Magic-link tokens need server-enforced expires_at. Default Supabase is 1 hour — don't ask Cursor to override it without a real reason.
  3. PRE — Audit the sign-in redirect guard. The next query param redirect after sign-in must be validated: must start with /, never //. Composer sometimes skips this. Add it manually if missing.
  4. POST — Test logout server-side state destruction. Sign in, sign out, inspect cookies (DevTools → Application → Cookies). The session cookie must be cleared immediately. If it persists, the logout handler isn't destroying state.

HTTP security headers and CSP (3 items)

Cursor rarely generates middleware by default. If you don't ask explicitly, CSP and HSTS usually aren't there.

  1. PRE — Demand CSP in .cursorrules. Add: "Generate a src/middleware.ts with Content-Security-Policy. Use nonce for script-src, no unsafe-inline." Then ask Cursor to generate it. Without this hint, middleware is skipped.
  2. PRE — Verify src/middleware.ts exists. With the src/ directory layout, Next.js only picks up src/middleware.ts. A root-level middleware.ts is silently ignored. If CSP isn't landing, check the file is in the right place.
  3. POST — Run headers.security-headers. Passive scan reports missing CSP, HSTS, X-Frame-Options, X-Content-Type-Options. Open the report and follow the fix guidance for your deployment platform.

Deployment hygiene (5 items)

Cursor apps often land on Vercel, which has good defaults but needs explicit hardening for the build/deploy boundary.

  1. DEPLOY — Check Vercel env-var scoping. Settings → Environment Variables → each secret should be scoped to Production only. Never share sk_live_* with Preview or Development.
  2. DEPLOY — Disable build-log secret echo. If your vercel.json or GitHub Actions workflow has echo $SECRET, remove it. Build logs are archived publicly; secrets in logs are compromised.
  3. DEPLOY — Use Vercel's managed secrets, not inline workflow vars. Vercel's Settings → Environment Variables is encrypted at rest. GitHub Actions' secrets are better than nothing but are designed for CI, not deployment platform integration.
  4. POST — Verify CSP nonce on the deployed preview. Open a Vercel Preview link in the browser, open DevTools → Network → the root HTML response. CSP header must be present and include 'strict-dynamic' with a unique nonce per request.
  5. POST — Rotate any key that ever shipped, even to Preview. If a key reached the production bundle for even 10 minutes, it's compromised. Rotate immediately.

Cursor-specific gotchas (4 items)

Patterns unique to Cursor's workflow that create security risks:

  1. Agent mode auto-fixes propagate old patterns. If you ask Agent to "fix auth errors", it may regenerate the same auth file multiple times, each time inlining the same service key if it's in the codebase context. Clean the original first, then ask Agent to fix.
  2. Cursor Index leaks intent. Cursor's @codebase indexing is powerful but if your .cursor directory is ever exposed (misconfigured S3, git history), the index reveals your architecture and secret patterns. Keep .cursor local.
  3. Composer mode loses context between files. Each file Composer generates is fresh. If you ask it to generate a client file, then an API route, they may use different Supabase client configs. Review both and ensure they match your architecture.
  4. Autocomplete bias toward "working" over "secure". Cursor suggests the fastest code that passes your current context. If your test has NEXT_PUBLIC_SERVICE_KEY, autocomplete remembers it and re-suggests it. Clean test fixtures before sharing code with the model.

Next steps

Once you've locked down the Cursor-specific patterns, cross-check against the general vibe coding security checklist (44 items) and then step-by-step hardening. Also see the Claude Code checklist if you're mixing tools.

// scan your app

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

Drop in a URL — FixVibe runs every passive check from this guide plus 200+ others in under a minute. Free, no install, no card.

  • Free tier — 3 scans / month, no card.
  • Passive scans against any URL — no domain verification needed.
  • Tuned for Cursor, Claude Code, Lovable, Bolt, v0, Replit.
  • AI fix prompts on every finding — paste back into your IDE.
Чек-лист безопасности Cursor: 28 пунктов перед запуском — Docs · FixVibe