Penetration Testing

Vibe-Coded SaaS Pentest 2026: Cursor and Lovable Gaps

Your AI-coded SaaS app is in production. Here's what a founder-led pentest finds in Cursor, Lovable, Bolt, and Copilot-generated code before customers do.

RG&AK
Rathnakara GN & Ashok Kamat
Cybersecify
9 min read

Key Findings (2026 from Cybersecify pentests of AI-generated SaaS apps):

  • Service-role keys exposed in the browser is the top finding: present in roughly 7 of 10 vibe-coded apps Cybersecify pentested in 2026.
  • Missing or permissive Supabase RLS policies appeared in roughly 6 of 10 apps.
  • IDOR between organisations on shared resources appeared in roughly 5 of 10 multi-tenant vibe-coded apps.
  • Missing rate limit on at least one critical auth endpoint appeared in roughly 8 of 10 vibe-coded apps.
  • The 10 patterns below repeat across Cursor, Lovable, Bolt, v0, and Copilot-generated codebases because the AI assistants produce the same shortcuts repeatedly.

Your vibe-coded SaaS is in production. Cursor wrote the Supabase queries. Lovable built the Stripe integration. Bolt scaffolded the admin panel. You shipped fast, hit product-market fit, and now an enterprise prospect is asking for your last security report. A pentest from a real human reviewing AI-generated code finds different things than a SAST scanner does. This guide covers what we actually find in vibe-coded SaaS pentests in 2026, the 10 patterns that repeat across Cursor, Lovable, Bolt, and Copilot-generated codebases, and how to scope a pentest for an AI-built app without paying for unnecessary depth.

Why vibe-coded apps need a different pentest lens

Vibe coding (the practice of building software primarily through natural-language prompts to AI coding assistants) has moved from prototype experiment to production reality. Indian SaaS founders are shipping MVPs in Cursor, Lovable, Bolt, v0, and Replit, raising on the back of paying customers, and integrating Supabase, Stripe, Clerk, and Resend with minimal hand-written code. The AI does the typing. The founder does the prompting.

This works, until it does not. The patterns that fail in vibe-coded SaaS are not exotic. They are the same broken-authorization, IDOR, secret-leakage, mass-assignment classes that broke hand-written apps for a decade. What is new: the AI assistants generate the same shortcuts repeatedly. A vibe-coded SaaS pentest is faster than a hand-written one because the pentester knows exactly where to look. The findings repeat across customers because the AI suggestions repeat across customers.

We test vibe-coded apps with the same OWASP Top 10 + OWASP API Security Top 10 + business logic methodology we use for hand-written apps. The findings cluster differently. This post covers what clusters where.

The 10 patterns we find in vibe-coded SaaS pentests

1. Service-role keys exposed in the browser

The most common finding. Cursor and Lovable both default to generating Supabase client code that uses the service-role JWT rather than the anon JWT in many starter templates. The service-role JWT bypasses Row Level Security and grants full database access. When it ships in a React component or a NEXT_PUBLIC_* environment variable, any user can extract it from the browser bundle and read or write the entire database.

What we find: roughly 7 out of 10 vibe-coded apps have either the service-role key in client-side code, or RLS policies disabled because the developer used the service-role key to bypass them during development and never switched back. Fix: rotate the key, regenerate, run all client code through the anon key with RLS enabled and tested.

2. Missing or permissive Supabase RLS policies

The Supabase Row Level Security model requires the developer to write per-table policies that scope reads and writes to the current user or organisation. Cursor and Lovable generate tables without policies (default DENY ALL, which the developer then circumvents with service-role) or generate over-broad policies (USING (true), which allows any authenticated user to read every row).

What we find: at least 1 critical-severity RLS gap in roughly 6 out of 10 vibe-coded apps. The most common shape: a users or profiles table where any authenticated user can read every row including emails, billing status, internal notes. Fix: per-table policies scoped to auth.uid() or auth.jwt() -> 'organisation_id', tested against a non-owner user account.

3. IDOR between organisations on shared resources

Multi-tenant SaaS apps need to enforce that User A in Org X cannot access User B in Org Y. Vibe-coded apps frequently scope by user ID but not by organisation ID. A user submits a request like GET /api/invoices/12345 and the backend returns the invoice if it exists, without checking that invoice 12345 belongs to the requesting user’s organisation.

What we find: classic horizontal authorization gaps on invoice, project, document, settings, and webhook endpoints. The fix is a single middleware that validates organisation membership on every authenticated route. AI assistants rarely generate this middleware unsolicited.

4. Stripe webhook signature verification missing or broken

Stripe webhooks signal payment success, subscription state changes, refunds, disputes. The webhook handler must verify the Stripe-Signature header against your webhook signing secret. If the verification is missing or broken, anyone can POST a fake invoice.paid event to your endpoint and unlock premium features without paying.

What we find: in vibe-coded apps with Stripe integration, the webhook handler often has either no signature verification, or a try/catch that swallows verification failures and processes the event anyway. Fix: hard fail on signature verification failure, return 400, log the rejection.

5. Admin endpoints reachable from regular user sessions

Cursor and Lovable scaffold admin panels alongside the user-facing app. The admin routes typically check that the user is logged in, but not that the user is actually an admin. Adding ?admin=true to the URL, or simply visiting /admin while logged in as a regular user, often works.

What we find: admin functionality (user management, billing override, content moderation, support actions) accessible to any authenticated user on roughly 4 out of 10 vibe-coded apps. Fix: server-side role check on every admin route, not client-side hide-and-show.

6. Mass assignment on profile and settings updates

A PATCH /api/users/me endpoint that takes a JSON body and spreads it into a database update will accept fields the user should not be allowed to set. Common: role, subscription_tier, credits_balance, email_verified, organisation_owner. The user sends {"role": "admin"} and is promoted.

What we find: at least 1 mass-assignment gap in roughly half of vibe-coded apps with user profile editing. Fix: explicit allowlist of editable fields, never spread-update from request body.

7. Hard-coded secrets in client-side environment variables

Next.js NEXT_PUBLIC_* variables, Vite VITE_* variables, and React REACT_APP_* variables are bundled into the browser-visible JavaScript. AI assistants frequently put API keys for Resend, Stripe, OpenAI, Supabase service-role, and third-party services into these variables for convenience.

What we find: at least 1 secret leaked to client-side bundle on roughly 5 out of 10 vibe-coded apps. Beyond the service-role key (covered in #1), the most common leaks are OpenAI keys (the user can drain your OpenAI credit) and Resend keys (the user can send email from your domain). Fix: server-side env vars only for anything sensitive, with API routes acting as proxy.

8. SSRF via user-supplied URLs in image proxies and webhooks

Vibe-coded apps that allow user-supplied URLs (avatar import, webhook destination, OG image proxy, RSS feed parsing) usually do not validate the URL is not pointing at internal infrastructure. The classic SSRF payload http://169.254.169.254/latest/meta-data/iam/security-credentials/ against a cloud-hosted app extracts the instance’s IAM credentials.

What we find: SSRF reachable on URL-input endpoints in roughly 3 out of 10 vibe-coded apps that have such endpoints. Fix: URL allowlist or block-list, IP range filter (no RFC1918, no link-local, no metadata IPs), DNS rebinding protection.

9. Rate limiting missing on authentication and OTP endpoints

Login, signup, password reset, and OTP verification endpoints in vibe-coded apps rarely have rate limiting. An attacker can brute-force passwords, enumerate accounts via signup error messages, and grind through OTP codes until one works.

What we find: missing rate limit on at least one critical auth endpoint in roughly 8 out of 10 vibe-coded apps. Fix: per-IP and per-account rate limiting on every auth-adjacent endpoint, with progressive lockout on repeated failures.

10. CORS configured to allow any origin with credentials

The starter Next.js or Express middleware often has CORS set to origin: "*" with credentials: true. This is a contradiction the browser silently ignores, but slight variations like reflecting any origin back as the allowed origin do work and allow cross-origin requests with credentials. An attacker can host a malicious page that makes authenticated requests to your API as the visiting user.

What we find: CORS misconfiguration in roughly 4 out of 10 vibe-coded apps. Fix: explicit allowlist of trusted origins, never reflect the request Origin header, no wildcard with credentials.

Why a pentest catches what scanners and CI tools miss

SAST scanners (Snyk, Semgrep, GitHub Advanced Security) catch hard-coded secrets and some injection patterns. DAST scanners (OWASP ZAP, Burp Pro automated) catch obvious misconfigurations and known CVEs. Both miss the structural failures listed above because those require runtime context, valid auth, multi-user state, and an understanding of what the application is supposed to do.

A pentest is a human attacker working with a real user account, trying to violate the application’s intended security boundaries. The findings depend on what the app is supposed to allow versus what it actually allows. No scanner can encode the difference between “the user should be able to read their own invoice” and “the user should not be able to read another organisation’s invoice.” A pentester can, because the pentester read your product description and tested both.

For more on the methodology gap, see our DAST scan vs pentest breakdown.

How to scope a pentest for a vibe-coded SaaS

The scope is the application surface, not the lines of code or the framework used to write them. A typical Cursor or Lovable MVP with the following surfaces fits the Startup Pentest plan at INR 74,999 with 7 calendar day delivery:

  • Web application (React, Next.js, or similar) with authenticated user flows
  • Backend API (Next.js API routes, Express, or Supabase Edge Functions)
  • Supabase database with RLS policies
  • Stripe integration with webhook handler
  • Email transactional flows (Resend, SendGrid, or similar)
  • Single tenant model (one user account, multiple records)

If your app adds any of the following, the Growth Pentest plan at INR 1,79,999 with 10 calendar day delivery and 2 scopes is the better fit:

  • Multi-tenant model (organisations with multiple users)
  • Mobile companion (iOS or Android)
  • Third-party OAuth or SSO integration beyond Supabase auth
  • Compliance requirement (SOC 2 or ISO 27001 evidence pack)
  • AI agent layer with tool calls (see how-to pentest AI agent)

Both plans include a free retest after you fix the findings. The retest verifies whether the fixes actually closed the gaps, and you get a v2.0 report you can show to investors and enterprise prospects.

Founder-led pentest, not auto-scanned report

Cyber Secify pentests are run by Rathnakara GN (OSCP, M.Sc Cyber Security, CompTIA PenTest+), not handed off to a junior or replaced by a scanner. We test what we say we test, we explain every finding in plain language, and we are available on call during remediation to walk through fixes. The sample report at /sample-report/ shows the exact format you would receive for a vibe-coded SaaS engagement.

What happens next

If your app is vibe-coded, in production, and you are 6 to 12 months from a Series A or an enterprise security review, this is the right time to test it. Findings caught now are weeks of work to fix; findings caught during a customer security review are deal blockers.

Book a 30-minute discovery call with the founders to scope your engagement, or request a custom quote if your scope is non-standard. Both options are no-commitment and founder-led.

Frequently Asked Questions

What is vibe coding and why does it create security risk?

Vibe coding is the practice of building working software primarily through natural-language prompts to AI assistants like Cursor, Lovable, Bolt, v0, and GitHub Copilot, rather than writing the code line-by-line. The AI generates Supabase queries, Stripe integrations, auth flows, and API endpoints based on what the developer asked for. The security risk: AI assistants optimise for working code that ships, not secure code that survives an attacker. Defaults skip authorization checks, leak service-role keys to the client, return entire row objects instead of curated fields, and trust client-supplied IDs. A vibe-coded app in production at Series A scale has the same blast radius as a hand-written one, with none of the manual review that catches the common breakage.

Do vibe-coded apps have different security issues than hand-written apps?

The vulnerability classes are mostly the same as hand-written apps (broken authorization, IDOR, mass assignment, secret leakage, missing rate limiting, weak session handling). The difference is concentration: vibe-coded apps reliably fail in the same 10 to 12 patterns because the AI assistants generate the same shortcuts repeatedly. A pentester who has tested 5 vibe-coded apps knows exactly where to look first, which makes the work fast and the findings predictable. Hand-written apps fail in more idiosyncratic ways.

What is the most common finding in a vibe-coded SaaS pentest?

Service-role or admin keys exposed in the browser. Cursor, Lovable, and Bolt frequently generate Supabase client code using the service-role JWT instead of the anon JWT, or hard-code the key in a React component that ships to the browser. A single curl from any user's session can then read or write the entire database without organisational scoping. We find this in roughly 7 out of 10 vibe-coded apps on first scope.

Will running a SAST scanner against my Cursor or Lovable app catch these issues?

Partially. Static analysis catches hard-coded secrets and some injection patterns. It misses the structural failures: missing authorization on a Supabase RLS policy, an IDOR between organisations, a Stripe webhook that does not verify signatures, an admin endpoint reachable from a regular user session. These require runtime testing with a real auth context, which is what a pentest provides and a scanner does not.

How long does a vibe-coded app pentest take?

Comparable to a standard web application pentest of equivalent complexity. The Startup plan (INR 74,999, 1 scope, 7 calendar days) covers a typical Cursor or Lovable MVP with Supabase backend and Stripe integration. If the app has multi-tenancy or extensive third-party integrations, the Growth plan (INR 1,79,999, 2 scopes, 10 calendar days) is the better fit. The scope is the application surface, not the lines of code.

Can I get a pentest before my Series A due diligence even if the app is vibe-coded?

Yes, and you should. Investor security questionnaires and customer security reviews do not ask how the app was built; they ask what was tested and what was fixed. A founder-led pentest report with the technical findings, the remediation walkthrough, and a free retest after fixes is exactly the artefact that closes a security-conscious enterprise deal or unblocks a Series A. The vibe-coded origin is irrelevant if the security posture survives a real test.

Got a question or counter-take?

Email contact@cybersecify.com, WhatsApp +91 9986 998 333, or DM the author on LinkedIn.

Share this article
vibe coding securitycursor securitylovable securityai generated codesaas pentestvibe coded pentest