5 Security Risks Every Vibe Coder Should Know
What Is Vibe Coding?
Vibe coding is building software by describing what you want to an AI tool and letting it write the code. Tools like Cursor, Bolt, Lovable, v0, Replit, and Claude Code have made it possible for anyone to ship a web app in hours.
The problem? Every AI coding tool optimizes for functionality — not security. They generate code that works, but that code often has serious security vulnerabilities baked in.
We've scanned thousands of vibe-coded apps at VibeSafe. Here are the 5 most common security risks we find.
1. Exposed API Keys in Client-Side Code
How common: Found in ~40% of scans
AI tools store API keys wherever they're needed. They don't always distinguish between server-side and client-side code. The result: your OpenAI key, Stripe secret key, or Supabase service_role key ends up in the JavaScript bundle that anyone can read.
What can go wrong:
- Your OpenAI bill spikes to thousands of dollars
- Someone steals your Stripe key and creates fraudulent charges
- Your entire database is readable and writable
Fix: Move all secret keys to server-side environment variables (no NEXT_PUBLIC_ prefix) and call APIs through your own backend routes.
2. Missing Security Headers
How common: Found in ~70% of scans
No AI tool adds security headers by default. Headers like Content-Security-Policy, Strict-Transport-Security, and X-Frame-Options protect against XSS, man-in-the-middle attacks, and clickjacking.
What can go wrong:
- XSS attacks inject malicious scripts into your app
- Your app can be embedded in an iframe and used for phishing
- Browser doesn't enforce HTTPS
Fix: Add a security headers configuration to your next.config.ts or middleware:
// next.config.ts
async headers() {
return [{
source: "/(.*)",
headers: [
{ key: "X-Frame-Options", value: "DENY" },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
],
}];
}
3. No Auth Checks on API Routes
How common: Found in ~35% of scans
AI tools generate API routes that handle data — create, read, update, delete — but they almost never add authentication checks. Anyone who knows the endpoint URL can call it.
What can go wrong:
- Unauthorized users access or modify data
- Admin functions are available to everyone
- Data exfiltration through unprotected endpoints
Fix: Check the user's session at the top of every API route handler. In Next.js with Supabase:
export async function POST(req: Request) {
const supabase = createServerClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) {
return Response.json({ error: "Unauthorized" }, { status: 401 });
}
// Now safe to process the request
}
4. CORS Wildcard Configuration
How common: Found in ~25% of scans
When AI tools need to handle cross-origin requests, they set Access-Control-Allow-Origin: * — allowing any website to call your API. This is especially dangerous if your API uses cookies or session tokens.
What can go wrong:
- Malicious websites can make API calls on behalf of your users
- Session hijacking through cross-origin requests
- Data theft from your API
Fix: Set specific allowed origins instead of wildcard:
const allowedOrigins = ["https://yourapp.com"];
if (allowedOrigins.includes(origin)) {
response.headers.set("Access-Control-Allow-Origin", origin);
}
5. Database Security Misconfigurations
How common: Found in ~20% of scans
When using Supabase or Firebase, AI tools often skip Row Level Security (RLS) policies. They create tables and insert data, but they don't add policies that restrict who can read or write what.
What can go wrong:
- Any user can read all data in all tables
- Users can modify other users' records
- Sensitive data (emails, addresses, payment info) is publicly accessible
Fix: Enable RLS and create policies for every table:
ALTER TABLE todos ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users see own todos"
ON todos FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users create own todos"
ON todos FOR INSERT
WITH CHECK (auth.uid() = user_id);
How to Check Your App
You can manually audit each of these, or run an automated scan:
- Go to vibesafe.tech
- Paste your deployed URL
- Get your security grade in 60 seconds
VibeSafe checks for all 5 of these risks — plus 50 more — and gives you step-by-step fix instructions for each finding.
The Bottom Line
Vibe coding is great for speed. But speed without security is a liability. Build fast, then scan. Fix the issues before your users find them — or worse, before an attacker does.