Adding a chatbot or an "AI summary" button is one of the first things people build with Lovable, Bolt, v0 and Cursor. Every one of those features runs on a paid API key from OpenAI, Google Gemini, Anthropic or a similar provider. So we asked a simple question: in apps built this way, who can spend that key?
We sampled 535 public GitHub apps that were pushed to in the last two months, scanned them with the PreflightPR engine plus a set of AI-specific checks, and then read every flagged result by hand.
This page reports aggregate numbers only. We do not name any repository or owner, we did not test or use any key we found, and we did not call any of the endpoints described below. Every finding comes from reading code.
The short version
| Finding | Apps | Share |
|---|---|---|
| Calls an AI model (OpenAI, Gemini, Anthropic, Lovable AI and others) | 185 of 535 | 34.6% |
| Has a server endpoint that calls an AI model | 104 of 185 AI apps | 56.2% |
| Has an AI endpoint anyone can call, with no login check and no rate limit (confirmed by hand) | 32 of 104 | 30.8% |
| Puts the developer's own AI key into the browser bundle (confirmed by hand) | 6 of 185 | 3.2% |
| Committed a real-looking AI provider key to git (confirmed by hand) | 8 of 185 | 4.3% |
| At least one of the three problems above | 43 of 185 | 23.2% |
In plain terms: roughly one in five AI-powered apps in our sample lets a stranger spend the owner's AI budget. None of these need any hacking skill. A leaked key can be copied, and an open endpoint can be called in a loop from a script.
Finding 1: a third of AI-built apps now call an AI model
185 of 535 apps (34.6%) call an AI model somewhere in their code. It varies a lot by builder:
| Found via | Apps | Call an AI model | Share |
|---|---|---|---|
| Lovable markers | 142 | 78 | 54.9% |
| Cursor rules files | 136 | 50 | 36.8% |
| Bolt markers | 103 | 35 | 34.0% |
| v0 markers | 154 | 22 | 14.3% |
Which providers they use (an app can use more than one):
| Provider | AI apps | Share of 185 |
|---|---|---|
| OpenAI | 84 | 45.4% |
| Google Gemini | 69 | 37.3% |
| Anthropic (Claude) | 59 | 31.9% |
| Lovable AI Gateway | 55 | 29.7% |
| Groq | 20 | 10.8% |
| OpenRouter | 18 | 9.7% |
| Others (DeepSeek, xAI, Mistral, Perplexity, Hugging Face and more) | 24 | 13.0% |
Lovable apps lean heavily on Lovable's own AI gateway, which bills usage to the workspace that owns the app. That matters for Finding 2: an open endpoint on the gateway burns the owner's Lovable credits instead of an OpenAI bill, but the cost is still real.
Finding 2: 31% of AI endpoints are open to anyone
The safe way to use an AI key is to keep it on a server and expose a small endpoint that your frontend calls. 104 of the 185 AI apps (56.2%) do this, mostly with Supabase Edge Functions (67 apps) and Next.js or serverless API routes (36 apps).
The catch is that the endpoint itself becomes the thing to protect. We hand-reviewed every AI endpoint our scanner flagged as having neither a login check nor any rate limiting, and confirmed 32 apps (30.8% of apps with AI endpoints) where, based on the code, anyone on the internet can trigger a paid AI call as often as they like:
- 21 were Supabase Edge Functions. Many builders assume these are private because Supabase checks a JWT by default. But the anon key counts as a valid JWT, and it ships in every Supabase frontend. Unless the function calls
supabase.auth.getUser()(or similar) and rejects anonymous users, anyone who opens your site has what they need to call it. Four of the 32 had JWT checks switched off entirely withverify_jwt = false. - 11 were Next.js or serverless API routes with no session check at all.
- Several were open relays: they accept any message list or system prompt from the request body and pass it straight to Claude or Gemini. Someone else can use these as a free, anonymous chatbot paid for by the app owner.
- Others were expensive by design: speech-to-text, image analysis and "generate a full report" functions with token limits of 4,000 to 8,192 per call.
A typical example is an edge function that reads { messages, system } from the request, adds the owner's Anthropic key from Deno.env, and forwards everything. It is only a few lines of code, and it works perfectly in a demo, which is why it ships.
To fix it, see our guides on rate limiting OpenAI API routes and securing Next.js API routes. For Supabase Edge Functions, check the user at the top of the function and return 401 when there is none, then add a per-user daily cap stored in a table.
Finding 3: keys built straight into the frontend
Six of the 185 AI apps (3.2%) read their AI key from a browser-public environment variable such as VITE_GEMINI_API_KEY, VITE_OPENAI_API_KEY or NEXT_PUBLIC_GEMINI_API_KEY, and call the provider directly from the browser.
Variables with these prefixes are copied into the JavaScript bundle at build time on purpose, so the key is readable by every visitor in the browser's developer tools, even though it never appears in the repo. Five of the six used Gemini.
We did not count four more apps that call providers from the browser with a key the user types in (a "bring your own key" design). That is a different trade-off and does not expose the developer's key.
More on this in why NEXT_PUBLIC and VITE_ keys are public.
Finding 4: AI keys committed to git
Our secret scan covered the full git history of every app, using provider-specific patterns for OpenAI, Anthropic, Gemini, Groq, OpenRouter, xAI, DeepSeek, Perplexity, Replicate and Mistral keys. After hand review, 8 apps (4.3% of AI apps, 1.5% of all apps) had committed a real-looking AI provider key:
- Gemini in 3 apps, and OpenAI, Anthropic, OpenRouter, Groq and DeepSeek in 1 each.
- Places they turned up: a committed
.envfile, a.env.examplethat held a real key instead of a placeholder, a key hard-coded as the fallback value in an edge function, a key pasted into a deployment checklist and a setup doc, and a Gemini key written directly into an API route's URL (three different keys over the repo's history). - Only 2 of the 8 were still in the current code. The other 6 had been deleted, but they stay readable in git history. Deleting a key from the code does not revoke it; the provider still accepts it until you rotate it.
If this applies to you: how to check whether your keys leaked on GitHub and how to rotate leaked Supabase and OpenAI keys.
By builder
Share of AI-using apps with at least one confirmed problem (open AI endpoint, key in the browser bundle, or committed key):
| Found via | AI apps | With a confirmed problem | Share |
|---|---|---|---|
| Bolt markers | 35 | 11 | 31.4% |
| Cursor rules files | 50 | 11 | 22.0% |
| Lovable markers | 78 | 17 | 21.8% |
| v0 markers | 22 | 4 | 18.2% |
The groups are small, so treat these differences as rough. The bigger point is that no builder is immune: in every group, roughly one AI app in five or more had a problem.
How precise are these numbers?
Automated checks over-report, so we only publish counts we confirmed by reading the code. Here is how each automated check held up against hand review:
| Check | Flagged automatically | Confirmed by hand | Precision |
|---|---|---|---|
| "Calls an AI model" (random sample) | 25 | 24 | 96% |
| AI provider key committed to git (all hits) | 10 | 8 | 80% |
| AI endpoint with no auth and no rate limit (all hits) | 38 | 32 | 84% |
| Developer AI key shipped to the browser (all candidates) | 30 | 6 | 20% |
The false positives were things like test fixtures, a saved Gmail web page that contained Google's own browser key, webhooks that verify a secret, functions that only accept the service-role key, a health-check route, and apps where users paste in their own keys. The browser-key check was the noisiest because many projects keep server code inside src/, which looks like frontend code at first glance. A second, file-level review found real open AI functions in 2 apps we had first marked as false positives, so the endpoint count is 32, not 30.
These checks are now built into the PreflightPR scanner, tuned against the hand labels above. On that labeled set, the scanner's open AI endpoint check is 97% precise (31 of 32 flags), the browser key check is 100% precise (6 of 6), and the committed AI key check is 100% precise (8 of 8). The browser check now only fires when a real-looking key value is committed, or when code reads a server-only provider key (OpenAI, Anthropic, Gemini, Groq and similar) through a browser-public variable.
Methodology
- Date: collected and scanned on October 20, 2026.
- Finding repos: GitHub repository and code search for markers that AI builders leave behind:
lovable.dev,gpt-engineerandlovable-taggerfor Lovable;bolt.newfor Bolt;v0.devandv0.appfor v0; and.cursorrulesor.cursor/rulesfiles (plus "built with Cursor" in a README) for Cursor. That gave 9,301 unique repos. We removed repos that were in our first study, so none of these apps were counted before. - Recently active only: we kept non-fork, non-archived, non-template repos between 30 KB and 80 MB that were pushed to on or after August 20, 2026, which left 4,804. The median app in the final sample had its last commit on October 6, 2026.
- Sampling: we randomly sampled 185 repos from each of the four builder groups (740 total), cloned 738, and removed 1 exact duplicate. We then removed 194 repos that were not apps (awesome lists, docs, readme-only repos) and 8 copies of AI builder tools themselves (for example self-hosted Bolt clones), since those are not apps built with a builder. Final N = 535.
- Scanning: each repo was scanned locally and read-only with the PreflightPR engine (gitleaks over full git history, Semgrep rules, OSV-Scanner and our Supabase checks), plus AI-specific checks: provider-specific key patterns across full history, AI SDK and API usage, browser-public AI key variables, and server endpoints (Supabase Edge Functions, Next.js and serverless API routes, server actions) that call a model without a login check or rate limit.
- Hand review: every committed-key hit, every AI endpoint flagged as open, every browser-key candidate, and a random sample of 25 apps flagged as using AI.
Limitations
- Repo is not the live app. A key might already be rotated, an endpoint might sit behind a gateway we cannot see, and an env variable might not be set in production. We did not test any key or call any endpoint.
- Public repos only. Private repos may look better or worse.
- Markers bias the sample. Each group is "repos that carry this builder's fingerprint", and the four groups were sampled equally, so the overall percentages are a blend, not a census of all AI-built apps.
- Endpoint counts are a lower bound. We counted an endpoint as protected if it contained any login or rate-limit code, even when that code might not actually block anonymous users. Some apps we counted as safe are probably not.
- Small groups. Per-builder numbers rest on 22 to 78 AI apps each.
Check your own app
If your app has an AI feature, ask three questions: Is the key only on the server? Does every AI endpoint require a logged-in user? Is there a per-user limit? The free scan now checks all three findings from this study: AI endpoints (Supabase Edge Functions, including ones with verify_jwt = false, and Next.js API routes) with no login check or rate limit, AI keys exposed through VITE_ or NEXT_PUBLIC_ variables, and committed OpenAI, Anthropic, Gemini (including Google's newer AQ. key format), Groq, OpenRouter and other AI keys. Paste your public repo to check it in about a minute, or install the PreflightPR GitHub App to scan every push, including your full git history, and get fixes as a pull request.