Is Lovable Safe for Production? The Access-Control Review Problem
Lovable can turn a sentence into a full-stack app, but production data depends on access control the accountable builder must be able to inspect, understand, and approve.
TL;DR: Lovable is one of the fastest ways for a non-developer to ship a real full-stack app. The production risk is specific: the access control that decides who can read user data can end up as generated Supabase row-level-security SQL, written by AI for someone who may not be able to review SQL. A frontend .eq('owner', user.id) filter that makes the demo behave correctly is a request convenience, not a security boundary. CVE-2025-48757, though disputed, documented real exposure risk in Lovable-built apps. “It works” and “it is safe” are different claims, and the person shipping must be able to tell them apart.
Here is the exact shape of the failure, because “vibe coding is risky” is too vague to be useful.
A founder describes an app with user accounts. Lovable builds it, wires up Supabase, and ships. Every user sees only their own records. The founder tests it with two accounts; it behaves perfectly. It is, in the demo, correct.
Now open the browser’s network tab, which many non-developers never open, and watch the request the app actually makes:
// the frontend "scopes" the query to the current user:
const { data } = await supabase
.from('customers')
.select('*')
.eq('owner', user.id) // looks like the security boundary. it isn't.
That .eq('owner', user.id) is a filter, a parameter on a request. Anyone can open the network tab, copy the endpoint, and re-issue it without the filter. What stops them from getting everyone’s rows is supposed to be the row-level-security policy on the table. Here is the dangerous pattern:
-- the RLS policy that is supposed to be the boundary:
create policy "Enable read access for all users"
on public.customers for select
using (true); -- ← evaluates to true for every row, every caller
using (true) means: every authenticated caller may read every row. The policy exists. It is on. And it protects nothing. The app is safe in exactly one configuration: the one the frontend happens to request. It is exposed the moment anyone asks differently. This is not a theoretical class of mistake; public vulnerability reporting has documented real Lovable app exposure tied to this kind of access-control failure.
A Filter Is Not a Boundary
This is the whole concept, and it is worth naming: a filter is a request convenience; a boundary is enforced on the server regardless of the request. The demo works because of the filter. The data is safe only if there is a boundary. The two are indistinguishable from the outside because both make two test accounts see the right thing. That is why a non-developer cannot tell a safe app from an exposed one by using it.
The person Lovable empowers to build the app is often the person least equipped to read the difference between using (true) and a real using (auth.uid() = owner). The capability and the comprehension have been split apart. That split is the product’s magic and its liability at the same time.
What About Lovable’s Security Scanner?
To Lovable’s credit, the company has invested in security scanning and enterprise controls such as SSO and audit logs. So the fair question is: doesn’t that close the gap?
Scanners help, and teams should use them. But a scanner does not transfer accountability away from the builder. The hard question is not only “does a policy exist?” It is “does this policy actually enforce the boundary the business believes it has?” Answering that requires understanding the data model, the user model, and every access path. A security scanner can catch classes of mistakes, but it cannot make an unreadable access-control model reviewable to the non-expert who is accountable for shipping it.
Enterprise controls such as SSO and org audit logs govern how people log into Lovable and how work is tracked at the organization level. They are real and useful, but they are not the same as proving that the per-app access logic the AI generated is correct. The gap is not Lovable’s enterprise posture. It is whether the app’s data boundary is visible and reviewable to the person responsible for it.
The Number Behind the Problem: Verification Asymmetry
Here is the figure that makes the pattern structural rather than unlucky. Compare two costs:
- Cost to build the app: one sentence. Effectively zero, by design — that’s the entire pitch.
- Cost to verify it’s safe: read the generated RLS for every table, reason about every API path, distinguish filters from boundaries. Expert-hours, and a skill the builder doesn’t have.
When build cost collapses toward zero but verification cost stays at expert-hours, the rational behavior of a non-expert is to skip verification because they cannot do it and the app looks done. Multiply that across many apps and you should expect leaks. The specific CVE count is less important than the mechanism: verification asymmetry appears with any tool that lets non-experts generate access control they cannot read.
Where Lovable Is Exactly Right
For a prototype, a landing page, a hackathon build, an internal throwaway, or a fundraising demo, anywhere no real person’s data sits behind the app, Lovable is superb and almost certainly faster than anything more disciplined, us included. The verification asymmetry costs little when there is nothing sensitive to expose. Use it, and enjoy it.
And the honest caveat that keeps this from being a hit piece: this is structural, not just a Lovable defect. Any tool that collapses build cost for non-experts while leaving verification at expert cost inherits the same asymmetry, and Lovable is actively trying to narrow it. The point is not “Lovable bad.” It is that for production data, “the builder cannot read the access control” is disqualifying no matter whose logo is on the builder.
The line is bright: the moment real people’s data lives behind it — customers, patients, employees — “it works” stops being evidence of anything, and “I can’t see the boundary” stops being a convenience and becomes the risk.
A Test You Can Run in Thirty Seconds
Forget the feature list. Ask whoever shipped it:
“Open the network tab, take the data request, remove the filter, and send it. Do you get back only your rows — or everyone’s?”
If they cannot run that test, do not understand it, or the answer is “everyone’s,” the app is a beautiful prototype and not a production system, regardless of how polished it looks or whether a scanner gave it a check mark.
ObjectStack’s Position
ObjectStack inverts the split that causes the leaks. Access control is not generated SQL the builder cannot read; it is declared, readable metadata, such as read: owner == current_user as a property of the object. It is a boundary the runtime enforces server-side, so removing a frontend filter changes nothing. When the AI proposes a change to who-can-read-what, it surfaces as a diff a non-expert can actually approve: “this makes customers readable by everyone; confirm?” It should not appear as silent SQL someone would have to read to catch. And because ObjectStack is self-hostable and sits on systems you already run, sensitive data does not quietly land somewhere you cannot inspect.
We will not beat Lovable on time-to-first-demo, and for prototypes we would not try. The claim is the one that matters the instant real data is involved: the security of an AI-built app has to be visible to the person accountable for it. An app whose boundary you cannot see is not safe; it is simply unverified.