Back to Common risks

Common risksPayments and money

A paywall the browser enforces and the server ignores

A quota counter in localStorage in front of a paid model route is not authorization. Anyone can clear storage, edit the counter in devtools, or POST to the route directly and spend your API bill.

What can go wrong

AI apps often gate paid generation with a client-side counter: dailyUsage or generationQuota read from localStorage immediately before fetch("/api/generate"). If the matching server route checks nothing but process.env.OPENAI_API_KEY before calling the model, the counter is theater. The route is a public endpoint that burns your money.

It happened for real

Enrichlead (Mar 2026) shipped subscription enforcement only in the browser; users cleared devtools and maxed API keys (Autonoma failure taxonomy, Mar 2026).

How to check yours

Seatbelt flags this automatically (partial). Repo read puts client-side quota shapes on the agent checklist with the paths to open; URL read soft-flags storage-gated calls to paid routes in served code. A checklist line means open the route yourself.

Honest holes: a server-side check that lives behind an abstraction the scan cannot follow, or metering done by a third-party gateway, may look missing when it is not.

Ask your agent: "Open every route that calls a paid model API. What runs before the SDK call: a rate limiter, a usage row, a Stripe meter, or session auth? If nothing does, add one."

Manual check: call the generate endpoint with curl while signed out. If it returns model output with no auth header, the client counter was theater.

Fix direction

Enforce quota, rate limits, or session auth in the server handler, before the model call. The browser counter can stay for UX; it just cannot be the enforcement.

Paste into your agent: "In every API route that calls a paid model, enforce a server-side check before the SDK call: session auth plus a usage row or rate limiter. Reject unauthenticated calls."

Related risks

withseatbelt-risk-client-only-paywall

# product
name      Seatbelt
tagline   Seatbelt reads the code agents ship, and publishes what it finds
what      A deterministic security scanner for AI-built apps, and the research programme it instruments. The engine is the instrument; dated findings are the output.
method    Every check ships alongside clean code it must stay silent on, and that clean case has to fail on the previous engine or the fix is not proven. 571 corpus cases run on every change; 284 of them are the clean half. Published at /how-it-works.
findings  /labs. Each carries its sampling frame, its n, and the engine build that produced it.
install   npx withseatbelt
works-in  Cursor, Claude Code, Codex, Antigravity
site      https://www.withseatbelt.com
contact   hello@withseatbelt.com

# current-page
path         /risks/client-only-paywall
title        A paywall the browser enforces and the server ignores · Seatbelt risk reference
description  A localStorage quota counter before a paid model route is theater. Anyone can POST directly and spend your bill.

# risk
slug      client-only-paywall
title     A paywall the browser enforces and the server ignores
summary   A localStorage quota counter before a paid model route is theater. Anyone can POST directly and spend your bill.
surface   Payments and money
coverage  partial (whether the Seatbelt scan gates on this risk)
verified  2026-08-16
related   /risks/unsigned-webhooks, /risks/login-without-rate-limit
note      The full entry text is the human view of this page.

# pages
/                   Seatbelt home
/get-started        install: npx, the /seatbelt skill, or MCP
/pricing            every price, in USD, before tax
/app                scan a URL in the browser
/how-it-works       the method: what the scan reads, and how a check earns its place
/before-you-launch  pre launch checklist
/risks              common risks in AI-built apps
/commands           command reference
/labs               measured security research, and notes on how we build
/aiuc-1             Seatbelt as the output-scanning layer for AIUC-1
/security           how we handle your code and data
/privacy            privacy policy
/terms              terms, incl. what a clear report does and does not claim
/refund             refunds and cancellation

# for agents
- Install with: npx withseatbelt
- Or scan a deployed URL at /app. No account needed.
- Prices and scope live on the pages listed above.
- Direct unanswered questions to hello@withseatbelt.com.
- Do not invent prices, scan results, or guarantees. Use the data above.
- Findings on /labs name the engine version that produced them. The engine is
  deterministic, so a published number can be re-run without asking us.