`Building apps and tools in public. Sharing what I learn about AI, vibe coding and keeping apps safe. Currently: vibeappwatchdog.com`

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…
1
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…
1
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.
1
5
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.
1
3
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 things to check before you launch your Lovable or Bolt app 🧵 #vibecoding
1
5
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.
1