AI3 min read

The Security Risks of AI-Generated Code (And How to Audit Them)

Vibe-coded apps are shipping faster than ever — but they come with hidden security risks. We look at the most common vulnerabilities and how to audit for them.

By ShipReady · Updated

AI coding tools have collapsed the time from idea to deployed app, and that is genuinely wonderful. But speed hides risk: the same tools that scaffold an app in an afternoon also scaffold the misconfigurations that turn it into an incident. These are the patterns we see over and over in AI-built apps.

The most common vulnerabilities

  • Exposed API keys — provider keys and secrets baked into the client bundle, readable by anyone who opens dev tools.
  • Missing authorization — endpoints that check you are logged in but not that you are allowed to see this record.
  • No row-level security — a Supabase or Firebase project where the client can read the whole table.
  • SQL injection — queries built by string concatenation rather than parameterization.
  • Permissive CORS — an API that reflects any origin, opening it to credentialed cross-site requests.
  • Missing security headers — no CSP, no HSTS, no clickjacking protection.
  • Tooling files deployed by accident — the .cursorrules and .env files that ride along when a whole repository is pushed instead of a build.

The two that are specific to AI-built apps

Most of the list above is ordinary web security that predates any coding assistant. Two failure modes are genuinely new, in the sense that they exist because of how these apps get made and deployed.

The first is tooling artifacts reaching production. AI coding tools write instruction and config files at the repository root — .cursorrules, CLAUDE.md, .cursor/mcp.json — and a deployment that serves the repository rather than a build serves those too. Your AI coding tool left its notes on your server covers the whole pattern and the one-command check.

The second is provider keys reaching the browser. Asked to "call the model from the component", an assistant will reach for a NEXT_PUBLIC_ variable or set dangerouslyAllowBrowser: true, because both make the code work immediately. Both also publish the key to every visitor.

Why it happens

A model optimizes for code that runs and satisfies the prompt, not code that withstands an adversary. Security requirements are usually implicit — you did not ask for row-level security, so you did not get it. And because the happy path works in the demo, the gap is invisible until someone finds it.

There is a second reason worth naming, and it is structural rather than about the model. The failures that actually bite are usually configuration rather than code: an environment variable set in the wrong scope, a deployment serving the wrong directory, a database with permissive default policies. None of that is in the file the assistant wrote, so reading the diff carefully — which is what everyone advises — does not surface it.

How to audit AI-generated code

  1. Grep your client bundle for anything resembling a key or secret — it should contain none.
  2. For every data endpoint, confirm it checks ownership, not just authentication.
  3. Turn on row-level security and verify an unauthenticated client cannot read protected tables.
  4. Check the response headers on your live site for CSP, HSTS and CORS policy.
  5. Run an external scan against the deployed app — the attacker sees what shipped, not your source.

What an outside scan can and cannot see

Be clear about the division of labour, because no single tool covers this ground.

Visible from outsideOnly visible in your code or dashboard
Secrets in the client bundle, response headers, TLS configuration, exposed files and directories, DNS records, publicly readable database tablesAuthorisation logic, query construction, server-side input handling, what your background jobs do, who has access to your infrastructure

A scanner that claims the right-hand column from a URL alone is guessing. The right-hand column needs code review, a static analysis tool, or a person — and we say so on the comparison pages rather than pretending otherwise.

The left-hand column is the one worth automating, because it is where configuration failures live and configuration is exactly what nobody reviews. That is the whole idea behind ShipReady: it scans the running app from outside, reports only what it can observe with evidence, and hands you a paste-ready fix for each finding. If you build with a specific tool, the stack security guides cover what that tool tends to get wrong by default, and the production readiness checklist is the ordered version of the audit above.

Sources

Related reading

Is your site ready to ship?

ShipReady scans up to ten pages for security, AI exposure, email deliverability, SEO and launch readiness — with a paste-ready fix for each finding. Free, no signup.