You described what you wanted, your AI wrote the code, and now you have a working app. That is genuinely impressive, and it is worth protecting. The catch is that AI coding tools optimize for "it works", not "it's checked". In Veracode's GenAI code security research, roughly 45 percent of AI-generated code samples contained security flaws, and an academic benchmark of AI-generated app security found the same pattern across tools. Whether you build with Cursor, Claude Code, Lovable, Bolt, v0, or Replit, the mistakes tend to be the same handful, made silently.
This checklist walks through those mistakes in plain English, ordered by how often they show up. None of them require a security background to find or fix. Most of them come down to asking one question of your app and pasting one prompt into the tool you already use.
Do this in the next 10 minutes
If you only have ten minutes today, these four steps close the doors that get found fastest:
- Search your repo for keys and passwords. Look in your code, your config files, and your git history. If you find any, rotate them at the provider now, before cleaning up the code.
- Open your app logged out and try to read data. Use a private browser window. If you can see anything that should belong to a user, your database rules need attention today.
- Visit your admin or account pages while logged out. Type the URLs in directly. A redirect is only protection if the server enforces it too.
- Trigger an error on purpose. Submit a form with junk in it. If the error message shows file paths, stack traces, or query text, turn detailed errors off in production.
Done? Good. The rest of this guide goes through the full list properly, with the reasoning and the fixes.
The full checklist, worst-first
1. Leaked keys and secrets
The most common finding in vibe-coded apps, and the one with the shortest fuse. AI tools often put API keys directly into code to get things working, and once a key is committed, deleting the line later does not help: git history keeps every old version of every file. Automated scrapers watch public repositories for exactly this pattern, so an exposed key tends to get found in hours, not months. The scale is real: in February 2026, researchers at Wiz found an exposed Moltbook database revealing roughly 1.5 million API keys. Keys leak constantly, everywhere, and yours are only special because they bill to your card.
The fix has a strict order: rotate first, clean up second. A rotated key in your history is a fossil. An active key in your history is a problem. If one of your keys is public right now, skip the rest of this article and follow the leaked API key runbook; it is this section expanded into ordered steps, including the history cleanup.
Search this entire repository for hardcoded secrets: API keys, database passwords, tokens, and connection strings. Check every file, including config files, and list each one you find with its file path.
Then:
1. Move every secret into environment variables, loaded from a .env file.
2. Add .env to .gitignore.
3. Create a .env.example file with the variable names but placeholder values.
4. Tell me which secrets appeared in code so I can rotate each one at its provider, since git history keeps old versions of files.Checking your full git history by hand is the tedious part. Our guide to scanning a GitHub repo for vulnerabilities covers what that takes, and the faster route.
2. A database anyone can read
Plain English: anyone can read your users' data (broken access control). This happens because backends like Supabase and Firebase hand the browser a public key by design, and rely on per-table rules to decide who can read which rows. AI tools frequently generate the tables without the rules. The result looks completely normal in the app and is completely open from outside it.
This is not hypothetical. In 2025, a researcher found 170+ Lovable-built apps exposing user data through exactly this pattern (tracked as CVE-2025-48757). If your app was built with Lovable or uses Supabase, our Lovable security checklist walks through the two-minute check and the verbatim fix, and the Supabase Row Level Security deep dive covers writing and testing the policies themselves, whatever tool you build with.
3. Routes that never check who's asking
A quieter cousin of the open database: your API endpoints exist, they work, and they answer anyone. AI tools are good at hiding the admin button from non-admins and much less consistent about making the server refuse a non-admin who calls the admin endpoint directly. The same goes for changing an ID in a URL: if /api/orders/1041 shows you someone else's order when you change the number, the check lives in the wrong place.
Review every API route and server function in this app that reads or writes user data. For each one, tell me:
1. Does it verify the request comes from a logged-in user, on the server, not just in the browser?
2. Does it check that the user is allowed to access the specific record they asked for, so user A cannot request user B's data by changing an ID?
For every route that fails either check, add the missing server-side verification. Do not rely on hiding buttons or client-side redirects as protection.4. Trusting whatever users type
Anything a visitor can type or send can be crafted to do something you did not intend: query text that reads your whole database (SQL injection) or a script that runs in another visitor's browser (cross-site scripting). AI-generated code handles the happy path well and is inconsistent about the hostile path. The fix is a principle rather than a patch: user input is data, never instructions. Database queries should be parameterized, and user content should be escaped before it is rendered. Ask your AI tool to audit every place user input reaches a query or a page, and to fix the ones that pass it through raw.
5. Dependencies with known problems
Your app is mostly other people's code, and some of those packages have publicly documented vulnerabilities (known CVEs) with fixes already published. The packages your AI picked were current at generation time and have been aging ever since. This is the easiest class to check, because the problems are already catalogued: compare what you have installed against the public databases and update what's flagged. GitHub surfaces some of this for you if it's enabled on the repo.
6. Debug leftovers and exposed config
Verbose error pages, committed .env files, test endpoints, and "temporary" logging: scaffolding the AI put up while building and nobody took down. Individually small, they add up to a map of your app's insides. Walk through what production actually serves and remove what a visitor has no business seeing.
7. No rate limits where it hurts
Without rate limits, a script can try passwords on your login form all night or call your expensive AI-backed endpoint a million times on your bill. Put limits on login, signup, password reset, and anything that costs you money per call. This one rarely announces itself until it matters, which is exactly why it's on the list.
What a scanner can't catch
A scan of your repo, ours included, reads your code. Some real risks never appear in code:
- Business logic flaws. If your app lets a user apply the same discount code forever, the code is working exactly as written. No scanner knows your rules well enough to call that a bug.
- Credentials that already left. A scan can find a key sitting in your repo and tell you to rotate it. It cannot know whether someone copied it last month. That is why rotation, not deletion, is always the fix.
- Social engineering. No code change stops someone from being talked out of their password. Turning on two-factor authentication for your own accounts, especially GitHub and your hosting provider, is the single best move here.
- What your tools do outside the repo. In July 2025, an AI coding agent deleted a production database during a code freeze. Keep production credentials out of your AI tools' reach, and keep backups that your tools cannot touch.
A scanner's honest job is to make sure the checkable things are actually checked, so your attention is free for the parts that need a human.
Frequently asked questions
Is vibe coding safe?
Vibe coding is as safe as the checking you do afterwards. Research from Veracode found that roughly 45 percent of AI-generated code samples contained security flaws, so the sensible assumption is that your app has a few, and that they are findable and fixable. The risk is not building with AI, it is shipping without looking.
My app is small and has almost no users. Do I really need this?
The checks that matter most, leaked keys and open databases, are found by automated bots that crawl everything, not by attackers choosing targets. A small app with a leaked key gets that key abused just as fast as a big one. The good news: a small app takes minutes to check.
I already pushed an API key to GitHub. Is deleting it enough?
No. The key stays in your git history, and automated scrapers watch public repositories for exactly this. Treat the key as exposed: rotate it at the provider first, then remove it from the code and history.
Which AI coding tools does this checklist apply to?
All of them. The issue classes here show up in apps built with Cursor, Claude Code, Lovable, Bolt, v0, Replit, and anything else that writes code for you. Some tools have platform-specific patterns worth checking too, like the Supabase row-level security setup in Lovable apps, and some have their own walkthrough, like the Cursor security checklist.
How often should I go through this?
Once fully now, then a lighter pass whenever you ship a feature that touches auth, payments, or user data. Every new AI-generated feature is new code that nobody has read yet.
Do I need a security background to work through this checklist?
No. Every item is written in plain English and comes down to a question you can answer by looking at your own app. Where a fix is involved, there is a prompt you can paste into the AI tool you already use.
You built something real. Working through this list, or letting a scan work through the checkable parts for you, is how you make sure it's actually done.