CodanopySecurity scanning for AI-generated apps
Security risks in AI-generated code

Is your AI-generated app actually secure?

Code written by an AI assistant runs the same risk of security bugs as code written by a person — except the specific bugs it tends to produce, and how fast it accumulates them, are different enough to be worth naming on their own.

The recurring risk categories

Hardcoded secrets

In plain terms

Your app uses passwords and keys to talk to things like your database or payment provider. AI tools often paste these straight into the code so an example works right away. If that code is ever shared or leaked — even an old version — anyone who sees it can use those keys as if they were you.

For developers

Ask an assistant for a working example and it writes a working example — API key, database password, or JWT secret inlined as a string literal so the snippet runs without extra setup. It ships that way because nobody went back to move it into an environment variable. Worse, deleting the line from the working tree later doesn't remove it from git history, where it's still reachable.

Missing or broken authorization

In plain terms

Your app probably checks that people are logged in. What it often doesn't check is whether the thing they're asking for is actually theirs. That means any signed-in user could see or change someone else's orders, messages, or profile just by changing a number in the address bar.

For developers

Assistants are very good at 'does this endpoint require login' and much weaker at 'does this endpoint's response belong to the logged-in user.' The result is routes that check authentication, then fetch a record by an ID taken straight from the request — an IDOR any authenticated user can walk by incrementing a number.

Injection from string-built queries

In plain terms

When your app looks something up using text a visitor typed in, a careless setup lets that text be treated as a command instead of plain text. Someone who types the right thing into a search box or login form can then read, change, or delete data they should never touch.

For developers

An assistant asked for 'a function that looks up a user by name' will often produce exactly that, with the name concatenated into SQL. It's the shortest correct-looking answer to the literal question, and it's also a textbook injection point. The same pattern shows up in shell calls built from user input.

Insecure defaults copied from example code

In plain terms

Example code is written to work on the first try, not to be safe. Settings that are fine on your own laptop — like showing detailed error pages or accepting requests from any website — often stay switched on in the live app, where they make an attacker's job easier.

For developers

Permissive CORS ('*'), debug mode left on, weak or unsalted hashing, cookies without `Secure`/`HttpOnly` — these are the settings that make a tutorial snippet run on the first try with the fewest moving parts. They're reasonable defaults for a five-minute demo and a liability in anything that ships.

Trust boundaries that only exist in the browser

In plain terms

Anything that happens in the visitor's browser can be changed by the visitor. If your app decides the price, the user's plan, or whether they're an admin inside the browser, and the server just believes it, a user can edit that value and give themselves a discount or extra access.

For developers

A price, a role, or a quota decided in client-side code and simply accepted by the API when it comes back. Each half of that — the UI logic and the endpoint — looks correct in isolation; the vulnerability only exists in the gap between them, which is exactly the kind of thing generated one file at a time misses.

Prompt-injection surface, if the app itself calls an LLM

In plain terms

If your app sends user text to an AI model and then acts on its answer, a user can write instructions that the AI follows instead of yours — for example, telling it to reveal private data or do something it shouldn't.

For developers

Apps that wrap an LLM (a common AI-generated app shape) often pipe untrusted text — a user message, a scraped page, a document upload — straight into a prompt, then let the model's output drive an action. Untrusted input reaching a decision-making step through a prompt instead of a parameter is a new-shaped version of an old problem.

Why this isn't the same problem as hand-written risk

Locally correct, globally wrong
Each generated file, viewed alone, does what it was asked to do. The gaps are almost always between files — an auth check in one handler that a sibling handler forgot to copy — which is invisible to anything that reviews one file at a time.
No accumulated judgment
A developer who's been burned by a SQL injection once tends to parameterise queries by reflex afterward. A prompt has no scar tissue — it optimises for 'answers the question asked,' not 'avoids the mistake I made last time.'
Volume, not just novelty
The individual mistakes aren't new. What's new is how much code ships per hour without a second set of eyes on it, which is a volume problem a manual review process wasn't sized for.

Checking for it

A code review by someone who's seen these patterns before is the gold standard, and also the thing that doesn't scale to every commit from every vibe-coded side project. Codanopy is built specifically for the gap: a free static scan plus an AI pass that reads across files, aimed at exactly the categories above rather than a generic vulnerability checklist.

See how the scan works, how Codanopy compares to a manual review or a dependency-focused scanner, or jump straight to a stack-specific landing page.