Skip to content

The State of Vibe-Coded App Security 2026

30,998live apps
9passive checks
Aug 12 –⁠ 14scan window
Aug 19, 2026first edition
Reeve research

We looked for live apps built with Lovable, Bolt, v0, Replit or Base44, then ran each one through the same nine checks anybody can run free on the Reeve home page. This page is what came back.

Your app could be in this sample. Nothing here names it, so the only way to see where yours stands is to run the same nine checks on it

Outside view only. We read what a visitor's browser already reads: the code the app ships, the headers it sends back, the endpoints named in its own code. No logins, no password guessing, nothing downloaded. Method ↓

No app is named here or in the data file. Each figure carries the method that produced it, and the file at the bottom holds every aggregate in one table if you want to check the arithmetic.

Every app, graded

452 apps, about one in 69, sit at D or F
A23,62176% , grade A, 23,621 apps
B4,95816% , grade B, 4,958 apps
C1,9676% , grade C, 1,967 apps
D4441% , grade D, 444 apps
F8<1% , grade F, 8 apps

Six numbers that tell the story

These six figures are the report. Everything after them is the base each one sits on, and how we got it.

  1. Security headers1/6
    99%

    of the 30,998 apps we scanned had at least one finding. Most of those were moderate, and nearly all of them are missing browser security headers.

  2. Database access2/6
    57%

    of the Supabase-backed apps we could reach let a stranger read at least one table without logging in: 2,096 of 3,680.

  3. Database access3/6
    394

    apps had a readable table whose name looks like people's data: users, profiles, orders. One request, no password.

  4. Exposed secrets4/6
    1in23

    apps ship a secret key in public code: 1,332 in total. Only 3 of them shipped the master database key. That is rarer than the usual panic implies.

  5. Source maps5/6
    13%

    publish source maps, which means the original source is sitting in the browser's developer tools. That is 3,885 apps.

  6. Grade distribution6/6
    76%

    earn an A. The ordinary checks mostly pass. The serious failures sit in the database layer.

Platform defaults fail almost everywhere, and most of those failures are moderate. The settings only the person who built the app can change fail far less often, and they are the ones that put somebody's data on the open internet.

How these apps grade, A to F

Reeve grades the way a school report does. Findings knock points off 100 by severity. Then the worst single finding puts a ceiling on the result: one critical finding anywhere and the app can score no higher than D, one high finding and no higher than C.

How every app we could classify grades

23,621 · 76% , grade A, 23,621 apps
4,958 · 16% , grade B, 4,958 apps
1,967 · 6% , grade C, 1,967 apps
444 · 1% , grade D, 444 apps
8 · <1% , grade F, 8 apps

That is 452 apps with a hole a stranger could walk through today.

Most apps land in A or B. The D and F band is small. Those are the apps where a stranger can already read somebody's rows.

What we checked, and how many apps failed each

Each check asks one question about the app from outside, and each one is counted over the apps where it got an answer. If a check could not reach an app, that app drops out of that check's base rather than counting as clean. The scan prints "Couldn't check" for those, and this page does the same.

Scroll sideways to see the share and the worst case.

Findings per check
CheckAppsOfShareWorst seen
Security headersBrowser protections the hosting platform should send30,75630,98199%up to Medium
Cross-site sharingThe app's API answers any website that asks6,86730,92622%up to High
Source mapsThe original code published next to the app3,88530,98713%up to Medium
Database accessDatabase tables readable without logging in2,09626,2498%up to Critical
Exposed secretsKeys that belong on a server, shipped to browsers1,33230,9984%up to Critical
Storage bucketsFile storage anyone can list from outside79227,2693%up to High
Domain renewalRegistration lapsing soon, or already lapsed5530,980<1%up to High
SSL certificateCertificate expired, expiring or untrusted3230,851<1%up to High
Private filesConfig files and dumps left at public paths830,749<1%up to Critical

Each share is over the apps that check could answer. The dot is the worst version of that problem we saw in the row, not the typical one.

Two rows read worse than they are. Security headers are instructions the hosting platform sends to the browser, and a missing one leaves one class of attack with one fewer obstacle in front of it. A published source map is the app's original code sitting beside the compiled version: it shows an attacker where to look, and hands over nothing on its own.

A row can also read severe because a handful of apps in it shipped something serious while the rest shipped something ordinary. The data file breaks each row out by key type so you can see which is which.

More than half of checkable Supabase apps leak table data

This is the number we kept coming back to.

A Supabase project is open to the internet by design. The app running in the browser talks to the database directly, using a key that is meant to be public, and the thing standing between a stranger and the rows is Row Level Security: a rule on each table. Switch that rule off, or write a policy that lets everyone in, and any table in the project can be read with one request and no password.

57% 2,096 of 3,680

8,429 apps in this sweep name a Supabase project. The check got an answer from 3,680 of them. The rest sit behind backends we do not follow, so we leave them out. Of the 3,680, 2,096 had at least one table a stranger can read with a single request and no password.

Fewer than half the apps that name a Supabase project can be checked at all. Some send their database traffic through their own backend, where a check from outside cannot follow, so we say nothing at all about those. The share above is over the apps that answered.

1,702 apps expose tables with generic or technical names: settings, content, logs.

394 apps expose tables named like personal data: users, profiles, orders, messages.

The split is the useful part. A readable table called settings or content is a mistake. A readable table called users, profiles or orders is other people's personal data on the open internet, and whoever built the app almost certainly believes it is private.

The check never reads a row. It asks the database how many rows would be visible and reads the count back out of a response header. That is enough to tell a table with an RLS rule from a table without one, and the check goes no further.

The same nine checks, split by builder

Each app is grouped by the builder it was published with, and measured against the other apps on that builder.

Scroll sideways to see the two Supabase columns.

By builder, on default publish domains only
BuilderAppsAny findingD–F gradesUse SupabaseReadable database
Lovable18,55499%2% 407 apps35%57%of 3,553
Base445,438100%<1% 2 apps27%too few checkable apps to publish a share
Replit3,04299%<1% 9 apps1%too few checkable apps to publish a share
v01,790100%0% 0 apps1%too few checkable apps to publish a share
Bolt1,123100%1% 15 apps24%77%of 35

The last column is the share of that builder's Supabase apps the check could answer on, with that base printed beside it. A dash means too few checkable apps to publish a share at all. Treat it as a gap in our data, and draw no conclusion about how safe those apps are.

The marked row sends database traffic through the builder's own backend. A check from outside cannot follow it, so those apps are unmeasured here.

Apps on custom domains cannot be tied to a builder from outside. They are not in this table.

Most of what this table compares is defaults. Nobody picks Lovable or Bolt for its security headers. The platform sets those for every app it hosts, so one change there moves a whole column of this table.

Two limits before anyone quotes a row. We attribute apps by publish domain, so an app that moved to a custom domain sits outside this table entirely, and those are often the more finished ones. And a builder that routes database traffic through its own backend cannot be checked from outside at all. A blank there means we could not measure, and says nothing about how safe those apps are.

Two kinds of findings, two kinds of fixes

Findings on this page fall into two groups, and the two need fixing by different people.

What the platform controls

up to High

When nearly every app on a host is missing the same header, that is not tens of thousands of people making one mistake. It ships with the hosting. One change on the platform's side would fix every one of them.

  • Security headers99%
  • Source maps13%
  • Domain renewal<1%
  • SSL certificate<1%

What only you control

up to Critical

No host can tell which of your tables should be public, or which key belongs on a server. Every critical finding in this report is on this side.

  • Cross-site sharing22%
  • Database access8%
  • Exposed secrets4%
  • Storage buckets3%
  • Private files<1%

The first group is a product decision at a company. One edit to a hosting default moves every app on that platform at once, which is why those rows come out so uniform and why they are the cheapest findings here to fix.

The second group is on the person who built the app. No hosting platform can know which of your tables are meant to be public, or which key belongs on a server. Every critical finding in this report sits in that group. The per-builder safety guides and the launch checklist both start there.

What vibe-coders get right

We counted what passed, over the same apps.

96%ship no secret of any kind in their public code.

97%of the storage we could check is locked to outsiders.

99%serve a valid certificate.

A publishable key in the frontend is supposed to be there. We mark those OK and explain why.

Generic scanners usually get the last one wrong. A publishable key in the frontend (a Supabase anon key, a Stripe publishable key) belongs there: it is designed to be read, and the protection lives in the rules behind it. Flagging it sends somebody off to change a setting that was already correct.

How we measured, and where the limits are

Where the apps came from

Three lists, merged and de-duplicated: apps people posted on X and Reddit, apps launched on Show HN, and apps we enumerated from the builders' own publish domains. The publish domains are the bulk of the sample and the only list that scales. The other two can only find an app somebody chose to post about.

Dead hosts came out first, and we judged that by reading the page itself. A deleted deployment often still answers a perfectly cheerful 200 OK.

The denominator rule

Every percentage here is over the apps that check could answer, never over the sample as a whole. A check that could not reach an app leaves that app out of its own base, and it is never counted as clean. The two numbers beside each bar are that base, so anyone can see which one they are reading.

56 apps returned too little to classify either way. They are out of every number on this page. We did not count them as clean.

Grades are counted over a smaller number for the same reason. An app that returned too little to classify is dropped from every figure above rather than graded on a guess.

What we did, and did not do

  • Passive reads only: the requests a visitor's browser already makes, plus the public endpoints the app itself points at.
  • The database check takes a row count from a response header. We never read a row, downloaded a file, logged in or guessed a password.
  • No app is named, here or in the data file. A list of apps paired with their weaknesses is a target list, and we do not keep one in publishable form.

Limits worth knowing

  • The sample leans towards newer apps. An app that has moved to a custom domain cannot be tied to a builder from outside, and those are often the more established ones.
  • Colour in a row marks the worst case we saw, which can be one app among hundreds. The data file breaks each row out by exact key type.
  • This is a three-day window in August. An app fixed the following week still counts here as it stood on the day we looked.
  • An automated external check is not an audit. Absence of findings is not a guarantee.

Use these numbers

Journalists, researchers and anyone writing about this are welcome to reuse the data with attribution. The file below holds every aggregate on this page in one flat table, and names no app.

Reeve. The State of Vibe-Coded App Security 2026. 30,998 live apps scanned August 12, 2026 – August 14, 2026. reeve.page/research/vibe-coded-app-security-2026

Data licensed CC BY 4.0: reuse it, credit Reeve, and link back. The file holds every aggregate on this page, and names no app.

10

Questions

Can you tell me which apps had which problems?

No. Counts and percentages only, never names, and the data file holds exactly what the page shows. A list of apps paired with their weaknesses is a target list, and we will not produce one.

My app might be in this data. What should I do?

Scan it yourself. It is the same nine checks, it takes about twenty seconds, and it shows your grade and what a stranger can already see. Nothing on this page identifies anyone, so that is the only way to find out where you stand.

Is a readable database table really that serious?

If anyone on the internet can pull those rows with one request and no password, yes. A readable settings table is sloppy. A readable users or orders table is a data breach that nobody has noticed yet.

Why do you count publishable keys as fine?

A Supabase anon key is supposed to be public. The protection is the database rules behind it, not the key itself. Tools that flag those keys train people to ignore the next warning, which may be the one that matters.

Will you run this again?

Yes. The scans keep running and the next edition follows them. The data file records the window these numbers came from, so an old copy cannot pass for a current one.

Where does your app land?

The same nine checks, on your app, free. A grade and a report in plain language in about 20 seconds.

Security reportyour-app.com
C

Grade · Score 72/100

Secret keysA secret key is exposed in your codeHigh
Database protectionRow-level security is onOK
Scan your app free