Founder guide
How to tell if your AI-generated app is secure
A plain-English checklist for non-technical founders who shipped a “vibecoded” MVP and now wonder what’s hiding under the hood. Updated June 2026.
AI code generators are extraordinary at producing software that works. Paste a prompt, get a running app, ship it. But “it works” and “it’s safe to put in front of paying customers” are two very different statements — and the gap between them is exactly where most AI-generated apps get into trouble. The failures aren’t in the features you can see; they’re in the security, access control, and scaling decisions that never come up when you’re demoing to yourself. Here’s what to look for, in the order that actually matters.
1. Secrets committed to the repo
The single most common — and most damaging — mistake. An AI assistant, mid-flow, drops your database password, Stripe key, or OpenAI token directly into a file “just to get it working.” That file gets committed. Now the credential lives in your Git history forever, readable by anyone who can see the repo. Attackers run automated bots that scan public GitHub for exactly this, and they find keys within minutes. The fix is simple but urgent: never put a secret in code. Use environment variables, rotate any key that was ever committed, and purge it from history.
2. An API that anyone can call
This is the subtlest and scariest one. Your app’s interface hides buttons the current user shouldn’t see — but the API behind those buttonsis often wide open. If the server doesn’t independently check who is making each request and whether they’re allowed to touch that specific record, then anyone with a browser’s developer tools can read or modify other users’ data directly. AI scaffolds routinely generate endpoints with no authentication and no ownership checks. Every protected route needs to verify a session or token and confirm the caller owns the data before returning or changing it.
3. SQL and commands built from strings
When user input is glued directly into a database query or a shell command, an attacker can rewrite what that query or command does — reading your entire database (SQL injection) or running arbitrary commands on your server. The safe pattern is parameterized queries (or an ORM’s query builder) and passing command arguments as a list rather than building one big string. If you see template strings with ${...}inside a SQL statement, that’s a red flag.
4. No input validation
A robust backend treats every incoming request as hostile until proven otherwise: it validates the shape and type of the data before doing anything with it. AI-generated endpoints frequently trust whatever the client sends, which leads to crashes, corrupt data, and a wider attack surface. Look for a validation library — zod and pydantic are the common ones — wrapping your request handlers. If there isn’t one, that’s a gap.
5. Queries inside loops (the N+1 problem)
This one doesn’t bite until you have traffic — which is the worst time to discover it. If your code loops over a list and runs a database query for each item, then ten users means dozens of queries and a thousand users can take your database down. It runs fine in your demo and melts in production. The fix is to fetch what you need in a single query (a join, or an IN (…) clause) instead of one-at-a-time.
6. Errors that get swallowed
Empty catch blocks and bare except: passstatements hide failures. A payment silently fails, data silently doesn’t save, and you find out from an angry customer instead of your logs. Errors should be logged and handled, never quietly discarded.
7. Debug mode left on
Many frameworks have a debug mode that shows detailed stack traces — and sometimes an interactive console — when something breaks. Wonderful in development, catastrophic in production, where it hands attackers a map of your system. Debug should be driven by an environment variable and default to off.
8. No tests
Tests aren’t about perfectionism; they’re about being able to change your code without breaking the things that already work. A codebase with zero automated tests is one where every fix is a gamble. You don’t need 100% coverage — start with smoke tests on the flows that earn or lose you money: signup, login, payment, and your core action.
9. Dependency drift
If your project has no lockfile, or pins dependencies to “latest,” then the libraries your app depends on can change underneath you — introducing bugs or, worse, a compromised version. Commit a lockfile and pin versions so your builds are reproducible.
How to check your own app in 10 seconds
You don’t need to read your codebase line by line to get a sense of your risk. Slop Scan runs all nine of these checks automatically: paste a public GitHub repo and it returns a 0–100 health score and a prioritized, plain-English list of what it found, with an estimated cost to fix. It’s free for the score and your top issues — the fastest way to turn “I’m not sure” into a concrete to-do list.