We Scanned 1,072 Vibe Coded Apps, 98% Had Security Flaws!
65,643 URLs crawled. 1,085 confirmed. 6,185 vulnerabilities found.
Automated security study on web applications generated by vibe coding platforms (Lovable, v0, Bolt.new, Replit, Windsurf, Tempo…) using Supabase as their backend.
Overview
Metric | Value |
|---|---|
URLs crawled by discovery | 65,643 |
Unique sites confirmed (after dedup + Supabase verification) | 1,085 |
Sites fully scanned | 1,072 (98.8%) |
Awaiting scan | 12 |
Discovery cycles executed | 2,052 queries across 19 sources |
Total vulnerabilities | 6,185 |
Critical | 431 |
High | 657 |
Medium | 1,907 |
Low | 2,415 |
Informational | 756 |
Average per site | 5.9 vulnerabilities |
Maximum on a single site | 30 vulnerabilities |
Exposure Rates
Indicator | Sites | Percentage |
|---|---|---|
Sites with at least one vulnerability | 1,046 / 1,072 | 98% |
Sites with a critical vulnerability | 173 / 1,072 | 16% |
Sites with critical or high | 313 / 1,072 | 29% |
Completely clean sites | 26 / 1,072 | 2% |
98% of vibe coded applications have at least one security flaw.Only 26 out of 1,072 scanned sites had zero issues detected.
Critical Vulnerabilities in Detail
Data deletion without authentication
172 sites allow anyone to delete records from the database without any authentication. A simple DELETE API call using the public key is enough to wipe entire tables.
Data modification without authentication
172 sites expose PATCH endpoints allowing modification of existing records (user profiles, settings, content) with no identity verification.
Data reading without authentication
39 sites have tables fully readable by anyone who holds the public Supabase key (which is exposed in the page’s JavaScript). All user data, payments, and private messages are accessible.
Sensitive columns exposed through the REST API
34 sites expose columns containing sensitive personal data: emails, hashed passwords, authentication tokens, phone numbers. These columns are directly queryable through the Supabase API.
Data insertion without authentication
14 sites allow writing new rows to the database without authentication. It is possible to inject fake users, fake orders, and fake content.
High Severity Vulnerabilities
Vulnerability | Affected sites | Occurrences |
|---|---|---|
Supabase | 308 | 309 |
CORS misconfiguration on Supabase API | 197 | 198 |
Email confirmation disabled | 69 | 69 |
RPC functions exposed and callable | 44 | 44 |
API key exposed in source code | 24 | 24 |
Upsert possible without authentication | 12 | 12 |
CORS origin reflection | 1 | 1 |
Medium and Low Severity Vulnerabilities
Vulnerability | Sites | Severity |
|---|---|---|
Missing Content Security Policy header | 1,039 | Medium |
Open signup endpoint | 220 | Medium |
GraphQL introspection enabled | 195 | Medium |
Open password reset endpoint | 190 | Medium |
Open magic link endpoint | 138 | Medium |
Exposed RPC functions | 108 | Medium |
JavaScript source maps available | 10 | Medium |
Missing Permissions Policy header | 1,046 | Low |
Missing X Frame Options header | 1,043 | Low |
JWT with excessive lifetime | 308 | Low |
The single most vulnerable site has 30 flaws including 4 critical ones allowing reading, writing, modifying and deleting data without any authentication. Site names are deliberately withheld for responsible disclosure.
Worst Cases (anonymized)
Rank | Critical | High | Total findings |
|---|---|---|---|
#1 | 5 | 6 | 22 |
#2 | 5 | 5 | 20 |
#3 | 5 | 5 | 20 |
#4 | 5 | 5 | 20 |
#5 | 5 | 3 | 18 |
#6 | 4 | 5 | 18 |
#7 | 4 | 4 | 30 |
#8 | 4 | 4 | 19 |
#9 | 4 | 4 | 19 |
#10 | 4 | 4 | 18 |
Publicly Exposed Database Tables
The most frequently accessible tables without authentication across all scanned sites:
Table | Exposed on | Occurrences | Risk |
|---|---|---|---|
| 10 sites | 20 | Business data, emails, phone numbers |
| 8 sites | 15 | Personal user data |
| 7 sites | 14 | Contact forms, private messages |
| 5 sites | 12 | Administrator accounts, credentials |
| 4 sites | 8 | Security configuration |
| 4 sites | 6 | Internal application parameters |
| 3 sites | 6 | User registrations |
| 3 sites | 6 | Payment data |
| 3 sites | 6 | Tracking and analytics |
| 3 sites | 6 | User votes (manipulable) |
| 3 sites | 5 | Roles and permissions (escalation possible) |
| 2 sites | 4 | Financial portfolios |
| 2 sites | 4 | Administrator profiles |
| 2 sites | 4 | Event registrations |
| 2 sites | 4 | Private messages between users |
Tables like admin_users, payments, rading_user_portfolio and chat_messages should never be accessible without authentication.
Informational Data Collected
Type | Count |
|---|---|
Contact/administrator email addresses extracted | 447 |
Supabase URLs identified in source code | 309 |
How Sites Were Discovered
The discovery pipeline crawled 65,643 candidate URLs across multiple cycles. After deduplication and Supabase verification (confirming each site actually connects to a *.supabase.co backend), 1,085 unique sites were retained.
The 19 discovery sources ran 2,052 queries in total. Most candidates were duplicates or sites without an actual Supabase backend. The dedup and verification pipeline reduced 65,643 raw URLs down to 1,085 confirmed targets.
Discovery source | Confirmed sites | Share |
|---|---|---|
Dorking (DuckDuckGo, Bing) | 632 | 58.2% |
Common Crawl (web archive) | 251 | 23.1% |
DNS Enumeration (subdomain bruteforce) | 149 | 13.7% |
Certificate Transparency (crt.sh) | 52 | 4.8% |
Supabase Dorking (Supabase specific search) | 1 | 0.1% |
Total confirmed | 1,085 |
The Scanning Pipeline
Overall Architecture
The scanner operates as an autonomous multi agent system running continuously, 24/7. It combines AI orchestration, multi source passive discovery, and active scanning across 80 security rules.
Step 1: Strategy (CrewAI + MiniMax)
A CrewAI agent powered by the MiniMax language model analyzes the overall system state: how many targets are pending, what types of vulnerabilities are emerging, what priorities should be set for the next cycle. It produces a strategic report that guides the next actions.
MiniMax 2.5 (230b) is a language model running locally on a dedicated server. Every strategic decision goes through it: this is not a simple script, but a contextual analysis that adapts to the evolving results.
Step 2: Discovery (19 sources in parallel)
The system simultaneously launches 19 discovery sources, organized in four categories:
Classic discovery (8 sources)
Certificate Transparency via crt.sh, search engines (DuckDuckGo, Bing), Common Crawl, GitHub Code Search, Wayback Machine, DNS subdomain bruteforce, urlscan.io, AlienVault OTX.
Technical fingerprint discovery (4 sources)
Detection of platform specific signatures in HTML and JavaScript source code. Searches for CSS classes, meta tags, CDN URLs and identifiers unique to each builder. Every candidate is verified: the scanner loads the page and confirms the actual presence of markers before adding it to the database.
Multi platform discovery (6 sources)
Targeted search by platform: v0.dev, Bolt.new, Replit, Windsurf, Tempo Labs, FlutterFlow. Each adapter looks for sites from its platform that use Supabase as their backend. A generic Supabase adapter catches any site using Supabase regardless of the builder.
Creative discovery powered by MiniMax (1 source)
When classic sources stop returning new results, MiniMax takes over. The model receives a system prompt describing all known technical fingerprints for each platform (Lovable, v0, Bolt, Replit, Windsurf, Tempo, FlutterFlow), along with real time statistics from the current cycle: number of targets in the database, number already scanned, platforms covered, results from the last discovery round.
From this context, MiniMax generates 15 original search queries, each paired with its target engine (DuckDuckGo, Bing, or GitHub) and the reasoning behind why this search might uncover new targets.
Here is a real example of queries generated by MiniMax during a cycle:
Engine | Generated query | Model reasoning |
|---|---|---|
DuckDuckGo |
| Find sites exposing their Supabase project identifier in source code |
DuckDuckGo |
| Search for .env files accidentally indexed by search engines containing Supabase URLs |
DuckDuckGo |
| Identify v0 built sites that mention Supabase in their markup |
DuckDuckGo |
| Browse Product Hunt for recent product launches using Supabase |
DuckDuckGo |
| Find Bolt.new projects deployed on custom domains with a Supabase backend |
DuckDuckGo |
| Spot exposed JSON configuration files containing the Supabase anonymous key |
DuckDuckGo |
| Search for Windsurf sites on custom domains using Supabase |
DuckDuckGo |
| Explore the Indie Hackers forum for community projects using Supabase |
DuckDuckGo |
| Identify Tempo Labs applications deployed with a Supabase backend |
DuckDuckGo |
| Detect sites with visible Supabase REST API calls in their URLs |
DuckDuckGo |
| Browse Dev.to articles showcasing Supabase projects to identify demo URLs |
DuckDuckGo |
| Search for the base64 Supabase JWT header signature in indexed page source code |
DuckDuckGo |
| Browse SaaS template directories for demos using Supabase |
DuckDuckGo |
| Explore the Lovable community project directory for custom domains |
DuckDuckGo |
| Find sites calling Supabase authentication endpoints directly |
Each query is executed automatically. Results are filtered to exclude documentation sites, forums, and code platforms. Every candidate domain is then loaded and verified: the scanner only adds it to the database if it actually contains a Supabase URL (*.supabase.co) in its HTML or JavaScript source code.
Because MiniMax uses a temperature of 0.7, the queries vary from one cycle to the next. The model never repeats the same searches and explores different angles on every run: forums, template directories, exposed configuration files, indexed JWT tokens, blog posts with demo links.
All 19 sources run in parallel via asyncio.gather. A complete discovery cycle takes approximately 6 minutes.
Step 3: Scanning (10 modules, 80 rules)
Each discovered site passes through 10 specialized scanners, executed sequentially:
Key Extraction Scanner
Downloads the site’s JavaScript and extracts Supabase keys (anon key, service role key, project URL). Analyzes Vite, Webpack, and Next.js bundles to find environment variables compiled into client code.
RLS Probe Scanner
Attempts to read, write, modify, and delete data via the Supabase REST API using only the public anon key. If an operation succeeds, it means Row Level Security policies are missing or misconfigured.
Deep Supabase Scanner
Queries the PostgREST OpenAPI schema to enumerate all accessible tables and columns. Identifies sensitive columns (email, password, token, ssn, credit_card). Tests access to Supabase Storage (public buckets, anonymous uploads).
Header Scanner
Checks for the presence of HTTP security headers: Content Security Policy, Strict Transport Security, X Frame Options, Permissions Policy, Referrer Policy, X Content Type Options.
Secret Scanner
Searches source code for exposed third party API keys: Stripe, AWS, Firebase, SendGrid, Twilio, OpenAI, and others.
Endpoint Scanner
Tests the accessibility of Supabase endpoints: Auth (signup, login, password reset, magic link), Storage, Functions, GraphQL. Checks whether sensitive endpoints are open without rate limiting.
CORS Scanner
Sends requests with malicious origins to detect CORS misconfigurations: origin reflection, wildcard with credentials, null origin acceptance.
JWT Analyzer
Decodes Supabase JWT tokens to check: signing algorithm, excessive lifetime, assigned role (anon vs service_role), unusual claims.
Info Disclosure Scanner
Searches for information leaks: accessible JavaScript source maps, debug headers, detailed error messages, exposed framework versions.
Email Extractor Scanner
Extracts contact email addresses from scanned sites to enable responsible disclosure of discovered vulnerabilities.
Sites are processed in batches of 100. When all pending sites are scanned, the system automatically triggers a new discovery cycle to find fresh targets.
Step 4: Deep Analysis (MiniMax)
For each critical vulnerability detected, MiniMax performs a full contextual analysis. The model receives raw data from each finding and transforms it into structured assessments.
Business impact evaluation
The model receives a prompt containing the technical details of the vulnerability: rule identifier, name, severity, target URL, description, and evidence collected by the scanner. It produces a natural language assessment of the real impact: what data is at risk, what is the risk for end users, what is the regulatory risk (GDPR, CCPA, HIPAA depending on the data type), and which exploitation scenarios are most likely.
For example, when the scanner detects that the payments table is readable without authentication on an e-commerce site, MiniMax evaluates that customer billing data is exposed, that this constitutes a potential GDPR Article 32 violation, and that the exploitation risk is high because the anon key is already public in the JavaScript.
Exposed data classification
For each table accessible without authentication, MiniMax receives the table name, column list, record count, and a sample of data keys. It then classifies the sensitivity level:
Classification | Example columns detected |
|---|---|
PII (Personally Identifiable Information) | email, phone, full_name, address, date_of_birth |
Financial data | credit_card, bank_account, payment_amount, invoice |
Credentials | password_hash, api_key, token, secret, auth_token |
Medical data | diagnosis, prescription, health_record, blood_type |
Business data | leads, revenue, customer_value, contract_amount |
This classification enables prioritized disclosures: a site exposing credentials or medical data is treated with absolute priority.
Responsible disclosure email generation
When the Email Extractor has found contact addresses on a site with critical vulnerabilities, MiniMax drafts a complete disclosure email. The model receives the site URL and a structured summary of all vulnerabilities found (identifier, name, severity, short description). It produces a professional email containing: an introduction explaining the security research approach, an accessible technical description of each vulnerability, the potential impact for the site’s users, and concrete remediation recommendations (enable RLS policies, configure security headers, restrict CORS).
Executive summary report
At the end of each cycle, MiniMax generates an executive summary from the global statistics and the most critical sites. This summary is sent via Discord webhook to enable real time monitoring of the discovered attack surface.
Continuous Loop
The system never stops. After each complete cycle (strategy, discovery, scan, analysis), it starts over. Every 5 scan batches, an intermediate discovery round is launched to immediately integrate newly found sites. The pause between two cycles is 2 minutes.
The Fundamental Problem
Vibe coding platforms let anyone create a full stack application in minutes from natural language prompts. The generated code is functional, the design is polished, the deployment is automatic.
But security is systematically absent.
Supabase exposes a REST API by default. When a table is created, it is immediately accessible via the rest/v1 API. Without explicitly configured Row Level Security policies, anyone can read, write, modify, and delete all data.
The anon key is public by design. It is embedded in client side JavaScript, accessible to any site visitor. Supabase is designed this way: security relies entirely on RLS policies, not on key secrecy. But code generators do not configure these policies.
Vibe coders do not verify. The code is generated by an AI, it compiles, it works. Why would anyone go check the database security policies? The result: production applications with real user data, completely open.
172 sites allow data deletion without authentication. 39 sites expose their entire database for reading to anyone. Tables named payments, admin_users, chat_messages are publicly accessible.
This is not a theoretical problem. These are production applications, with real users, real data, and zero protection.
Scanner Technical Stack
Component | Technology |
|---|---|
Agent orchestration | CrewAI (Sequential Process) |
Language model | MiniMax (llama.cpp, local server) |
HTTP client | httpx (async) |
Database | PostgreSQL 17 (asyncpg) |
Architecture | Hexagonal (DDD, ports/adapters) |
Discovery | 19 parallel sources (asyncio.gather) |
Scanners | 10 modules, 80 rules (BB-001 to BB-080) |
Notifications | Discord webhooks |
Language | Python 3.12 |
Methodology
All tests are performed in a passive or semi passive manner:
Passive discovery: no direct interaction with targets. Sources (crt.sh, Common Crawl, Wayback, DNS) are public databases.
Active but non intrusive scanning: the scanner sends standard HTTP requests to public Supabase endpoints. It does not exploit any vulnerability, does not modify any data, does not attempt any injection. It simply checks whether endpoints respond to unauthenticated requests.
Automated analysis: MiniMax analyzes results to assess impact and draft disclosure communications.
No data is exfiltrated. The scanner detects the presence of vulnerabilities, it does not exploit them. Examples of exposed data are limited to metadata (table names, column names, row counts)
Is your vibe coded app exposed?
98% of vibe coded applications have at least one security vulnerability. If you've built with Lovable, v0, Replit, Windsurf, or any platform using Supabase your app is likely at risk right now. Talk to our team