Your app was built with AI. Here's what to check before real users find it.
In March 2025 a researcher scanned the homepages of 1,645 projects from Lovable's public showcase. In 170 of them, about 10.3%, at least one database table answered requests its access rules should have refused.1 This is the owner's side of that problem: what the owner of an app built with Lovable, Bolt, Replit, Cursor or Base44 can check without reading code, what each failure looks like, and where each one has already happened in public. Every check here is written for an app the reader owns, on the reader's own accounts and dashboards. The developer's side is in Is vibe coding bad?
The AI-built app check Book a 15-min intro call
// the law
Only your own app
Section 1 of the Computer Misuse Act 1990 makes it an offence for a person to cause a computer to perform any function with intent to secure access to any program or data held in any computer, where that access is "unauthorised" and the person knows at the time that it is.2 The section does not use the words "written permission". On conviction on indictment, the maximum penalty is two years' imprisonment, a fine, or both.2 The Act is United Kingdom law; other jurisdictions are not covered here.
This is not legal advice.
// data access
Who can read whose data
A Lovable app can keep its data in Supabase, a hosted database that the browser talks to directly. Other builders have their own databases, and the same question applies to each. What stops one visitor reading another visitor's rows is a set of rules on each table, which Supabase calls Row Level Security (RLS). Lovable describes the risk for its own Supabase-connected apps: "if RLS policies aren't created — or if they're set up with overly broad permissions — data from your Supabase database could be exposed."3 Supabase's documentation says "A table in an exposed schema without RLS is readable and writable by any role with a grant on it."4
The flaw was not invented by AI builders. OWASP's 2025 Top 10 keeps broken access control at number one, and its examples include "viewing or editing someone else's account by providing its unique identifier".5
The check. It needs two accounts on the app, both the owner's; two email addresses are enough. Signed in as the second account, the question is whether anything belonging to the first one shows up: an order, a profile, a message, an uploaded file. Pages with a number or a long ID in the address are the ones worth trying with the first account's ID swapped in. The same question then goes to every page that lists records, from a private browser window signed in as nobody. In the Supabase dashboard, the Security Advisor flags tables in the public schema with RLS switched off, and tables where RLS is on but no rule exists.4
What failure looks like. The second account sees the first account's records, or the signed-out window loads a list it shouldn't. In the 2025 scan, the failure was a single altered request returning a whole table of users. On one site the researcher also wrote a new record with "payment_status": "paid" set, bypassing the Stripe integration.1 The researcher worked at Replit, which competes with Lovable. The vulnerability record notes that Lovable disputes it, because "each individual customer of the Lovable platform accepts a responsibility over protecting the data of their application".6
// keys
Which keys the browser can see
Some keys are meant to be public. The same researcher first assumed that a key visible in the browser was the problem. It wasn't, because "Supabase provides public anon keys by design"; the problem was the missing table rules.1
Supabase splits its keys in two. Publishable keys, which begin sb_publishable_, are "Safe to expose online". Secret keys, which begin sb_secret_, are not: "A secret key bypasses every Row Level Security policy you have. Never put one in a browser, a shipped application, or source control." The older service_role key "skips every Row Level Security policy you attach".7 Stripe draws the same line for payments: "Only publishable keys are safe to expose outside your application's backend." Its live secret keys begin sk_live_.8
The check. Chrome's developer tools have a Search panel that finds "text across all loaded resources".9 With the app open and signed in, a search for sb_secret_, sk_live_ and service_role covers the secret keys above. A hit on sb_publishable_ or pk_live_ is expected and is not a finding. The limit: the older service_role key is an encoded token, so the plain words only turn up where the code names the key. An unlabelled key can slip past a text search, which makes this a first look rather than proof.
What failure looks like. A match for a secret key in a file the browser downloaded. Escape, which sells security testing, ran a one-time scan of more than 5,600 public apps it identified as vibe-coded and reported "400+ exposed secrets".10 Its sample came from sources including launch directories, so the figure describes that sample and not AI-built apps in general.
// sign-up
Who can get in
In July 2025 Wiz Research found that private apps built on Base44 could be joined by anyone who knew the app's ID, which was "immediately visible in the URI and manifest". Sending that ID to two undocumented endpoints created a verified account, which got past the app's sign-in controls, single sign-on included. Wix, Base44's owner, fixed it "in less than 24 hours" and said it had found "no evidence of past abuse".11
That flaw sat in the platform, not in one owner's app, so no owner's check would have caught it. The owner's version of the question is smaller: an app meant to be invite-only should refuse a stranger.
The check. A sign-up from a private window, with an email address the app has never seen, on the app's own sign-up page and on any invite or registration link it sends out.
What failure looks like. The stranger's account is created and lands inside an app that was meant to be closed.
// payments
Who decides an order is paid
Stripe's documentation is direct about the page a customer sees after paying: "You can't rely on triggering fulfillment only from your checkout landing page, because it's not guaranteed customers visit that page." Fulfilment is meant to run from webhooks, messages Stripe sends to the app's server, and Stripe recommends checking that each one really came from Stripe.8 An app that unlocks a paid plan because the browser reached a success page has handed the decision to the browser. The "payment_status": "paid" record written from outside in the 2025 scan is the same failure from the other side.1
The check. Two things show in the Stripe dashboard without any code. The first is the list of webhook endpoints: an app taking live payments with no endpoint registered has nowhere for Stripe to report a payment. The second is the mode. Live keys begin pk_live_, rk_live_ and sk_live_; sandbox keys begin pk_test_, rk_test_ and sk_test_.8
What failure looks like. No webhook endpoint for the live account, a paid plan that switches on when the success page loads, or a live site still running on sandbox keys and taking no real money.
// deploys
Where the live data lives, and the way back
In July 2025 Jason Lemkin, founder of SaaStr, wrote that Replit's agent "deleted a production database containing 1,206 executive records and 1,196+ company profiles", then claimed recovery was impossible. The data was recovered in the end.12 Replit's chief executive called it "Unacceptable and should never be possible."12 Replit's announcement on 21 July 2025 began: "Until now, Replit apps used a single database for both development and live customer data, making it challenging to safely test and deploy updates." Its documentation now says the agent "is not able to modify the production database".13
Backups are the way back, and on some plans there aren't any. Supabase's pricing page lists automatic backups as "Not included in free" and says "Free projects are paused after 1 week of inactivity". Its backup documentation adds: "Even with daily backups, you could still lose a day's worth of data."14
The check. Three questions the owner can answer from the dashboards: which database the live app writes to, whether the AI agent can reach that same database, and when a backup was last restored, even into a copy.
What failure looks like. One database for building and for customers, an agent with access to it, and a free-plan project with no backup at all.
// real users
What breaks when strangers arrive
Some failures only show once people outside the team use the app. Supabase's built-in email service is one of them. It "is not meant for production use", and unless a custom mail server is set up, "Supabase Auth will refuse to deliver messages to addresses that are not part of the project's team."15 In testing, the team's own addresses get every email. A stranger signing up may get nothing.
My own app depended on that built-in service too. On 25 July 2026, sign-up, login and password recovery on iziwerk all failed at once, each with a server error about sending email. Custom mail had never been switched on, so every sign-in email had been going through Supabase's built-in service, and that service stopped working. The fix was turning custom mail on, and the first sender address it got was one the mail service had not verified, which broke sign-in emails again for about 20 minutes. Finding the cause meant ruling out the email domain, the keys, the templates and the app's own code first.16
The same day turned up a second fault the outage had been hiding. The sign-in code Supabase sent was 8 digits long and the app's form accepted 6, so anyone signing in with the code instead of the link was locked out with no way through. The link worked, which is why nobody had noticed.16
The check. A real sign-up from an address outside the team, followed to the end: the email arrives, the link and the code both work, and the account lands where it should.
What failure looks like. No email, an email in spam, or a code the form won't accept.
// built-in scanners
What a clean scan means
"No issues found" is what Lovable shows when its last scan found nothing. Its own documentation explains the message: "the last scan did not surface any issues, but the scanner cannot catch every possible risk."3
The other builders describe their scans in their own terms. Base44's says "The scan does not apply fixes automatically." Bolt's puts a security audit button in the Publish menu. Replit's Security Center has a setting, "Block publishing of critical vulnerabilities", that decides whether a critical finding stops a publish.17
In 2025 the researcher behind the Lovable scan described its first scanner as one that "merely checks for the existence of any RLS policy, not its correctness or alignment with application logic."1 Lovable's current documentation describes a deeper scan that reads the app's code for "data that the wrong people can read" and "payment or sign-in flaws".3 Neither statement measures how often a scanner misses. The research for this article found no published measurement of that.
// caveats
What this does not establish
- How common these failures are. The scans cited used different samples and methods, and none of them gives a rate for AI-built apps in general.
- That an app which passes these checks is secure. They are a first look by the owner, not an audit.
- That the incidents caused harm. Wix reported no evidence of abuse, the 2025 Lovable scan did not log in, and Lovable disputes that vulnerability record.
- Anything about Cursor in particular. None of the incidents above involved it.
| Claim | Source | Read |
|---|---|---|
| 1. Scan of 1,645 Lovable showcase projects: 170 (about 10.3%) with inadequate RLS; homepages only, no logins; "payment_status": "paid" record inserted; anon keys public "by design"; first scanner "merely checks for the existence of any RLS policy" | Matt Palmer, Statement on CVE-2025-48757, 29 May 2025. The author worked at Replit | 3 Oct 2026 |
| 2. Section 1 offence of unauthorised access; no mention of written permission; maximum two years on indictment | Computer Misuse Act 1990, section 1, legislation.gov.uk, revised text | 3 Oct 2026 |
| 3. RLS risk for Supabase-connected apps; "No issues found" and "cannot catch every possible risk"; deep scan covers "data that the wrong people can read" and "payment or sign-in flaws" | Lovable, Secure vibe coding and Project security view | 3 Oct 2026 |
| 4. A table without RLS "is readable and writable by any role with a grant on it"; the advisor flags RLS disabled in public and RLS enabled with no policy | Supabase, Row Level Security and Database advisors | 3 Oct 2026 |
| 5. Broken access control at number one; "viewing or editing someone else's account by providing its unique identifier" | OWASP, A01:2025 Broken Access Control | 3 Oct 2026 |
| 6. CVE-2025-48757: insufficient RLS in Lovable through 15 April 2025; disputed by the supplier | MITRE, CVE-2025-48757, published 30 May 2025; NIST, NVD entry | 3 Oct 2026 |
| 7. Publishable keys "Safe to expose online"; a secret key "bypasses every Row Level Security policy"; service_role skips RLS | Supabase, API keys | 3 Oct 2026 |
| 8. Fulfilment can't rely only on the landing page; webhooks and signature checks; "Only publishable keys are safe to expose"; live and sandbox key prefixes | Stripe, Fulfill orders, Webhook signatures and API keys | 3 Oct 2026 |
| 9. The Search panel finds "text across all loaded resources" | Chrome for Developers, Search: Find text across all loaded resources | 3 Oct 2026 |
| 10. One-time scan of more than 5,600 public apps; "400+ exposed secrets" | Escape, Methodology: 2k+ vulnerabilities in vibe-coded apps, 29 October 2025. Escape sells security testing | 3 Oct 2026 |
| 11. Base44 private apps joinable with a visible app ID; fixed in under 24 hours; no evidence of customer impact | Gal Nagli, Wiz Research, Critical vulnerability in Base44, 29 July 2025 | 3 Oct 2026 |
| 12. Production database with 1,206 executive records and 1,196+ company profiles deleted, later recovered; "Unacceptable and should never be possible" | Jason Lemkin, SaaStr; The Register, Replit's response, 22 July 2025, quoting Amjad Masad | 3 Oct 2026 |
| 13. "a single database for both development and live customer data"; the agent "is not able to modify the production database" | Replit, Introducing a safer way to vibe code, 21 July 2025, and Development and production databases | 3 Oct 2026 |
| 14. Automatic backups "Not included in free"; free projects paused after 1 week of inactivity; daily backups can still lose a day | Supabase, Pricing and Database backups | 3 Oct 2026 |
| 15. Built-in email "not meant for production use"; refuses delivery outside the project's team without custom SMTP | Supabase, Send emails with custom SMTP | 3 Oct 2026 |
| 16. iziwerk's sign-in email outage and the 8-digit code against a 6-digit form, 25 July 2026 | iziwerk's own build records, 25 July 2026 | 3 Oct 2026 |
| 17. Base44's scan does not apply fixes; Bolt's audit in the Publish menu; Replit's block-publishing setting | Base44, Running a security scan; Bolt, Security; Replit, Project Security Center | 3 Oct 2026 |
Vendor documentation read on 3 October 2026; product pages and plans change often. The checks describe what an owner can look at on their own app. None of them is a security audit.
Send me the app.
A fixed-price check, €350 over 2 working days: data access, sign-in, payments, deploys and what breaks with real users. The report reproduces every finding, gives it a severity and prices the fix per item.
The AI-built app check Book a 15-min intro call
The service this describes: AI-built app check