← All guides

We Scanned 456 AI-Built Apps on GitHub. Here's What We Found

Updated 2026-10-15

AI app builders make it easy to ship. We wanted to know what that code looks like from a security point of view, so we pointed the PreflightPR scanner at 456 public GitHub repositories built with tools like Lovable, Bolt, v0 and GPT Engineer, and then checked the scanner's own results by hand.

This page reports aggregate numbers only. We do not name any repository or owner, we did not test any key we found, and we did not contact or open anything on these projects.

The short version

Finding Repos Share
Committed a .env file to git 89 of 456 19.5%
Committed a private secret we confirmed by hand (service_role key, server secret in .env, client secret, private key, API key) 14 of 456 3.1%
Hard-coded a Supabase service_role key 5 of 456 1.1%
Has a Supabase policy letting anonymous users update or delete rows (using (true)) 14 of 87 with Supabase migrations 16.1%
Creates a table that never gets Row Level Security enabled (confirmed by hand) 6 of 87 with Supabase migrations 6.9%
Has at least one dependency with a published security advisory 394 of 456 86.4%

Finding 1: one in five repos commits a .env file

89 of 456 repos (19.5%) had a .env file tracked in git. The good news is that most of these are harmless: in 63 of the 89, every variable used a public prefix like VITE_ or NEXT_PUBLIC_, which in practice means a Supabase URL and the anon key. Those values ship to the browser anyway.

The rest is where it matters. By hand we confirmed 6 repos whose committed .env held real-looking server-side secrets: things like JWT signing secrets, email app passwords, image and AI provider API keys, a database password, and a Google OAuth client secret. Once a file like that is pushed, deleting it is not enough. It stays in git history and the keys need to be rotated.

If this sounds like your project, our guide on rotating leaked Supabase and OpenAI keys walks through it.

Finding 2: anon keys everywhere (fine), service_role keys in 5 repos (not fine)

118 repos (25.9%) had a Supabase JWT hard-coded in source. We decoded the role inside each token (without using it). Almost all were anon keys, which are designed to be public, so we do not count those as a problem.

But 5 repos (1.1%) hard-coded a service_role key, in frontend files, scripts, or SQL migrations. A service_role key skips Row Level Security completely, so anyone who finds it can read and write the whole database. Across all checks, we confirmed private secrets in 14 repos (3.1%). Treat that as a floor, not a ceiling (see limitations).

Finding 3: Supabase policies that let anyone write

87 repos included Supabase SQL migrations, so we could read their database rules. We looked for policies that apply to anonymous visitors and use using (true) or with check (true), which means "no condition at all."

Policy type (anonymous or public role) Repos Share of 87
Anyone can read a table (select) 45 51.7%
Anyone can insert rows 33 37.9%
Anyone can update or delete rows, or do everything (all) 14 16.1%

Public reads and inserts are often intentional (a product catalog, a contact form). Public update and delete rarely are. In the examples we read, these covered things like student and faculty records, abandoned carts and applications. Any visitor with the anon key from the frontend could change or wipe them.

We also confirmed 6 repos (6.9%) that create a table and never enable RLS anywhere in their migrations. One caveat: RLS can also be switched on in the Supabase dashboard, which we cannot see from the repo.

The Supabase RLS checklist shows how to write tighter policies.

Finding 4: dependencies age fast

394 of 456 repos (86.4%) had at least one package with a published advisory in their lockfiles. The median affected repo had 27 such packages. Most are build tools pulled in by Vite and friends (for example vite itself in 302 repos), which matter less in production. A few ship to users:

AI builders scaffold a project once and rarely bump versions afterward, so the lockfile you got on day one is often the one you launch with.

What we left out, and why

We ran every check in the scanner, then hand-checked samples. Some checks were too noisy to publish as a rate:

These misses are already on our list of scanner improvements.

Methodology

Limitations

Check your own app

Most of these problems take minutes to fix once you know they're there. Run a free scan on your repo to see if any of them apply to you, or start with our pre-launch security checklist.

Check your repo in about a minute

Paste a public GitHub URL and get a free launch score.

Run a free scan

More guides