ONE FEATURE, ONE REGRESSION: HOW LOVABLE APPS DRIFT AFTER LAUNCH
A clean Lovable app at launch is not durable. Incremental feature additions reliably introduce new authorization gaps — most often a new table without an RLS policy, a new API route without an ownership check, or a new integration with an inlined secret. This catalog documents the regression shapes, the feature types that trigger them, and the structural fix.
This is a longitudinal-shape catalog, not a snapshot. The structural finding is that a clean scan at launch is not durable on Lovable: incremental feature additions reliably introduce new authorization gaps because the generator’s table-creation step does not consistently emit the matching RLS policy. The same logic applies to API routes (missing ownership check) and new integrations (inlined secret).
The point is structural — a one-time pre-launch audit does not protect a Lovable app over time. Continuous scanning on deploy is the only defense that survives the regression curve.
Catalog scope
| Field | Value |
|---|---|
| Window | Feb 2026 – Apr 2026 |
| Source | Anonymized builder-consented tracking of Lovable apps post-launch + gapbench reproducible scenarios |
| Pattern observed in | Both production (with paying users) and demo/pre-launch cohorts |
| Reproducibility anchor | supabase-clone (new table without RLS), multi-tenant-saas (new route without scope), agent-app (new integration with leaked key), ref-rls (clean control) |
We do not publish a cohort N, regression-rate percentages, or a weekly attrition curve because the underlying tracking is anonymized and not a uniform random sample of all Lovable apps. The regression shapes themselves — what regresses, why, and how to detect it — are reproducible against gapbench in seconds.
What regresses
The classes of new finding we observe in re-scans, ranked by relative frequency.
| Regression class | Relative frequency | Why |
|---|---|---|
| New table without RLS | Most common | Generator adds the table, does not emit alter table … enable row level security or a base policy |
| New API route without ownership check (BOLA) | Common | New handler matches authentication boilerplate but skips the ownership scope |
| New integration with leaked secret | Common | New service requires a key; AI inlines VITE_*/NEXT_PUBLIC_* env without warning |
| New form without input validation | Less common | Reflected XSS or unsafe SQL where allow-list/parameterization was skipped |
| Other (CSRF on new mutator, CORS opened on new route) | Less common | Middleware reapplied inconsistently across new routes |
The modal shape is “a new table is added, and the RLS policy that was correct on the existing tables is not added to the new one.” The Supabase dashboard shows the new table without an “RLS Enabled” badge, but no warning is surfaced to the builder.
What features cause regressions
Feature additions ranked by how reliably they introduce a new regression, based on what we observe across the tracked cohort. Some changes add risk; some are neutral.
| Feature type | Regression risk on next scan |
|---|---|
| New resource type (new table) | Highest |
| New permission tier (admin role, team plan) | High |
| New integration (Stripe, OpenAI, third-party API) | Moderate |
| File upload | Moderate |
| New page or view (no new data) | Low |
| Cosmetic changes (style, copy) | None observed |
Adding a new resource type (a new table) is the highest-risk change a builder can make on Lovable. New permission tiers — adding an admin role to an app that previously had only one user type — are the second-highest risk because they introduce a new field that the existing RLS policies do not understand.
The pattern in detail
Across the modal regression shape, the sequence is consistent:
- App launches clean. RLS is enabled on every table; policies restrict reads to the row owner.
- Builder asks the AI to add a new feature: “let users add line items to invoices”.
- The AI creates a
line_itemstable with a foreign key toinvoices. - The AI does not add RLS or any policy to the new table.
- The Supabase dashboard shows the new table with no RLS badge.
- The next deploy ships an app where every line item is publicly readable.
The fix is structural — Lovable’s generator could trivially add alter table line_items enable row level security and a default policy on every table-creation step. As of April 2026, it does not consistently do so.
CWE / OWASP mapping per regression class
Each regression class has a distinct CWE / OWASP fingerprint. Triage and fix are different per class.
| Regression class | CWE | OWASP | Fix shape |
|---|---|---|---|
| New table without RLS | CWE-862 Missing Authorization | A01 · API1 BOLA | alter table X enable row level security + base policy in the same migration |
| New API route without ownership check | CWE-639 Auth Bypass via Key · CWE-284 | A01 · API1 BOLA | Scope the query by auth.uid() = owner_id server-side; return 404 not 403 |
| New integration with leaked secret | CWE-798 Hard-coded Credentials | A02 · A05 | Server-only env; route through backend handler |
| New form without input validation | CWE-20 Improper Input Validation · CWE-79 / CWE-89 | A03 Injection | Allow-list fields; parameterized queries; output-encode reflected values |
| Other (CSRF on new mutator, CORS opened on new route) | CWE-352 / CWE-942 | A05 / A01 | Middleware reapplied; cross-origin allow-list scoped |
The CWE-862 → CWE-639 split matters operationally: the modal regression is missing authorization (the new table has no policy at all, easy to find with one anon-key probe) while the next-most-common is bypassed authorization (the route exists but does not check the right thing, which requires a two-session cross-account probe to detect). The reason missing-authorization dominates is that adding a table is usually a single AI prompt away, while adding a route handler frequently invokes “authentication boilerplate” that gives the false impression of authorization.
The fix patterns per regression class
The mechanical fix per class is short. The trap is doing the fix once (on the table that surfaced the regression) instead of systemically (on the generator step that creates the pattern).
-- Class 1: every new table needs RLS + a base policy at creation time.
-- Wrap this into a Supabase migration template the generator always emits.
alter table line_items enable row level security;
create policy "owner_select" on line_items for select using (auth.uid() = (select user_id from invoices where invoices.id = line_items.invoice_id));
create policy "owner_modify" on line_items for all using (auth.uid() = (select user_id from invoices where invoices.id = line_items.invoice_id));
// Class 2: every new route handler scopes by the authenticated user.
// Wrap this into a helper or framework convention so it is harder to forget.
const session = await getSession(req);
if (!session) return new Response(null, { status: 401 });
const project = await db.project.findFirst({
where: { id: req.params.id, owner_id: session.userId, tenant_id: session.tenantId },
});
if (!project) return new Response(null, { status: 404 });
# Class 3: every new integration has its key in server-only env.
# A pre-commit check that scans for VITE_*_KEY / NEXT_PUBLIC_*_KEY catches the
# moment the AI suggests it.
grep -rE 'VITE_[A-Z_]*KEY|NEXT_PUBLIC_[A-Z_]*KEY' src/ && exit 1 || exit 0
The structural fix — and the one that breaks the regression curve entirely — is to put the check itself into a generator template, a helper, or a CI rule, so the AI’s next “add a feature” prompt cannot skip it. Telling the builder to “remember to add RLS” does not work; the regression rate measures exactly how reliably the human-in-the-loop forgets.
The apps that stay clean
The apps in the tracked cohort that did not regress have one of three things in common:
- They have not added new features after launch (effectively static apps).
- Their builder manually writes RLS policies after every Lovable iteration and runs a re-scan before each deploy.
- They have only added cosmetic changes — style updates, copy changes, no new tables.
We have not observed a Lovable app actively adding features over a multi-month window without manual intervention and remaining clean.
What this means
For Lovable builders: assume your app will regress. The cheapest defense is automated re-scanning on deploy. Do not rely on a one-time pre-launch audit.
For Lovable: the longitudinal regression shape is a stronger signal than any snapshot benchmark. If the platform’s marketing says “secure by default”, the empirical test is what happens to a clean app after three feature additions, not what happens at the moment of launch.
For other AI builders: the pattern is structural and likely applies wherever generators incrementally extend a schema. Bolt’s main regression class is secrets-in-bundle on new integrations rather than RLS gaps (because most Bolt apps don’t use Supabase). Cursor’s main regression class is missing ownership checks on newly-added API routes.
Methodology
Source. Anonymized builder-consented tracking of Lovable apps post-launch between Feb 2026 and Apr 2026, plus the deliberately vulnerable scenarios on the gapbench public benchmark that mirror each regression shape. We do not publish a cohort N or regression-rate percentages because the engagement portion is anonymized by design and not a uniform random sample of all Lovable apps.
Snapshots. Periodic automated scan using the same probe set as the main catalog. Findings de-duplicated against the previous snapshot to identify new (regressed) findings.
Feature classification. Surface-level diffs between snapshots — new pages, new forms, new resource types — clustered into discrete “features” by manual review. We acknowledge this is approximate without access to commit logs.
Limits. The regression-shape ranking is directionally meaningful; absolute frequencies would have wide confidence intervals if we tried to publish them with the underlying engagement sizes.
Calibration via gapbench. The regression shapes in this catalog — new table without RLS, new route without ownership check, new integration with leaked key — each map to a deliberately vulnerable scenario on gapbench.vibe-eval.com. A reader can verify the detection (against the public benchmark) without needing access to the tracked cohort URLs. The clean control (ref-rls) demonstrates what “added a table without regressing” looks like when the policy is added in the same migration step.
Reproduce on the public benchmark
The longitudinal cohort apps are not public for builder-privacy reasons. The reproducibility anchor for each regression class is the matched gapbench scenario:
| Regression class | Equivalent scenario | URL |
|---|---|---|
| New table without RLS | Supabase clone (RLS off on multiple tables) | /site/supabase-clone/ |
| New API route without ownership check | Multi-tenant SaaS | /site/multi-tenant-saas/ |
| New integration with leaked secret | Indie SaaS, Agent app | /site/indie-saas/, /site/agent-app/ |
| New form without input validation | LLM-rendered HTML | /site/llm-rendered-html-markdown/ |
| Clean control (added tables without regression) | ref-rls | /site/ref-rls/ |
For the structural argument behind why generator-driven schemas regress on every iteration unless the access-control step is templated, see The Supabase service-role key in your frontend bundle and BOLA in AI-generated CRUD.
Sources and references
- gapbench regression-shape scenarios. supabase-clone, multi-tenant-saas, agent-app, llm-rendered-html-markdown, ref-rls (clean control).
- Supabase Row Level Security docs. supabase.com/docs/guides/database/postgres/row-level-security.
- CWE-862 Missing Authorization, CWE-639 Auth Bypass via Key, CWE-798 Hard-coded Credentials, CWE-20 Improper Input Validation, CWE-79 XSS, CWE-89 SQLi, CWE-352 CSRF, CWE-942 Permissive CORS. cwe.mitre.org.
- Companion catalogs. Supabase RLS Misconfiguration Atlas, BOLA in AI-generated CRUD.
Citations
VibeEval. One Feature, One Regression: How Lovable Apps Drift After Launch. May 2026. https://vibe-eval.com/data-studies/lovable-regression-longitudinal-study/
Related
- Pattern walkthrough: BOLA in AI-generated CRUD — the modal regression class for new API routes
- Pattern walkthrough: The Supabase service-role key in your frontend bundle
- Pattern walkthrough: Mass assignment — common companion to the new-permission-tier regression
- Data study: 2026 AI App Security Benchmark
- Data study: Supabase RLS in the Wild
- Data study: Lovable vs Bolt vs Cursor — Same Spec — the snapshot before the regression curve starts
- Data study: Honeypot Supabase — time-to-abuse measured from the attacker side
- Safety review: Is Lovable Safe?
- Guide: Is My Lovable App Secure? Builder Checklist
RUN IT YOURSELF
Each scenario below is live on the public benchmark. The commands are copy-paste ready. Outputs may evolve as we tune the scenarios; the bug stays.
curl -s 'https://gapbench.vibe-eval.com/site/supabase-clone/rest/v1/line_items?select=*' -H 'apikey: ANON_KEY'
curl -s https://gapbench.vibe-eval.com/site/multi-tenant-saas/api/projects/1 -H 'Authorization: Bearer USER_B_TOKEN'
curl -s https://gapbench.vibe-eval.com/site/agent-app/ | grep -oE 'sk-(proj-)?[A-Za-z0-9_-]{40,}'
curl -s 'https://gapbench.vibe-eval.com/site/ref-rls/rest/v1/line_items?select=*' -H 'apikey: ANON_KEY'
COMMON QUESTIONS
DETECT REGRESSIONS AS THEY HAPPEN
VibeEval re-scans on every deploy and alerts on new findings. Catch the regression before users do.