The Hidden Security Debt of Vibe-Coded Apps: What 155 Launches Revealed
The Speed Trap of AI-Powered Development
Let's be honest—we've all done it. Spent an afternoon prompting Lovable, Bolt, or Cursor, and by dinner, we had a live URL. It felt like magic. The platform handled hosting, SSL was automatic, and our little side project was suddenly real.
But here's the uncomfortable truth I keep coming back to: shipping fast doesn't mean shipping secure. And as someone who's watched the vibe coding revolution unfold, I think we need to talk about what that afternoon-to-URL pipeline actually leaves behind.
A recent deep dive scanned 155 vibe-coded applications that their creators had publicly launched. Ninety-nine were still live and scannable. The results? Equal parts encouraging and concerning—and they should change how we think about pre-launch checklists.
The Good News: Secrets Stay Hidden
Here's what pleasantly surprised me: only 1% of scanned apps leaked actual secret keys to the browser.
No exposed OpenAI API keys burning through someone else's budget. No AWS credentials floating in client-side JavaScript. No Stripe live keys ready to drain a bank account.
This tells me something important: the modern AI coding platforms have genuinely improved their defaults. When you create a new project in Bolt or Replit, the platform guides you toward edge functions for secrets rather than dumping them in the browser bundle. That's genuinely good UX design for security.
But one percent is still one too many. One exposed key is a $50,000 OpenAI bill, a compromised AWS account, or a Stripe dispute that sinks your startup before it starts. Don't be that one percent.
The Supabase Problem Nobody Talks About
Here's where things get genuinely tricky.
37% of live vibe-coded apps include a Supabase anonymous key in their frontend code. And before you panic—that's actually expected. Supabase is designed this way. The anon key is meant to be public; your data security is supposed to come from Row Level Security (RLS) policies.
Here's the problem: RLS is opt-in. Tables start fully open. And when you're vibe coding at 11 PM, racing to hit your launch deadline, it's remarkably easy to miss that checkbox.
Every table with RLS disabled—or worse, a lazy using (true) policy—is a door wide open to anyone with that public anon key. An attacker doesn't need to hack anything. They just... query your database, because you forgot one setting.
I can't stress this enough: passive scanning can't detect RLS misconfigurations. The scanner only sees the frontend. The vulnerability lives in your database. You have to check this manually, table by table, before you go live.
The same advice applies to Firebase (which appeared in 4% of scanned apps). Security rules aren't optional add-ons. They're the whole security model.
Security Headers: The Invisible To-Do List
If you've never thought about HTTP security headers, you're not alone. 91% of scanned apps lack a Content-Security-Policy, and 88% can be embedded in iframes on any website (hello, clickjacking).
These aren't exotic vulnerabilities. They're standard hardening steps that have been best practice for years. The vibe coding pipeline just... doesn't include them by default.
Here's the breakdown from the scan:
- 91% missing Content-Security-Policy
- 88% missing X-Frame-Options / frame-ancestors
- 37% missing X-Content-Type-Options
- 38% missing Referrer-Policy
- 8% missing Strict-Transport-Security
- Only 5% had all security headers configured
The bright spot? Hosting platforms handle HSTS automatically, so that's mostly covered. But the CSP gap is significant. When an AI-written component renders user-generated content or integrates third-party scripts, a CSP is your last line of defense. Without one, XSS attacks have nowhere to hide.
The Launch Polish Gap
Here's a finding I didn't expect to care about, but totally do: 30% of vibe-coded apps launch without Open Graph tags.
That means when someone shares your product on X (Twitter), Discord, or LinkedIn, it shows up as a bare URL with no preview image, no title, no description. Just... text. In 2024, that looks amateurish and kills click-through rates.
Additional launch-day oversights found in the scan:
- 11% had no meta description
- 77% had no sitemap.xml
- Overall security grades averaged B-minus (84/100), with only 13% earning an A
The apps weren't disasters—they just needed polish. The same speed that gets you to launch is the speed that makes you forget <meta property="og:title">.
My 5-Minute Pre-Launch Checklist
After reading through this research, I've updated my personal launch checklist. Here's what actually matters before you post that Show HN thread:
1. Hunt for secrets in your bundle
Search your built output for sk-, sk_live_, service_role, ghp_. Anything that matches gets rotated immediately and moved to an edge function or environment variable. One exposed key is all it takes.
2. Audit every Supabase or Firebase table
Open your dashboard. Every public table needs RLS enabled. Every policy needs to be specific—never using (true). Read access to one misconfigured table can expose your entire user database.
3. Add these security headers
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Start with Content-Security-Policy-Report-Only if you want to test without enforcement. But get it deployed.
4. Disable production source maps
Your *.map files are debugging gold for you—and for attackers. Most platforms have a toggle. Flip it off before launch.
5. Add your Open Graph metadata
At minimum: og:title, og:description, og:image. Your launch post deserves to look good in a timeline.
6. Generate a sitemap.xml Your SEO future self will thank you. Most platforms auto-generate these—check if yours did.
The Bigger Picture
Here's my take: vibe coding isn't the problem. The problem is the gap between "it works on my machine" and "it's production-ready." Traditional developers learned this gap through years of painful deployments. Vibe coders are learning it faster—which is actually good.
The platforms are improving. The defaults are getting better. But until security hardening is as automatic as SSL certificates, the responsibility falls on us as builders to add that five-minute checklist before launch.
The speed of vibe coding is a superpower. Security doesn't have to be the tax you pay for using it.
What's your pre-launch security routine? Drop your checklist additions in the comments—I'm always looking to improve mine.