Scorpr LogoSCORPR
SECURITY CHECKLISTUpdated for Cursor, Bolt & Lovable Stacks

The Vibe-Coding Pre-Launch Security Playbook

AI code assistants let you ship at lightspeed, but they routinely forget database authorization, leak API credentials in client builds, and omit security headers. Complete this interactive checklist before pointing your custom domain.

Checklist Readiness: 0 of 6 Completed0%
DATABASE & SUPABASE • RULE #1

Enable Row Level Security (RLS) on ALL Public Tables

CRITICAL

When Cursor or Lovable generates a Supabase table, RLS is often disabled by default. Anyone with your public Anon Key can query `POST /rest/v1/<table_name>` and dump all customer records.

Target: supabase/migrations/001_enable_rls.sql
-- 1. Enable RLS
ALTER TABLE public.user_profiles ENABLE ROW LEVEL SECURITY;

-- 2. Restrict Read to Owner
CREATE POLICY "Users can only read their own profile"
ON public.user_profiles FOR SELECT
USING (auth.uid() = id);

-- 3. Restrict Updates to Owner
CREATE POLICY "Users can only update their own profile"
ON public.user_profiles FOR UPDATE
USING (auth.uid() = id);
API SECRETS & KEYS • RULE #2

Never Prefix Secret Keys with NEXT_PUBLIC_ or VITE_

CRITICAL

Variables prefixed with `NEXT_PUBLIC_` or `VITE_` are baked directly into compiled client-side JavaScript bundles, making them visible to anyone inspecting DevTools.

Target: .env.local & src/app/api/checkout/route.ts
// ❌ WRONG (Leaked to client bundle):
// NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_live_...

// ✅ CORRECT:
STRIPE_SECRET_KEY=sk_live_...

// Use ONLY in Server Components, Server Actions, or Route Handlers:
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
FRAMEWORK & BUILD • RULE #3

Disable Production Source Maps (.js.map)

HIGH

Source maps allow reverse-engineers to reconstruct your entire TypeScript codebase, database schemas, internal endpoint structures, and hidden business logic.

Target: next.config.ts / next.config.mjs
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  // Ensure production sourcemaps are never uploaded to public CDN
  productionBrowserSourceMaps: false,
};

export default nextConfig;
SERVER ACTIONS • RULE #4

Enforce Session Authentication Inside Server Actions

CRITICAL

Next.js Server Actions are public POST endpoints. Never trust client arguments like `userId`. Always verify the caller’s session on the server side.

Target: src/app/actions/update-user.ts
'use server';
import { auth } from '@/auth'; // Or supabase.auth.getUser()

export async function updateUserProfile(formData: FormData) {
  // 1. Authenticate session on server
  const session = await auth();
  if (!session?.user?.id) {
    throw new Error('Unauthorized');
  }

  // 2. Perform mutation strictly for authenticated user
  const newName = formData.get('name') as string;
  await db.update(users).set({ name: newName }).where(eq(users.id, session.user.id));
}
HTTP SECURITY HEADERS • RULE #5

Configure Strict OWASP Defense Headers

HIGH

Prevent clickjacking (iframe embedding), MIME sniffing, and enforce HTTPS with HSTS.

Target: next.config.ts
headers: async () => [
  {
    source: '/:path*',
    headers: [
      { key: 'X-Frame-Options', value: 'DENY' },
      { key: 'X-Content-Type-Options', value: 'nosniff' },
      { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
      { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
    ],
  },
]
AI ENGINE VISIBILITY • RULE #6

Deploy /llms.txt for ChatGPT, Perplexity & Claude Discovery

MEDIUM

Vibe-coded SPAs often render as blank shells to AI search bots. Publish `/llms.txt` in your public folder so LLMs can cite your SaaS.

Target: public/llms.txt
# Your Product Name
> Clean 1-sentence value proposition for LLM models.

## Core Features
- Feature A: Detail
- Feature B: Detail

## Documentation & API
- https://yourdomain.com/docs

Automate This Entire Checklist in 30 Seconds

Scorpr tests these 6 rules and dozens more automatically via live external headless probes.