Common miss in Lovable, Bolt, Cursor apps: no Strict-Transport-Security header. Without it, the first request can go over plain http, where it can be intercepted.
Fix: send
Strict-Transport-Security: max-age=31536000; includeSubDomains
Free scan: vibeappwatchdog.com?utm_sour…
Supabase changed something today: new tables are no longer granted to your app automatically.
Lovable app says "permission denied for table" (42501)? Skip GRANT ALL. In one migration: grant only what's needed, enable RLS, add a policy.
Free scan: vibeappwatchdog.com?utm_sour…
Many Lovable/Bolt apps ship with no Content-Security-Policy header, so an injected script can run freely and leak user data.
Fix: add a CSP in vercel.json or _headers. Start with default-src 'self', then allow only domains you use.
Free scan: vibeappwatchdog.com?utm_sour…
Easy mistake: the Supabase service_role key in your frontend. It bypasses all RLS, so anyone reading your JS gets full database access.
Fix: only the anon key goes in the browser. Keep service_role in Edge Functions, rotate it if exposed.
Free scan: vibeappwatchdog.com?utm_sour…
AI-built app mistake: anyone can download your .env file at /.env, usually because it landed in public/ or the build output.
Fix: keep it out of public/ and dist/, add it to .gitignore, and rotate every key that was exposed.
Free scan checks for it: vibeappwatchdog.com?utm_sour…
Easy mistake: calling OpenAI from the browser with VITE_OPENAI_API_KEY. The VITE_ prefix puts the key in your public JS, so anyone can use it.
Fix: call OpenAI from a Supabase Edge Function, keep the key there as a secret, rotate the old one.
Free scan: vibeappwatchdog.com?utm_sour…
No frame headers on your AI-built app? Any site can load it in an invisible iframe. Users think they click your page, but they click the attacker's. That's clickjacking.
Fix: send Content-Security-Policy: frame-ancestors 'self'
Free header check: vibeappwatchdog.com?utm_sour…
Easy miss in Supabase apps: a Storage bucket set to Public. Anyone with a file's URL can open it, no login needed.
Fix: make the bucket private, add Storage policies, and serve user uploads via signed URLs.
Free outside scan of your live app: vibeappwatchdog.com?utm_sour…
Is your app's .git folder public?
Open your-app.com/.git/HEAD. If you see "ref: refs/heads/main", anyone can rebuild your code and its history, even keys you deleted.
Fix: deploy only the build folder (dist), block /.git, rotate old keys.
Free scan: vibeappwatchdog.com?utm_sour…
I ran a passive check on 13 live apps people shared as "built with Lovable" on X. Only what a visitor's browser sees, no logins, no probing. Here's the pattern 🧵 #lovable
Check your own app: vibeappwatchdog.com/?utm_sou…
The gap: all 13 lacked Content-Security-Policy and X-Frame-Options. 12 sit on *.lovable.app, where the platform likely sets headers, so don't blame the builders. CSP makes injected scripts harder to run; X-Frame-Options blocks hidden framing.
What a passive check can't see: your database rules (RLS) or server code. Test those logged out. For the outside part, the first scan is free: vibeappwatchdog.com/?utm_sou…
Shipped a Vite app (Lovable, Bolt, Cursor)? Check if your .map files are public. A source map can hand anyone your readable original source code, comments included. The free scan now checks this:
vibeappwatchdog.com/?utm_sou…
Check it yourself: open your live site, find the JS file in DevTools > Network, look at its last line for //# sourceMappingURL=..., then try the same URL + .map (e.g. /assets/main-abc123.js.map). A JSON file back = public.
Fix in Vite: build.sourcemap defaults to false. If vite.config has sourcemap: true, remove it. 'hidden' only drops the comment; the .map file is still built, so don't deploy it. And never put secrets in frontend code anyway.
3/ Security headers. Check that your site sends headers like Content-Security-Policy, Strict-Transport-Security and X-Frame-Options. They are easy to forget and easy to add.