Guide · 2026-03-05

The Vibe Coding Security Checklist: Ship Safe, Not Sorry

45% of AI code has vulnerabilities. A 10-point checklist, Supabase RLS explained, API key rules, and the one prompt to run before shipping.

What You'll Learn

  • A 10-point checklist to run before shipping any vibe-coded app
  • How Supabase Row Level Security works (and what happens without it)
  • The one prompt that catches security issues you'd never think to look for
  • 45% of AI-generated code has at least one security vulnerability (Stanford study). That doesn't mean you can't ship — it means you need to check before you ship.

    Why AI Code Has Security Issues

    AI tools optimize for "does it work" — not "is it secure." When you ask for a login page, the AI builds one that logs you in. Whether it stores passwords safely, protects against injection attacks, or hides API keys is secondary.

    The training data includes millions of code examples, and a huge portion of those examples have security issues. The AI copies patterns, including the insecure ones. It doesn't know the difference.

    Warning: Code that runs without errors is not the same as code that's safe to deploy. A working app with exposed API keys is a ticking time bomb.

    The 10-Point Security Checklist

    Run through this before you ship anything to real users:

  • API keys and secrets are NOT in frontend code
  • Supabase RLS is enabled on every table with user data
  • User input is validated and sanitized (forms, URLs, search)
  • Authentication checks exist on all protected routes
  • HTTPS is enforced (most hosts do this automatically)
  • No console.log statements with sensitive data
  • All secrets are in environment variables, not hardcoded
  • Rate limiting is set up on API routes
  • Error messages don't expose internal details (no stack traces to users)
  • Passwords are hashed, never stored as plain text
  • Pro tip: Print this list. Tape it next to your screen. Check it every time you deploy. It takes 10 minutes and prevents disasters.

    Supabase RLS — What It Is and Why It Matters

    Row Level Security (RLS) controls who can read and write each row in your database. Without it, any authenticated user can see and modify every other user's data.

    Think of it this way: without RLS, your database is a shared Google Sheet where everyone can see everyone else's rows. With RLS, each person only sees their own rows.

    What happens without RLS: User A signs up. User B signs up. User B opens browser dev tools, changes a request, and reads all of User A's data. Name, email, private notes — everything.

    Here's a simple RLS policy that restricts users to their own data:

    sql
    -- Enable RLS on the table
    ALTER TABLE todos ENABLE ROW LEVEL SECURITY;
    
    -- Users can only see their own todos
    CREATE POLICY "Users can view own todos"
      ON todos FOR SELECT
      USING (auth.uid() = user_id);
    
    -- Users can only insert their own todos
    CREATE POLICY "Users can insert own todos"
      ON todos FOR INSERT
      WITH CHECK (auth.uid() = user_id);
    
    -- Users can only update their own todos
    CREATE POLICY "Users can update own todos"
      ON todos FOR UPDATE
      USING (auth.uid() = user_id);
    
    -- Users can only delete their own todos
    CREATE POLICY "Users can delete own todos"
      ON todos FOR DELETE
      USING (auth.uid() = user_id);
    Warning: If you're using Supabase and haven't set up RLS, stop reading this guide and do it now. This is the #1 security issue in vibe-coded apps.

    API Keys — Where They Go

    Simple rule: if a key gives access to data or costs money, it goes on the server. Never the client.

    Correct — server-side only:

    text
    # .env.local (never committed to git)
    OPENAI_API_KEY=sk-abc123...
    STRIPE_SECRET_KEY=sk_live_...
    SUPABASE_SERVICE_ROLE_KEY=eyJ...

    Incorrect — exposed to every visitor:

    text
    # These are visible in the browser
    NEXT_PUBLIC_OPENAI_KEY=sk-abc123...
    NEXT_PUBLIC_STRIPE_SECRET=sk_live_...

    In Next.js, any variable starting with NEXT_PUBLIC_ is bundled into the frontend and visible to anyone who opens your site. Use it only for values that are meant to be public (like your Supabase anon key or a Google Analytics ID).

    Never commit .env files to Git. Add .env and .env.local to your .gitignore. If you already committed one, the keys are in your Git history and should be rotated immediately.

    What to Check in Your Browser Console

    Open your deployed app. Press F12 (or right-click → Inspect). Go to the Network tab. Click around your app.

    Look at each request. Expand the headers and the request URL. If you see any of these, you have a problem:

  • API keys in request URLs (?key=sk-abc123)
  • Secret keys in request headers
  • Full database connection strings
  • Internal error messages with stack traces
  • Try this: Open your app right now, open DevTools, and click through every feature. If you see any secret in the Network tab, that key is exposed to every visitor on your site.

    The One Prompt to Run Before Shipping

    Copy this prompt and run it in Cursor with your full codebase open:

    text
    Review this entire codebase for security vulnerabilities. Check for:
    - Exposed API keys or secrets in frontend code
    - Missing authentication checks on protected routes
    - SQL injection or XSS vulnerabilities
    - Supabase tables without Row Level Security
    - Sensitive data in console.log statements
    - Hardcoded credentials
    
    List every issue found with the file name, line number, and how to fix it.
    Pro tip: Run this prompt in Cursor with your full codebase open. It catches things you'd never think to look for. Run it after every major feature addition, not just before launch.

    This isn't a replacement for a professional security audit. But for most vibe-coded MVPs and side projects, it catches the critical issues that would otherwise ship to production.

    Want an automated check? Try our Security Checker tool.

    Built by Us

    This guide is based on real builds. gptsters.com is built with vibe coding — see for yourself.

    Related Guides

  • 7 Mistakes Every Vibe Coder Makes — security is mistake #3, but they're all worth knowing
  • Secure Your Vibe Coded App — deeper dive into security practices
  • When Vibe Coding Won't Work — know the limits, including security limits
  • Recommended Stack

    Services we recommend for deploying your vibe coded app