What a Code Review of a Vibe-Coded App Covers and What It Does Not

What a Code Review of a Vibe-Coded App Covers and What It Does Not
📌

Executive Summary & Key Takeaways

A code review of a vibe-coded app checks the things AI coding tools are most likely to get wrong: exposed secrets, missing database access controls, unsafe data flows, and outdated dependencies with known vulnerabilities. It does not replace runtime testing, load testing, or a full penetration test.

Table of Contents
  1. What 'vibe-coded' means for reviewers
  2. What the review actually checks
  3. What a code review does not cover
  4. The output
  5. What we see repeatedly in AI-generated code
  6. When to stop reading and ask for help
  7. Common questions
  8. Sources

A code review of a vibe-coded app checks the things AI coding tools are most likely to get wrong: exposed secrets, missing database access controls, unsafe data flows, and outdated dependencies with known vulnerabilities. It does not replace runtime testing, load testing, or a full penetration test.

What 'vibe-coded' means for reviewers

Apps built with Cursor, Lovable, Bolt, or similar AI-assisted tools follow a pattern a reviewer learns to recognise quickly. The happy path works. Navigation is clean. The code structure looks reasonable at a glance. What breaks is underneath: the security model, the data layer, the edge cases.

The UpGuard study published on 14 October 2026 found 16,326 Supabase databases with publicly readable tables across roughly 300,000 candidate domains. UpGuard's explanation: Supabase turns RLS on by default for tables made in the Table Editor, but tables created programmatically through the API, which is how coding agents interact with Supabase, do not get it by default. The AI generates the schema. The AI runs the migration. RLS stays off.

That is the category of problem a code review is built to find. Not the business logic. The infrastructure assumptions that the AI did not know to set.

What the review actually checks

Secrets and credentials

The first check is for exposed secrets: API keys, service role credentials, and database connection strings that have been committed to the repository or bundled into the frontend JavaScript. A Supabase service role key bypasses Row Level Security (the Supabase docs say the `service_role` Postgres role has the bypassrls attribute, and to keep the key server-side), so one that reaches the browser exposes your whole database. The free code review tool we run reads your repository files as they are now and checks them for secrets, risky code patterns, Supabase and Firebase configuration, and vulnerable dependencies. It does not scan git history or built output, so check those by hand.

This is not a rare finding. AI coding tools often generate environment configuration that works locally without making the production distinction clear. The result is a NEXT_PUBLIC_ prefix on a key that was never meant to be public, or a Vite import.meta.env variable that ships the key to the browser at build time.

Database access controls

The second area is access control at the database layer. For Supabase apps, that means checking which tables have RLS enabled, reading each policy for common mistakes (policies that check auth.uid() on insert but not on select, policies that use a role column the user can write to themselves, USING clauses with a literal 'true' that allow everyone), and checking whether any Postgres functions run with elevated permissions that skip the caller's access controls.

This kind of analysis requires reading the SQL, not just running the app. An AI tool that generated your migrations is unlikely to have written edge-case policies. It writes what was asked for. If you did not ask for 'no user can read another user's invoices', that rule probably does not exist. The common RLS policy mistakes post covers what these look like in practice.

Taint and data flow

Taint analysis traces untrusted input - anything a user submits - from where it enters the application to where it is used. The questions: does the input reach a database query without server-side validation? Does it get echoed back in a response in a way that could inject HTML or JavaScript? Does it get included in a server-side log without sanitising first?

AI-generated API routes often pass request body fields directly to database operations. The code works for expected input. It behaves unpredictably when input is shaped to exploit the gap. Validation present on the frontend form does not protect you - a direct API call bypasses the frontend entirely.

Dependency health

The fourth check is your dependency tree. AI coding tools suggest packages. They do not always suggest the most current maintained package. We check each direct dependency against the OSV (Open Source Vulnerabilities) database and against End-of-Life schedules. A package that has not had a security release in two years is a risk even if no CVE has been published against it yet.

Slopsquatting - where a hallucinated package name has been registered by a third party to serve malicious code - is a reported risk. As of October 2026, mass exploitation of this pattern is unconfirmed. The code review tool checks dependencies against OSV and end-of-life data; confirming that each package name is real is a manual step.

What a code review does not cover

A code review works with the code as written. It does not simulate runtime behaviour under load, test your app against a live attacker, or catch bugs that only surface when two users act simultaneously on the same record.

  • Runtime security testing: a code review finds a missing rate limit in the code; it does not confirm whether your API can be flooded in practice
  • Penetration testing: no credential brute-forcing, no network scanning, no exploitation of live endpoints - those require separate tools and a separate scope
  • Business logic correctness: whether your pricing calculation is right, whether your refund logic matches your policy - out of scope
  • Performance under load: database query plans, caching strategy, infrastructure sizing - the review notes structural risks visible in the code (like a missing index), but does not run load tests

If you are not sure which of these you need, when you need a code audit covers the decision in more detail.

The output

A review produces a prioritised list of findings, not a pass/fail score. Critical findings - secrets exposed in the repository, RLS off on tables containing user data, an authentication bypass in an API route - need to be addressed before real users arrive. Medium findings are things that do not create immediate exposure but will cause problems at scale or during an incident. Low findings are hygiene: inconsistent error handling, outdated packages without known CVEs.

What is not in the output: a recommendation to rewrite. A review works with what exists. If findings are severe enough that a rewrite is the better path, that is a separate conversation and not a conclusion a code review can reach on its own. The fix or rebuild decision post covers how to think through that.

What we see repeatedly in AI-generated code

The patterns we find are consistent with what the structural evidence predicts. Missing RLS. Service role keys in frontend bundles. Input that reaches the database without server-side validation. Dependency trees that include packages last updated in 2022.

The code often looks fine from the outside. Function names are sensible. Component structure is reasonable. The security problems are not visible from reading the surface - they are in the data flow from user input to database, in the policy that covers three of four query types and misses the fourth, in the key that was exported 'just for testing' and never removed.

When to stop reading and ask for help

Run the free automated check on your repository to see what the static analysis layer finds. The automated check covers the deterministic categories: secrets, known vulnerable dependencies, and Firebase and Supabase configuration signals. What requires human judgment is everything downstream of that - whether a policy is logically correct, whether a data flow creates a real exposure, whether a finding in isolation is actually exploitable.

If the automated check returns findings in the secrets or RLS categories, that is the point to bring in a reviewer. Those findings create real exposure the moment a real user arrives. The app health check gives you a broader read across your frontend, DNS, and configuration before launch. And if you want a human to walk through what the findings mean and what to prioritise, a technical review before your first real user is the cheapest version of this conversation you will ever have.

Common questions

What does a code review of a vibe-coded app check?

It checks what AI coding tools most often get wrong: exposed secrets, missing database access controls such as RLS, unsafe data flows from user input, and outdated dependencies with known vulnerabilities. It does not replace runtime testing or a penetration test.

Does a code review replace a penetration test?

No. A code review works with the code as written and does not simulate load, attack live endpoints or brute-force credentials. Those need separate tools and a separate scope, as do business logic correctness and performance under load.

When should I bring in a human reviewer for my AI-built app?

If an automated check returns findings in the secrets or RLS categories, bring in a reviewer, because those create real exposure the moment a real user arrives. Zovintra offers a technical review before your first real user.

Sources

TECHNICAL CONSULTATION

Building something similar?

Talk to our engineering team about your architecture, roadmap, and delivery timeline.

Request a Technical Review →

Related Reading

← Back to all posts