On April 14, 2026 we pointed vibeAudit at 40 production apps built with Lovable, bolt.new, Cursor and v0. Targets came from public showcase pages and hackathon winner lists. One read-only scan each. No credentials, no logins, no fuzzing — the scanner used the same public anon key the app already ships in its JavaScript bundle to every visitor.
Everything the scanner saw, a browser tab could see.
The numbers
- 111 findings total
- 30 CRITICAL
- 8 apps with at least one CRITICAL
- 6 apps with 3 or more CRITICAL on a single target
- 1 app shipping a Supabase
service_rolekey — the god-mode credential — inside its public JS bundle
Why we don't publish names
Before anything else: we have not, and will not, publish the list of 8 apps. Every example in this post is anonymized by platform and vertical only.
If you think one of these is your app, email hello@vibeaudit.net. We'll send the full report privately, help you fix it, and we will never attribute it publicly without your written consent.
A 14-day grace period plus a private, actionable report fixes the problem faster than a public callout. The founders shipping with AI builders are exactly the audience we want to help — burning them in public makes them defensive, not safer.
Three patterns that kept showing up
Not every app had all three of these. 32 of the 40 apps had zero CRITICAL findings. But these three patterns accounted for the majority of the 30 CRITICALs we did find, and we saw each of them across multiple unrelated apps.
1. Row Level Security left off
A Lovable-built job-matching SaaS had RLS disabled on 20+ tables. Jobs, recruiter contacts, private salary data — all readable with a single curl using the public anon key that already ships in the site's JavaScript.
RLS isn't on by default in every scaffolding path these tools use. The app works in the demo, so nobody circles back.
The fix is one SQL statement per table plus a policy:
ALTER TABLE public.jobs ENABLE ROW LEVEL SECURITY;
CREATE POLICY "jobs are readable by owner"
ON public.jobs
FOR SELECT
USING (auth.uid() = owner_id);
Ten minutes.
2. Secrets in public bundles
A bolt.new document utility had a Stripe live secret and a provider API key in its deployed JavaScript. Grep-able from the browser in under a second.
The fix: move to server env vars, call the provider from an edge function or API route, rotate the leaked key.
3. PII tables one GET request away
A Lovable real-estate CRM was exposing a leads table with names, phone numbers and budgets. Same root cause as pattern #1 — RLS never turned on — but the impact lands differently when the rows are people's contact details.
What this is not
- Not auth bypass. Not injection. Not fuzzing write endpoints.
- Not a list of named victims.
- Not an indictment of Lovable, bolt.new, Cursor or v0 — those tools ship great product. The gap is the 10 minutes of deployment hygiene between "prototype works" and "real users sign up."
Self-audit in 5 minutes, no tool required
You don't need us for the first pass. Do these three checks right now:
1. Grep your deployed JS bundle for secret prefixes
curl -s https://yourapp.com/assets/index-*.js \
| grep -E 'service_role|sk_live_|sk-proj-|xoxb-'
If anything comes back, that's a P0.
2. Curl your own Supabase REST endpoint with just the anon key
curl "https://<project>.supabase.co/rest/v1/<table>?select=*&limit=5" \
-H "apikey: <your anon key>" \
-H "Authorization: Bearer <your anon key>"
If you get rows back on a table that should be private, RLS is off or your policy is wrong.
3. Run the free scan
Open vibeaudit.net. Paste your URL. 30 seconds, no signup, no credit card. For anything it catches, you'll see the exact table, the exact secret, and the SQL to fix it.
Top comments (0)