AppLedger › Guides › State of vibe-coded app security 2026

State of vibe-coded app security, 2026

We ran AppLedger's free security check on 100 public GitHub repositories built with Lovable (50) and Claude Code (50). Here is what the scanners found, what it means for your app, and what a scan like this can't see.

Data collected 2026-10-14 · Download the aggregate data (JSON) · Methodology and limitations

In short

68 of 100 repositories (68%) had at least one problem marked “Fix before sharing”, and only 2 of 100 had no findings at all. The most common causes were packages with a known critical vulnerability (46% of repositories) and secrets files such as .env committed to git (37%). JWT-format tokens (16% of repositories), which are often public Supabase keys, and publishable keys are not counted here: AppLedger reports them as something to check, not as a leak. Leaving out committed secrets files too, whose contents we didn't open, the share is 49%. These are signals from a small, non-random sample, not a measure of all AI-built apps.

Headline numbers

68%had at least one “Fix before sharing” problem (68 of 100).Without committed secrets files: 49%
46%used a package with a known critical vulnerability (46 of 100).High or critical: 91%
46%had an exposed-secret finding (46 of 100), from file names or pattern matches.Many may be public keys
28.5/100median security score: Lovable 32, Claude Code 27.Higher is better

What we found

Grades

Grade distribution by builder Grade A: Lovable 1, Claude Code 5; Grade B: Lovable 2, Claude Code 6; Grade C: Lovable 4, Claude Code 6; Grade D: Lovable 19, Claude Code 6; Grade F: Lovable 24, Claude Code 27 0 6 12 18 24 1 5 A 2 6 B 4 6 C 19 6 D 24 27 F Lovable (n=50)Claude Code (n=50)
Number of repositories per grade (A best, F worst). Grades come from AppLedger's score: every finding lowers it, “Fix before sharing” findings the most. A: 6, B: 8, C: 10, D: 25, F: 51 of 100.

Why repositories were marked “Fix before sharing”

Reasons for 'Fix before sharing'Share of all scanned repositories with each kind of 'Fix before sharing' finding; one repository can have several. Critical-severity package 46% 46 of 100 repos Secrets file in git (.env…) 37% 37 of 100 repos JWT-format token in code 16% 16 of 100 repos Risky code pattern 5% 5 of 100 repos Other key in code 1% 1 of 100 repos Publishable key in code 1% 1 of 100 repos
Share of all 100 repositories with each kind of “Fix before sharing” finding. A repository can have several. Under AppLedger's current rules 68 of 100 had at least one (JWT-format tokens and publishable keys are no longer counted as “Fix before sharing”).

Most common problem categories

Most common problem categoriesShare of all scanned repositories with at least one finding in each category. High or critical package 91% known vulnerability Exposed-secret finding 46% file name or pattern match Critical package 46% known vulnerability Risky code pattern 45% any level Secrets file in git 37% contents not read Other key-like string 31% mostly low-confidence hints Container setup problem 17% Dockerfile, Kubernetes JWT-format token in code 16% often a public Supabase key
Share of repositories with at least one finding in each category, at any level. Package findings count known vulnerabilities in the lockfile, including indirect dependencies; 91% had a known-vulnerable package of any severity.

Lovable compared with Claude Code

Lovable compared with Claude Code Fix before sharing: Lovable 70%, Claude Code 66%; Fix before sharing, strict: Lovable 38%, Claude Code 60%; Critical-severity package: Lovable 38%, Claude Code 54%; Exposed-secret finding: Lovable 62%, Claude Code 30%; Secrets file in git: Lovable 46%, Claude Code 28%; JWT-format token in code: Lovable 30%, Claude Code 2%; Risky code pattern: Lovable 22%, Claude Code 68%; Container setup problem: Lovable 4%, Claude Code 30% Fix before sharing 70% 66% Fix before sharing, strict 38% 60% Critical-severity package 38% 54% Exposed-secret finding 62% 30% Secrets file in git 46% 28% JWT-format token in code 30% 2% Risky code pattern 22% 68% Container setup problem 4% 30% Lovable (n=50)Claude Code (n=50)
Lovable: median score 32, median 15 vulnerable packages per repo. Claude Code: median score 27, median 9.5. The two groups differ in more than the tool (Lovable projects share one React/Vite/Supabase starting point; Claude Code projects use many stacks), so this is a description of these samples, not a ranking of the tools.

The groups differ in what they trip over. In the Lovable sample, secret findings were common (62% had one), made up of a committed .env (46%) or a JWT-format token in code (30%), which in Lovable's Supabase setup is often the public anon key. In the Claude Code sample, critical package vulnerabilities (54% against 38%), risky code patterns (68% against 22%) and container setup problems (30% against 4%) were more common, so its strict “Fix before sharing” share was higher (60% against 38%).

Packages that showed up most often with known vulnerabilities

PackageRepositoriesShare
source-map-js61 of 10061%
nanoid57 of 10057%
postcss56 of 10056%
react-router53 of 10053%
lodash53 of 10053%
@remix-run/router48 of 10048%
postcss-selector-parser44 of 10044%
brace-expansion43 of 10043%

Many of these are indirect dependencies that the app pulls in through its framework or build tools. A known vulnerability is not always reachable in a running app, but updating is usually the cheapest fix.

Packages behind the critical findings

PackageRepositoriesShare
next16 of 10016%
proxy-addr14 of 10014%
websocket-driver8 of 1008%
protobufjs8 of 1008%
anyio7 of 1007%
pyjwt6 of 1006%

Risky code patterns found most often

PatternRepositories
Text patterns built from changing input (can freeze the app)15 of 100
Someone could read files on your server13 of 100
File names built from changing input11 of 100
Raw HTML inserted into pages (dangerouslySetInnerHTML)4 of 100
Text patterns that can be made very slow (ReDoS)3 of 100
Someone could run commands on your server3 of 100

Code patterns need a human look: a pattern is only a real problem if input from users or other systems can reach it. The scanner also raised lower-confidence “worth a look” hints, most often for HTML built inside text strings (30 repositories) and Log or message text built from changing input (27); these are not counted above.

What this means if you build apps with AI

Your app inherits old packages

Most apps sit on hundreds of open-source packages. If the lockfile was created months ago and never updated, it keeps versions with published vulnerabilities, which attackers can look up as easily as you can. Updating them is usually a single command plus a test.

A committed .env is a public .env

On a public repository, anyone can read every file in the history. In Lovable projects the .env often holds only the Supabase address and the public anon key, which is fine. Anything else in it, such as a service_role, Stripe secret or OpenAI key, should be treated as leaked and replaced.

Not every token is a secret

The Supabase anon key is a JWT and is meant to be in front-end code, as long as row-level security protects every table. The service_role key is also a JWT and must never be there. A pattern scanner can't tell them apart without reading the value, so check which one yours is.

Code patterns need a second look

Findings such as text patterns built from input, redirects or raw HTML are only dangerous if user input reaches them. Ask your AI tool to explain each one and show where the input comes from.

What to do

  1. Run the free check on your own app: pip install appledger, then python -m appledger path/to/your-app, or add it to Claude Code (how). It is the same engine we used for this report.
  2. Fix every “Fix before sharing” item first. For keys: create a new key at the provider, revoke the old one, then store the new one outside the code. Removing it from the latest commit is not enough.
  3. Update outdated packages (npm update or npm audit fix), run the app, and check again.
  4. Check what no code scanner can see: row-level security in Supabase (its Security Advisor helps), who can log in, and whether one user can reach another user's data. See the Lovable and Bolt guide.

Check your own app before you share it.

Run the free check

Methodology and limitations

Sample
100 public GitHub repositories: 50 built with Lovable, 50 built with Claude Code. Collected and scanned on 2026-10-14.
Lovable
Found with GitHub code search for lovable-tagger in package.json or “Welcome to your Lovable project” in README.md; the marker was verified at the repository root after cloning.
Claude Code
Found with GitHub code search for a root CLAUDE.md containing common build terms (for example “npm run dev”, “pip install”, “supabase”); kept only with an app manifest (package.json, requirements.txt, pyproject.toml, go.mod…) at the root or one level down, and without Lovable markers. A CLAUDE.md shows Claude Code was used, not that it wrote all of the code.
Both groups
Pushed in 2026; not forks, GitHub templates or archived; names, descriptions and topics suggesting templates, starters, tutorials, examples or agent/prompt tooling were excluded; at least 5 source files; at most 50 MB. Candidates were shuffled with a fixed seed and taken in order until 50 per builder were scanned. Lovable: 166 reviewed, 50 scanned; skipped: 101 not pushed in 2026, 9 over 50 MB, 5 fork/template/archived, 1 template/tutorial/tooling by name. Claude Code: 70 reviewed, 50 scanned; skipped: 8 over 50 MB, 4 not pushed in 2026, 4 template/tutorial/tooling by name, 3 marker not verified, 1 under 5 source files.
Engine
AppLedger 0.2.2, using the same steps as the hosted check: only files a hosted check would upload (no ignored, media, data or secrets files), scanned with Trivy 0.74.0 (vulnerability database of 2026-10-13) and Opengrep 1.30.2, plus AppLedger's check for secrets files tracked by git (by file name only). Shallow clones, one at a time; each clone was deleted right after its scan.
Score
Starts at 100; each “Fix before sharing” finding keeps 75% of the score, each “Fix soon” 93%, each “Good to know” 99%. Grades: A 90+, B 75+, C 55+, D 30+, F below 30.
Security only
The scores, grades and levels on this page leave out Opengrep rules whose own category is not “security”, for example jsx-not-internationalized (portability), react-props-spreading (best-practice), dockerfile-source-not-pinned (best-practice). Those style and translation rules fire on almost every React app and would push most scores to zero without saying anything about security. With them, the median score is 0; both versions are in the data file.
Limitations: read before quoting

How to cite

AppLedger (2026). State of vibe-coded app security 2026: an aggregate scan of 100 public repositories built with Lovable and Claude Code. https://appledger.net/reports/vibe-coded-app-security-2026/

Data: data.json (aggregate and anonymous, CC BY 4.0). Found a mistake? Write to bruno@contenta-software.com and we will correct it here.

Related guides