Vibe-Coding & AI 2026-10-10 7 min READ

Vibe-Coding Security: Mitigating Vulnerabilities in Lovable, Bolt, Cursor & v0 Projects

Why AI-generated web applications and vibe-coding prototypes are vulnerable out of the box. Exposed OpenAI and Stripe keys in client JS bundles, unconfigured Supabase RLS, and actionable pre-launch hardening steps.

S By Site Check Security Team

The meteoric rise of 'vibe-coding' workflows and generative web builders—including Lovable, Bolt.new, Cursor, and v0.dev—has empowered entrepreneurs, designers, and non-technical creators to scaffold complete SaaS platforms and interactive web applications in hours. However, building at the speed of natural language prompts creates a perilous blindspot: LLMs optimize code for functional immediacy and visual fidelity, almost never for application security.

Most creators deploying vibe-coded projects have no idea that their AI assistant embedded private OpenAI API keys or Stripe secret tokens directly inside compiled client-side JavaScript bundles, or that their connected Supabase backend allows unauthenticated public reads and writes because Row Level Security (RLS) was left disabled during rapid prototyping.

1. The Primary Hazard: Leaking Private API Keys in Client JavaScript

When you prompt an AI coding tool to connect OpenAI completions or Stripe checkouts, the AI frequently generates direct fetch calls inside React components. When the frontend bundles for production, secret keys prefixed with NEXT_PUBLIC_ or VITE_ get baked into public .js files. Automated scrapers discover these keys within minutes and consume thousands of dollars in API credits.

Important Note: Never store private API keys in variables prefixed with NEXT_PUBLIC_ or VITE_. These prefixes instruct modern bundlers to inline values directly into client-side JavaScript bundles.
Isolating secret API keys strictly inside server route handlers
                  // VULNERABLE VIBE CODE (in React client component):
// const res = await fetch('https://api.openai.com/v1/chat/completions', {
//   headers: { Authorization: `Bearer ${import.meta.env.VITE_OPENAI_KEY}` }
// });

// SECURE ARCHITECTURE (Next.js App Router Server Route /api/generate):
import { NextResponse } from 'next/server';

export async function POST(req: Request) {
  const session = await getServerSession();
  if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  
  const { prompt } = await req.json();
  const response = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_API_SECRET_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ model: 'gpt-4o', messages: [{ role: 'user', content: prompt }] })
  });
  return NextResponse.json(await response.json());
}
                

2. Cloud Databases with Disabled Row Level Security (Supabase & Firebase)

Vibe-coded frontends typically initialize Supabase using a public URL and anon_key. If Row Level Security (RLS) is disabled on Supabase PostgreSQL tables, any user can open browser DevTools, query the REST endpoint (e.g. /rest/v1/users), and dump the entire user database without authentication.

Enforcing Row Level Security (RLS) in Supabase SQL Editor
                  -- Mandatory security baseline for every Supabase table:
ALTER TABLE public.user_profiles ENABLE ROW LEVEL SECURITY;

-- Create policy allowing authenticated users to read only their own record:
CREATE POLICY "Users can only read own profile"
ON public.user_profiles FOR SELECT
USING (auth.uid() = user_id);

-- Create policy allowing users to update only their own record:
CREATE POLICY "Users can only update own profile"
ON public.user_profiles FOR UPDATE
USING (auth.uid() = user_id);
                

3. Production Source Maps (.map Files) Exposing Proprietary Code

Vite and Next.js projects configured by AI tools frequently leave source map generation enabled in production. This allows anyone opening the DevTools 'Sources' panel to view your original TypeScript source code, internal system routes, database schemas, and developer prompts.

Disabling production source maps in Vite
                  // vite.config.ts
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    sourcemap: false, // Ensure source maps are never published to production
    rollupOptions: {
      output: {
        manualChunks: undefined
      }
    }
  }
});
                

4. Unbounded AI Endpoints & Denial of Wallet Attacks

When AI assistants scaffold API proxy routes, they rarely implement rate limiting or anti-abuse protection. Automated scripts can fire tens of thousands of requests to your LLM completion endpoints, resulting in massive API invoices within a single afternoon.

Important Note: Implement Upstash Redis or Cloudflare Turnstile token verification on every endpoint executing paid third-party AI generations.

5. Pre-Launch Vibe-Code Hardening Protocol

Before allocating marketing capital or onboarding initial paying users, conduct an automated pre-flight audit: verify bundle secrets, test Supabase tables with unauthenticated cURL commands, disable source maps, and scan your domain using Site Check.

Developer Security Checklist

  • ✓ Inspect compiled JS bundles for exposed secret tokens (sk-..., sec_...)
  • ✓ Never expose private keys via NEXT_PUBLIC_ or VITE_ environment prefixes
  • ✓ Enable Row Level Security (RLS) on every Supabase PostgreSQL table
  • ✓ Disable production source map generation (sourcemap: false in build config)
  • ✓ Implement IP-based rate limiting on all LLM generation and billing endpoints
  • ✓ Run Site Check automated scanner before launching marketing campaigns

Security Auditor Synthesis & Key Takeaways

When shipping production web applications and vibe-coded projects built on modern stacks (Next.js, Astro, React, Supabase), perimeter security cannot be an afterthought. Over 85% of customer data leaks and database compromises do not stem from sophisticated zero-day exploits, but rather from trivial misconfigurations: orphaned staging endpoints, exposed environment files, overly permissive CORS policies, and disabled Row Level Security (RLS) rules.

Automated perimeter scanning with Site Check proactively catches these signatures across 36 critical attack vectors, equipping engineering teams and vibe-coders with immediate actionable remediation guides before automated scanning botnets discover the exposed endpoints.