12 things to check before you ship your vibe-coded app A security analysis by Symbiotic Security found that 98% of 1,072 Supabase-backed vibe-coded apps had at least one security issue, with 16% containing critical flaws. An academic study by Deng et al. identified recurring vulnerability patterns unique to these apps, while Xint.io reported 434 exploitable flaws concentrated in secrets exposure, broken authorization, and denial of service. A developer recommends a 15-minute checklist including checking for exposed .env and .git files, hardcoded secrets, missing security headers, and unauthenticated debug routes. Getting an app to work has stopped being the hard part. You describe what you want, Lovable or Bolt or v0 builds it, and forty minutes later there's something on a real URL that real people can click. The hard part moved. It's now everything between "it works" and "it survives contact with the internet." That gap isn't a vibe. It's measurable. Symbiotic Security https://www.symbioticsec.ai/research crawled 65,643 URLs and fully scanned 1,072 Supabase-backed vibe-coded apps in June 2026: 98% had at least one security issue, 16% had something critical. A separate academic study by Deng et al. https://arxiv.org/abs/2606.23130 found that vibe-coded apps show recurring vulnerability patterns that differ from the ones traditional codebases produce — meaning these aren't random mistakes, they're structural. And an Xint.io analysis reported by SecurityWeek turned up 434 exploitable flaws concentrated in secrets exposure, broken authorization and denial of service. Same handful of failure modes, over and over. Which is good news, because it means you can check for them in about fifteen minutes. Below is the list I actually walk through. Everything here you can run against your own domain with curl and browser devtools. No tooling required. .env reachable over HTTP? The single most common catastrophic finding. It happens when the build output directory and the project root end up being the same thing. curl -sI https://yourapp.com/.env | head -1 curl -sI https://yourapp.com/.env.local | head -1 curl -sI https://yourapp.com/.env.production | head -1 Anything other than 404 is an emergency. Rotate every key in that file before you do anything else — assume it's already been scraped, because bots hit these paths constantly. .git directory exposed? Worse than .env , because it hands over your entire history including keys you thought you'd removed. curl -sI https://yourapp.com/.git/HEAD | head -1 curl -s https://yourapp.com/.git/config If HEAD returns 200, the whole repository is reconstructable by a stranger. Open devtools, go to Sources, and search across all files. You're looking for sk- , service role , SECRET , PRIVATE KEY , and long strings starting with eyJ those are JWTs . The nuance that trips people up: a Supabase anon key in the browser is fine by design. A service role key is not — it bypasses row-level security entirely. AI assistants confuse the two constantly, because both are "the Supabase key" from the prompt's point of view. Having an anon key in the browser is only safe if RLS is enabled on every table. Default-off is the trap. Go through your tables one by one and confirm policies exist. "I'll add policies later" is how the 16% happens. curl -sI https://yourapp.com | grep -iE 'content-security-policy|strict-transport-security|x-frame-options|x-content-type-options|referrer-policy|permissions-policy' Most vibe-coded deploys return none of these. The two that matter most immediately are Content-Security-Policy or at minimum frame-ancestors to stop clickjacking, and Strict-Transport-Security so a downgrade attack can't strip your TLS. curl -sI https://yourapp.com/ next/static/chunks/main.js.map | head -1 Source maps in production hand attackers your original, readable source — comments, internal function names, dead code paths and all. Turn them off in your build config, or restrict them to authenticated access. Grep your own bundle for console.log and check whether anything sensitive is being printed on page load. Then try the routes nobody meant to ship: /api/debug , /api/test , /admin , /api/seed . AI-generated scaffolding loves to leave these behind, unauthenticated. Almost never present unless explicitly asked for. Without it, your login endpoint is a free credential-stuffing target and your LLM-backed API route is somebody else's free inference budget. Check whether your host gives you rate limiting at the edge — often it's a config flag you just haven't flipped. Trigger a failure deliberately: malformed JSON to a POST endpoint, a bad ID in a path parameter. If you get back a stack trace, a file path, or an ORM error naming your tables and columns, that's free reconnaissance for anyone probing you. curl -s https://yourapp.com | grep -iE '