You built an app with Lovable, Bolt, Cursor or Claude Code. It works, people are signing up, and it might be leaving the doors wide open.
AI writes code that works, not code that's safe, unless you specifically ask. Security is the invisible part of the spec, so the AI skips it, and so do you, because you can't see what's missing.
How often this goes wrong
Veracode's 2025 GenAI Code Security Report found that 45% of AI-generated code samples contained an OWASP Top 10 flaw, and the number barely moved between older and newer models. (Veracode sells security products, so treat it as directional.) A scan of 5,600 public vibe-coded apps found 2,038 high-impact vulnerabilities and 175 instances of exposed personal data, all live in production.
The incidents are concrete. In CVE-2025-48757, more than 170 Lovable apps had Supabase databases anyone could read, because Row Level Security was never turned on. In July 2025 the Tea app left about 72,000 images in an unsecured storage bucket. The same month, an AI agent on Replit deleted a live production database during a code freeze.
None of these were exotic attacks. They were basic, preventable mistakes. Here are the ones that matter most, and how to check each in minutes.
1. Secrets in the browser
An API key is a password. If it ends up in code that runs in someone's browser, it's public.
The trap: NEXT_PUBLIC_ (Next.js) and VITE_ (Vite) prefixes deliberately bake a variable into the public JavaScript bundle. AI tools often add that prefix to a secret to fix an "undefined" error, and now your Stripe secret key ships to every visitor. The Supabase service_role key deserves special fear: it bypasses every Row Level Security rule.
Check it: open your live site, press F12, go to Sources, and search the loaded scripts for sk_live, service_role, secret and AKIA. Any match is exposed. Move it to a server-only variable used from a server route, then rotate the key. Deleting it from the file doesn't remove it from git history, and bots scrape public bundles within minutes.
2. Database rules that were never turned on
With Supabase and Firebase, your app talks to the database straight from the browser using a public key. The only thing stopping a stranger from reading everyone's data is access rules you must enable yourself. This is the single most common vibe-coding breach.
- Supabase: security comes entirely from Row Level Security (RLS), and tables have it off by default. Dashboard → Database → Security Advisor flags every table without it.
-
Firebase: "test mode" (
allow read, write: if true) lets anyone read and write everything. Replace it before launch.
A subtle trap on both: "logged in" is not "owns this data". A policy of USING (true), or a rule that only checks request.auth != null, lets any signed-up user (including an attacker who just registered) read everyone's rows. Scope every rule to the user, for example (select auth.uid()) = user_id.
Test it: create two accounts, sign in as A, and try to fetch B's row. If data comes back, the policy is broken.
3. "Change the ID in the URL" bugs
Authentication is who you are; authorization is what you may touch. AI apps usually get login roughly right and authorization badly wrong.
The most common flaw is IDOR (also called BOLA), number one on the OWASP API Security list. Your app has /api/invoices/1042; change it to 1043 and you see someone else's invoice, because the server checked you were logged in but never that the invoice was yours. Hidden buttons and random UUIDs don't fix this. Anyone can call an endpoint directly, and IDs leak in emails and shared links.
Check it: log in as user A, find a request like /api/orders/1001 in the Network tab, copy it as cURL, change the ID, and re-run it. Fix it by putting ownership inside the query (WHERE id = :id AND user_id = :currentUser) and returning 404 when the record isn't theirs.
4. Payments the browser controls
Two money mistakes dominate AI-built apps:
- Client-set prices. If checkout sends an amount from the browser, an attacker changes it to 1. Decide prices on the server from a fixed price ID.
- Unverified webhooks. Your payment provider tells your server "payment succeeded" by calling a public URL, so anyone can POST a fake event to it. Verify the signature on every webhook, using the raw, unparsed request body, and reject anything invalid.
Then check subscription status server-side before unlocking paid features, not a flag the browser set once.
5. Unescaped input
React escapes text safely, but dangerouslySetInnerHTML turns that protection off. Veracode found AI tools failed to defend against cross-site scripting in 86% of relevant cases. Sanitise with DOMPurify, or avoid raw HTML entirely. Use parameterised queries, never SQL glued together from strings. And if your app passes user text to an LLM, never let the model's output trigger a sensitive action without a separate check.
6. Endpoints with no limits
If an endpoint that costs you money (an AI call, an email, a signup) has no limit, someone will hit it thousands of times. AI tools almost never add limits unless asked. Layer your defences:
- Set a hard monthly spend cap in your AI provider's dashboard. Do it today.
- Rate-limit per user ID, not just per IP.
- Require login before any expensive action.
- Cap input size. A rate limit controls how often, not how expensive one request is.
7. Packages that don't exist
AI sometimes recommends packages that don't exist, and attackers register those exact names with malware ("slopsquatting"). A USENIX Security 2025 study found 19.7% of packages recommended across 16 models didn't exist. Look up every AI-suggested package on npmjs.com before installing it, and run npm audit on what you already have.
The 30-minute pre-launch routine
You don't need a pentest to catch the big stuff:
- Search your bundle for
sk_liveandservice_role(5 min) - Enable RLS everywhere; kill Firebase test mode (5 min)
- Run the two-account IDOR test (5 min)
- Confirm webhook verification and server-side prices (3 min)
-
npm audit, and check for hallucinated packages (3 min) - Check your grade on securityheaders.com, and make sure errors hide stack traces (3 min)
- Set a hard AI spend cap (3 min)
- Confirm backups work and dev and prod are separate (3 min)
Run it before every launch and after any big change. If you handle health, financial or children's data, or a breach would sink the business, pay a professional for a review as well. And if you're in India, note that the DPDP Act requires reporting personal-data breaches to the Data Protection Board and affected users.
Originally published on TechBrosEbooks.
This article is adapted from the ebook Ship Your Vibe-Coded App Without Getting Hacked, which gives a detection step and a copy-paste fix-it prompt for every risk above, plus security headers, CORS, supply-chain tooling, and a full walkthrough auditing a sample Lovable + Supabase + Stripe app.
Top comments (0)