Security mistakes in vibe-coded apps, and how to fix them (2026)

The security mistakes that show up again and again in AI-built apps, mapped to the OWASP Top 10, with how to spot each one without reading code and the prompt that fixes it.

Floot ·

Key Takeaways

  • Most incidents are access control failures. OWASP puts Broken Access Control first in its 2025 Top 10. In vibe-coded apps it usually means data filtered in the browser instead of on the server.
  • Anything in frontend code is public. API keys, admin credentials and payment secrets must live only on the server, as environment secrets.
  • Database rules are not optional. If your frontend talks to the database directly, every table needs a row-level rule. Supabase’s docs say to enable Row Level Security on every table in an exposed schema.
  • Trust nothing that arrives from outside. Validate inputs on the server, verify webhook signatures, and don’t let the agent install packages you didn’t ask for.
  • You can test for most of these without reading code. Two accounts, a private window, the browser’s developer tools and a security-focused AI review catch the majority of problems.

Quick-Start Prioritization Framework

MistakeOWASP 2025 categoryQuick check
Users can see each other’s dataA01 Broken Access ControlTwo-account test with direct URLs
Secret keys in the browserA04 Cryptographic Failures / A02 MisconfigurationSearch the site’s JavaScript in developer tools for “sk_” or “key”
Tables with no row-level rulesA01 Broken Access ControlCheck each table’s RLS status in your database dashboard
Unverified webhooksA08 Software or Data Integrity FailuresAsk the agent to show the signature check
No server-side input validationA05 InjectionSend odd input via the form and the API
Unknown packages added by the agentA03 Software Supply Chain FailuresReview package.json changes in every diff
Errors that leak internalsA10 Mishandling of Exceptional ConditionsTrigger an error and read what the user sees

AI-built apps rarely get hacked in clever ways. They get hacked in boring ones: a page that returns every user’s records, a secret key shipped to the browser, a database table nobody put a rule on, a payment webhook that trusts whoever calls it. None of these produce an error while you build, which is exactly why vibe coders miss them. This guide walks through the most common mistakes, ties each one to the OWASP Top 10 (the industry’s standard list of web application risks, updated for 2025), and gives you a way to check for it without reading code and a prompt to fix it.

Why vibe-coded apps have predictable security holes

An agent optimises for what you can see: the feature works in the preview. Security is mostly about what you can’t see: what happens when someone who isn’t you sends a request. If you never ask for a rule, the agent may never add one, and nothing in the preview tells you it’s missing.

The upside is that the holes are predictable. The same handful show up across tools and models, so a short checklist covers most of the risk.

Mistake 1: access control in the browser instead of the server

This is the big one. The page fetches all orders, then the frontend shows only yours. Or the admin page is hidden from the menu but loads for anyone who types its address.

How to spot it

Sign in as user A and create data. Sign in as user B in another browser and paste A’s record URLs. Open the admin page while signed in as an ordinary user, and again signed out. In the browser’s developer tools, open the Network tab and look at what the API returns: if the response contains other users’ records, the filtering is happening in the browser.

The fix prompt

“Audit every endpoint and database query that returns or changes user data. Each must check on the server that the signed-in user owns the record or has the right role. Add tests that user B can’t read, update or delete user A’s records, and that a signed-out request is refused. Show me the test output.”

Mistake 2: secret keys shipped to the browser

Asked to “connect to OpenAI” or “add Stripe,” an agent may put the secret key wherever makes the demo work fastest, sometimes the frontend.

How to spot it

Open the published app, then the developer tools’ Sources or Network tab, and search the JavaScript for prefixes like sk_ (Stripe secret keys), sk- (many AI providers) or words like secret and apiKey. Also check your frontend environment variables: in many frameworks, variables with a public prefix such as NEXT_PUBLIC_ or VITE_ are bundled into browser code by design.

The fix

Revoke the exposed key at the provider and create a new one. Then: “Move all calls that use secret keys to server-side endpoints. The browser should call our endpoint, never the provider directly. Store keys only as server environment secrets.” Publishable keys designed for browsers, such as Stripe’s publishable key, are fine in the frontend.

And in Git

Keep .env files out of version control from the first commit. GitHub runs secret scanning automatically for free on public repositories, but a key that reached a public repo should be treated as leaked regardless.

Mistake 3: tables with no row-level rules

Some stacks let the frontend talk to the database directly with a public key. That’s safe only if the database itself enforces who can see which rows.

How to spot it

In Supabase, the dashboard shows whether Row Level Security is enabled on each table. Supabase’s documentation is direct: “Enable RLS on every table in an exposed schema.” A table the agent added last week without a policy is the classic gap.

The fix prompt

“List every table in the public schema with its RLS status and policies. Enable RLS on all of them. Write policies so users can only select, insert, update and delete their own rows, and admins can read all. Explain each policy in one sentence.”

Mistake 4: trusting input and webhooks

Anything that arrives from outside, whether a form, an API call, a file upload or a webhook, should be treated as possibly hostile.

Server-side validation

Validation in the form is for user experience; validation on the server is for security. Anyone can call your API without using your form. Ask: “Validate every endpoint’s input on the server with a schema: types, lengths, allowed values. Reject anything else with a clear error. Use parameterised queries for all database access.” Injection is A05 in OWASP’s 2025 list.

Webhook signatures

Stripe’s docs warn that without verification, an attacker could send fake events to trigger actions like fulfilling orders or granting access, and say to verify the Stripe-Signature header with the endpoint’s signing secret. They also note events may arrive more than once, so record processed event IDs. Ask the agent to show you the signature check and a test where an unsigned request is rejected.

File uploads

Limit file types and sizes on the server, store uploads outside the code’s folder, and don’t serve user uploads from your main domain as executable content.

Mistake 5: authentication shortcuts

OWASP lists Authentication Failures at A07. In AI-built apps they tend to look like home-made auth.

  • Passwords stored in plain text or with a weak hash. Use your platform’s or a well-known library’s auth instead of letting the agent write its own.
  • Sessions that never expire, or that survive sign-out.
  • Password reset links that don’t expire or can be reused.
  • No rate limit on sign-in, so passwords can be guessed endlessly.
  • Admin status stored somewhere the user can edit, such as local storage or a cookie value the server trusts.

Mistake 6: supply chain and configuration

OWASP’s 2025 list added Software Supply Chain Failures at A03 and keeps Security Misconfiguration at A02. Both are easy to create by accident with an agent.

Packages you didn’t ask for

Agents add dependencies freely, and occasionally suggest a package name that doesn’t exist or is a lookalike. Check package.json in each diff. Ask: “For each new dependency, tell me what it does, why it’s needed and whether it’s actively maintained.” Add a rule to your instruction file: “Ask before adding a production dependency.”

Debug settings left on

CORS set to allow any origin, verbose error pages, test routes, seed admin accounts with known passwords, and security checks “temporarily” disabled. Before launch, ask the agent to list every place where a setting differs between development and production.

Errors that say too much

A10 in OWASP 2025 is Mishandling of Exceptional Conditions. A stack trace or database error shown to users tells attackers what you run. Show users a plain message and log the details on the server.

A one-hour security pass before launch

Run this the day before you share the link.

  • Two-account test on every page and record URL.
  • Signed-out visit to admin, dashboard and known API addresses.
  • Search the published JavaScript for secret key prefixes.
  • Confirm every table has row-level rules (or every endpoint checks ownership).
  • Ask a fresh AI session for a security review of the whole repository, focused on the OWASP Top 10, with findings by severity.
  • Confirm webhook signature verification and duplicate handling.
  • Review dependencies added since the project started.
  • Trigger an error and check what users see.
  • Rotate any key that was ever pasted into a chat, a screenshot or a commit.

Common mistakes when fixing security

Even the fixes go wrong in predictable ways.

  • Hiding a button instead of protecting the endpoint behind it.
  • Deleting a leaked key from the code but not revoking it at the provider.
  • Disabling Row Level Security to make an error go away.
  • Asking the agent “is this secure?” in the same session that wrote it, and accepting yes.
  • Testing permissions only as an admin.
  • Letting the agent write its own password hashing instead of using proven auth.

If you’d rather not do this yourself

If you’d rather not build sign-in and permissions yourself, Floot gives each app its own sign-up and login (email, Google, Microsoft) with roles, so the agent builds on existing auth instead of writing its own. You still need to test that each user sees only their own data.

Frequently Asked Questions

Are vibe-coded apps less secure?

They tend to have the same, predictable gaps: missing server-side access checks, secrets in the browser, tables without row-level rules and unverified webhooks. A short checklist and a two-account test catch most of them.

What is the OWASP Top 10?

It’s the Open Worldwide Application Security Project’s list of the most critical web application security risks. The 2025 edition puts Broken Access Control first.

How do I know if my API key is exposed?

Open your published app’s developer tools and search the JavaScript for the key’s prefix or the word key. If it’s there, revoke it at the provider and move the call to a server-side endpoint.

Can I ask the AI to make my app secure?

You can ask for a security review and specific fixes, and it helps. Use a fresh session as the reviewer, ask for findings with file and line, and verify the fixes with behaviour tests.

What is Row Level Security?

It’s a Postgres feature, used heavily by Supabase, where the database itself decides which rows each user can read or change. If your frontend queries the database directly, it’s essential.

When should I hire a security professional?

Before handling payments directly, storing health or financial data, or serving a large public user base. Bring them your list of endpoints, tables and third-party services.

Sources