Skip to content

Security basics

Vibe coding security scanner: what a URL scan misses

A vibe coding security scanner reads your live app from outside. Here is what that covers, the four things it cannot see, and how to read the result.

Vlad Tkachenko9 min read
One lit pane of an app seen straight on, with two more panes receding behind it into shadow, unreadable.

In short

  • A vibe coding security scanner reads what your visitors' browsers already download: your bundle, your headers, your certificate, and the answers your database gives a stranger.
  • That covers the whole class of mistakes AI builders make most often. It covers nothing that happens on your server.
  • A clean result means every question the scan could ask from outside came back clean. Treat it as one fewer thing to worry about.

You paste your app's address into a scanner, wait about twenty seconds, and a letter comes back. A, maybe C. Then the question that actually matters arrives: does this mean my app is fine?

Here is the part most tools in this category leave you to work out on your own. A vibe coding security scanner reads your app from the street. It sees what any visitor's browser sees, which turns out to be a great deal, and it stops at your front door. Whatever your server does in private stays private from the scanner too.

Knowing where that line falls is what makes a scan worth running. An A tells you the doors facing the street were shut when we looked, and it says nothing at all about the room behind them.

What is a vibe coding security scanner?

A tool that loads your live app the way a visitor would, then reads what came back.

You hand it a URL. It does not ask for your source code, your repository, your database password or an account on the builder you used. It fetches your page, lets the JavaScript run so it can see the code your app actually ships, reads the headers that came with the response, looks at your certificate, and asks your database and your file storage a few questions any stranger could ask.

Then it writes down what answered. That is the whole shape of it, and it is why this takes twenty seconds instead of a week.

The category exists because apps built with Lovable, Bolt, v0, Cursor, Replit, Windsurf and Base44 tend to go wrong in the same small number of places, and almost all of those places are visible from outside. A secret key in the bundle. A table that answers a stranger. A storage bucket that lists its own contents. Nobody needs your source to find any of them, because your app hands them to every visitor by design.

What a scan actually reads

Five surfaces, and your own visitors download four of them without noticing.

What it readsWhere that comes fromWhat it catches
Your JavaScript bundleThe files a browser downloads to run your appKeys shipped to the browser, the API paths your app calls, table names it uses
Your response headersSent back with every page your host servesMissing browser protections, a rule that answers requests from any website
Your database's answersThe same project API your app itself callsA table handing rows to a request with nobody signed in
Your storage bucketsThe same public storage API your app uploads throughA bucket that will list its own files for a stranger
Your certificate and domainThe TLS handshake, and the public registry recordA certificate about to expire, a domain about to lapse
Five surfaces arrive in a browser, so a scan can read them. The four behind the rule never leave your server, so nothing outside can.

The bundle is the one that surprises people. Your app's code has to arrive in the browser before it can run there, so every key in it arrives too, along with the API paths it calls and often the names of the tables it reads. A scanner presses the same F12 a curious visitor would press. It is only faster, and it reads every file instead of the first one.

The database question is the one people expect to be invasive, and it is the tamest thing on the list. To find out whether a table is readable by strangers, ours asks the API for a count of the rows and reads the number off a response header. A count above zero means those rows are reachable. No row is ever fetched, and the key it asks with is the publishable one already sitting in your bundle, which is supposed to be there.

The four things a URL scan cannot see

Everything that happens on your server, because none of it is ever sent to a browser.

Your server code. Edge functions, API routes, database functions, anything running inside Supabase or on your host. A scanner can call an endpoint and read what comes back. It cannot read the code that produced it, so a mistake that only appears on certain inputs stays invisible.

Your environment variables. The keys you kept on the server, which is exactly where they belong. A scan can tell you it did not find a secret in your bundle. It cannot confirm that the secret is stored properly, because it never sees the place you stored it.

Your version history. A key you committed in March and removed in April is gone from your app and still sitting in your repository. Anyone who can see that repository can still read it, and no amount of looking at your live site will turn it up.

Your app's own logic. Whether one signed-in user can open another user's order by changing a number in the address. Whether a form will accept a price the browser sent it. These are decisions your app makes about what to allow, and catching them means signing in and trying things, which is a penetration test.

There is a fifth limit that belongs to us rather than to the category, and it is worth knowing before you read one of our reports. Supabase no longer serves the list of tables in a project to a publishable key, so a scanner has no way to ask what your tables are called. Ours works from three sources instead: the project index on older projects where it still answers, the table names it finds in your own bundle, and a list of twenty-six names that vibe-coded apps commonly use. An open table with an unusual name that never appears in your frontend code is one we will not reach. Supabase's own advisor will, which is the comparison two sections down.

Does a clean scan mean my app is secure?

No. It means every question the scan could ask from outside came back clean, and that is a smaller sentence than it sounds.

Part of the reason is the four blind spots above. The other part is that a check can end three ways and only one of them is a pass. A check finds something. A check asks and gets a clear no. Or a check gets no answer at all, because the request timed out, the host refused it, or the page never finished loading.

The third ending is the one to look for. A check that got no answer is drawn as no answer, because a tick there is a promise about a question nobody managed to ask.

That third ending is the one that decides whether a report can be trusted, and it is the easiest to quietly round up into a tick. Ours prints "Couldn't check" on the line and leaves your grade alone. A false tick is the most damaging thing this scanner could put on a screen, because you would act on it.

The same honesty is what makes our own published numbers less alarming than they first look. Between 12 and 14 August 2026 we ran these checks over 30,998 live vibe-coded apps, and 99% of them came back with at least one finding. Nearly all of that is a single line: browser safety headers the hosting platform never sets, which most owners on a builder subdomain cannot switch on themselves. Counting it is correct. Reading 99% as "almost every app is in danger" is not.

URL scan, repo scan, or Supabase's own advisor?

They read three different things, so the useful question is which one can see the problem you have.

KindWhat it readsWhat it needs from youWhere it is blind
URL scannerYour live app, from outsideA URLAnything your server keeps to itself
Repository scannerYour source code and its historyAccess to your repoWhether that code is deployed, and what your rules do live
Supabase Security AdvisorThat project's own configurationYour Supabase accountEverything outside the project: bundle, headers, other vendors

They overlap far less than the names suggest. Supabase's advisor scans your project and reports configuration problems, including tables with row-level security misconfigured. A URL scan reads the consequence, which is whether those rows are reaching strangers right now. The two come apart more often than you would expect, because switching the setting on is not the same as being protected.

A repository scanner is the only one of the three that can find the key you deleted last month. It is also the only one that cannot tell you whether the code it just read is the code you have deployed.

How to read the grade

The letter is capped by the worst single finding on the report, so a good score never rescues a serious one.

Every scan starts at 100. A critical finding costs 40 points, a high 15, a medium 5, a low 1. Then a ceiling sits over the arithmetic: one critical caps the grade at D, two cap it at F, and one high finding caps it at C. An otherwise tidy app with a single open table comes out a D, which is the intended behaviour.

Things you got right appear on the report and cost you nothing. Your publishable Supabase key sitting in your bundle is listed as correct, because that is what it is for, and painting it red is how a tool teaches you to ignore red.

What to do with a scan result

What to do

  • Read the lines that say "Couldn't check" first. Those are the questions still open, and they are not passes.
  • Work in severity order. A critical finding means your data is reachable today; a missing header is a setting nobody has switched on.
  • Handle the inside separately: keep secret keys on the server, search your own version history for keys you deleted, and sign in as a test user to see what they can reach.
  • Scan again after a deploy, and after anyone touches a database rule. That is the change nothing tells you about.
  • If your app takes payments or holds health records, book a penetration test eventually. An automated external check is not an audit, and no absence of findings is a guarantee.

Our own free website security scanner runs nine read-only checks on any live URL in about twenty seconds, with no account. It reads, it never writes, and it never signs in.

If you would rather go through it by hand first, the 10-minute security checklist covers the same ground in the order worth doing it in.

FAQ

What is a vibe coding security scanner?

A tool that loads your live app the way a visitor would and reads what came back: the JavaScript your app ships to the browser, the headers your host sends with it, the certificate, and the answers your database and file storage give to a request from a stranger. It needs a URL and nothing else. It reports what it found on the public surface of your app, which is where apps built with AI builders most often go wrong.

Is it safe to scan my own app?

Yes, when the scanner only reads. Ours makes the same kind of requests one ordinary visitor makes, never signs in, never writes, creates or deletes anything, and never downloads your users' data. To test whether a database table is readable it asks for a count of the rows and reads the number, without fetching a single row. The traffic is a handful of requests, which is less than one person browsing your site for a minute.

Does a scan need my source code or my database password?

No. A URL scanner works entirely from outside, so there is nothing to connect and no credentials to hand over. That is also its limit: it can only see what your app already shows every visitor. A tool that reads your repository or connects to your database account sees different things, and the article above sets the three side by side.

Does it work with Lovable, Bolt, Cursor, Replit, v0, Windsurf and Base44?

Yes, and with anything else that puts a live site on the internet, because the scan looks at what is deployed rather than at what wrote it. The builder matters for the fix rather than for the check: the repair for an open table is a different set of clicks in Lovable than in Replit, which is why the fix text names your builder.

What does a security scanner not check?

Anything that stays on your server. Your server code and database functions, the environment variables you kept out of the browser, the key you committed and later deleted from your repository, and bugs in your own logic such as one signed-in user being able to load another user's order by changing a number in the address. Finding that last group means signing in and trying things, which is a penetration test rather than a scan.

Is a vibe coding security scanner free?

Ours is, for the scan itself: you get the grade, the score and the counts on screen in about 20 seconds with no account, and the detailed findings and fixes after you give an email address. Paid plans exist for what a one-off scan cannot do, which is notice when something changes next month. A grade is true the second you take it.

Written by

Vlad Tkachenko

Founder, Reeve

I spend my time looking at apps built with Lovable, Bolt, v0, Cursor and Replit, and at the short list of mistakes that keep turning up in them.

More about the author

Read next

All articles

Not sure where your own app stands?

Run a free scan and get a plain-language grade from A to F in about 20 seconds. No account, no card.

Scan your app free

Automated external check, not a full audit. Absence of findings is not a guarantee of safety.