AIsecurityvibe coding

How to Secure a Vibe-Coded Website: A Founder's Guide for 2026

fivetwentyoneSeptember 15, 202610 min read

Most vibe-coded websites are not insecure because the AI wrote bad code. They are insecure because nobody ever wrote the security layer the code assumed someone else would add. A generator ships a working login, a live database, and a public deploy in an afternoon, and the parts that keep strangers out stay switched off by default. That is the whole of vibe-coded website security in one sentence, and it is also the reason so many of these sites leak.

The gap is now measurable. Veracode tested AI-generated code across more than 100 models in 2025 and found that 45 percent of it shipped with a vulnerability from the OWASP Top 10. That number had not improved by its Spring 2026 update. Security firm Escape then scanned 5,600 public vibe-coded apps and pulled out more than 2,000 vulnerabilities, 400 exposed secrets, and 175 sets of real personal data.

You do not need to become an engineer to manage this. This guide covers what your site is probably exposing, how to check it yourself, and the fixes that close the holes that show up again and again.

Why vibe-coded sites get breached

The typical vibe-coded breach is not an exotic hack. It is a database or a storage bucket left open to the public because the default was never changed. AI coding tools optimize for a working demo, so the prompt produces features fast while access rules, secret handling, and authentication stay as manual steps the prompt rarely asks for.

Wiz Research documented the pattern in September 2025 after building a scanner for these apps. Four flaws kept repeating. Password checks that ran entirely in the browser. Third-party API keys hardcoded into the JavaScript that ships to every visitor. Supabase tables with Row-Level Security weakened or turned off, leaking user data to anyone with the public key. Admin dashboards and staging environments deployed to the open web with no login at all. Wiz also noted that roughly one in five organizations now build on a vibe-coding platform, so the blast radius is large.

The scale holds up across other scans. Symbiotic Security checked 1,072 vibe-coded apps and found flaws in 98 percent of them. The 2025 Tea app case showed how ordinary the underlying mistake is. Reporting described roughly 72,000 user images, including driver's licenses, and more than a million private messages exposed through a storage system left without access rules. Alongside it sat an API that let one user pull another user's chats. None of that required a sophisticated attacker. It required a public endpoint that was supposed to be private. If you want the wider picture of the trade-offs first, our companion piece on whether vibe-coded websites are bad sets the context.

Know what your platform secures and what it leaves to you

Vibe-coding platforms secure their own infrastructure, but the security of the app you generate on top of it is yours. This is the part that trips up non-technical founders, because the polished result feels finished when the security work has barely started. After the Wiz findings, Lovable published a security best-practices guide of its own, which is a useful signal that the platforms expect you to do this configuration rather than assuming it is handled.

The clearest example is the public database key. Your generator hands the browser an anonymous key on purpose, because the front end needs some way to talk to the database. That key is safe only when the database rules behind it are switched on. Read your platform's security documentation once, so you know which switches are yours to flip. The rest of this guide is the short list of the switches that matter most.

Start by finding out what your site already exposes

You cannot manage a risk you have not measured, and most of a vibe-coded site's exposure is visible from an ordinary browser. The audit below is the same one an attacker would run, so it is worth doing before someone else does it for you.

  • Open your live site, view the page source, and read the loaded JavaScript. Search it for the words key, token, secret, and password. Anything that looks like a credential is readable by every visitor.
  • Open the browser developer tools, watch the Network tab while you click through the app, and read the responses coming back. If a request returns records that are not yours, your access rules are not doing their job.
  • List every database table, storage bucket, and API your app touches, then check each one for whether it requires a login. The ones that do not are your first priority.
  • Run a free external scan with a tool like OWASP ZAP or Mozilla Observatory. Both are free, and they surface the misconfigurations that are easy to miss by eye.

Write down what you find rather than fixing it on the spot, because a short inventory of every exposed table and key turns a vague worry into a list you can clear. Keeping that record is much easier when the build was documented from the start, which is the argument in our note on the development documentation you should require.

Move your secrets out of the browser

Any API key or password that reaches the browser is already public, so treat every exposed secret as compromised and rotate it first. Client-side JavaScript is downloaded in full by every visitor, which means a key sitting in that code is one right-click away from anyone.

There is an important distinction to get right. A public key that is designed to be public, such as a Supabase anonymous key, is only safe when your database rules are switched on behind it. A service key or admin credential carries full access and must never appear in anything the browser can load. The fix has three parts. Rotate any exposed key at the provider so the old one stops working. Store keys as server-side environment variables rather than in the code. Route calls to paid third-party services through a small backend function so the key stays on the server where the visitor cannot see it.

Turn on Row-Level Security before someone else finds it off

Row-Level Security is the rule that decides which rows of your database each user is allowed to read, and on a large share of vibe-coded Supabase projects it is switched off. With it off, the public anonymous key can usually read, and often write, every row in every table. This was the single most damaging flaw in both the Wiz and the Escape research, and it is the one most likely to spill your users' personal data.

Enable Row-Level Security on every table that holds user data, then write a policy so each person can reach only their own rows. Test it the way an outsider would, by opening an incognito window and querying the table with only the public key. If you get back rows that belong to other people, the policy is wrong and needs tightening before you go any further. Supabase publishes clear policy documentation, and the same principle applies to whatever database your generator wired up.

Put authentication and authorization on the server, not in the page

If your login check runs in the browser, it is decoration, because anyone can edit what runs inside their own browser. Real authentication is verified on the server, where the visitor cannot reach in and change the answer. Wiz found client-side password logic often enough that it made their top four, and it fails the moment someone opens the developer tools.

Authorization is the second half, and it fails differently. Even a properly logged-in user has to be checked for what they are allowed to touch, otherwise one account can read another account's data by changing an ID in a request. That is exactly the flaw behind the Tea app chats. Verify every sensitive action against the logged-in user on the server, and put admin routes, staging sites, and internal tools behind real authentication rather than a hidden URL. Where you can, lean on the managed authentication your platform already provides instead of writing your own, since the hand-rolled version is where these mistakes cluster.

Close the injection and input holes

The vulnerabilities AI writes most often are the old, well-understood ones, led by cross-site scripting, which Veracode found AI-generated code failed to defend against in 86 percent of cases. Log injection failed almost as often, at 88 percent. A December 2025 test by Tenzai went further. Every one of the AI coding platforms it tried introduced server-side request forgery, and none of the 15 apps it built came with cross-site request forgery protection.

Most of these have the same shape of fix. Never build a database query by gluing strings together, and use parameterized queries or your framework's query builder so user input cannot change the query's meaning. Encode and escape anything a user submits before it is shown back on a page, which is what stops cross-site scripting. Validate input on the server rather than trusting checks that run in the browser. A modern framework such as Next.js handles a good deal of this by default, which is one reason the tech stack you choose quietly sets how much of this you have to do by hand.

Harden the deployment and hide what should not be public

A site can carry clean code and still leak if it ships without HTTPS, without security headers, or with a staging copy left open to the world. These are settings on the hosting and deploy side rather than the code, and they are quick to fix once you know to look.

Force HTTPS on every page so traffic cannot be read in transit. Add the standard security headers, including a content security policy and HSTS, and confirm them with the free Mozilla Observatory scan mentioned earlier. Take admin panels, internal tools, and staging environments off the public internet or place them behind authentication, since Wiz found these deployed openly again and again. Make sure your environment file was never committed to the code repository, because a secret in your Git history is still a secret you have leaked. Fast, well-configured hosting is also what protects your Core Web Vitals, so this step pays off twice.

Treat security as a standing habit, not a launch-day task

Managing vibe-coded website security is ongoing work, because every new feature the generator adds can reopen a hole you already closed. A prompt that adds a table can leave Row-Level Security off on that one table. A prompt that adds an integration can drop a fresh key into the client code. The audit from earlier in this guide is not a one-time gate, it is something to repeat after any significant change.

Keep your dependencies updated, since most breaches use known flaws that already have patches. Add secret scanning to your workflow so a key is caught before it ever reaches the repository. Watch your logs for access patterns that do not look like normal use. Keep the record of what each part of the app is allowed to do current, which stays manageable only when the project was documented as it was built.

This is the layer we build in from the first commit at fivetwenty.one rather than bolting it on after launch, because retrofitting security onto a live product is slower and riskier than doing it as you go. If you would rather hand the hardening to a senior team, you can see how we work, look at what we have built, or start a project with us.

Got something to build?

Tell us about your product. We come back within 24 hours with a plan, a timeline and a fixed price.