Building a Class Action Claims App? 5 Security Checks First
October 9, 2026 · 1096 words
| Item | Detail |
|---|---|
| Example app | Payout: Claim Class Actions (helps users find and file class action settlement claims) |
| Builder | Developer (Connor Burd, self-taught, no CS background) |
| AI tool | Claude, per the founder; he says the app was built in under two weeks with AI |
| Stack | Expo, Next.js, TypeScript, RevenueCat, Mixpanel, Figma, GitHub |
| Time to launch | About 14 days |
| Revenue | $20K/month (self-reported, October 2025) |
| Source | Starter Story, October 26, 2025 |

Payout is a mobile app that finds class action settlements you might qualify for and helps you file claims. Its founder says he built it in about two weeks with AI. He says it reached $20K a month in revenue within about 50 days.
Today the homepage claims 500,000+ downloads and 300,000+ claims filed. That's a lot of people typing personal details into one app.
This post is not about Payout's security. I did not test it, and nothing here says it has these problems. Payout is just a clear example of an app type: a claims app built fast with AI.
The one point to take away: if your app files forms for people, you hold the kind of data attackers want, so lock it down before you scale.
Building an app like Payout?
Here's the app type in plain terms. A user signs up, answers questions, and the app matches them to open settlements. Then it helps them file. Filing often needs a name, address, email, and sometimes purchase or payout details.
Payout's own App Store privacy label lists data like financial info, contact info and identifiers. That's normal for this category. It's also why the security bar is higher than for, say, a habit tracker.
The stack Connor described is popular with vibe coders. Expo builds the iPhone and Android apps from one codebase. Next.js runs the website and backend. RevenueCat handles subscriptions. Mixpanel tracks usage.
Payout earns through weekly and yearly subscriptions. Connor's pricing tip is to steer users to the yearly plan, because it has the highest lifetime value. Lifetime value is the total a customer pays over time.
His growth engine is Facebook ads made from user-generated content, or UGC: short videos by creators that look like normal posts.
All of that is copyable. So are the security holes this type of app often ships with.
5 holes claims apps usually ship with

1. Claims anyone can read. The API returns a claim by ID, but never checks who owns it. Change the ID in the URL and you see a stranger's address. This is called IDOR (insecure direct object reference). See IDOR and authorization.
2. Fake subscription events. RevenueCat tells your backend about purchases through a webhook, a URL it calls with event data. If that URL trusts any request, anyone can grant themselves Pro.
3. Personal data in analytics. It's easy to send a whole form object to your analytics tool. Then names and addresses sit in a third-party dashboard.
4. Tokens in plain storage. Login tokens saved in AsyncStorage, a simple unencrypted key-value store on the phone, are easier to steal. See secure storage in React Native.
5. Keeping everything forever. Claim forms get filed, then the data sits in your database for years. Every extra field you keep is extra damage if you leak.
BEFORE and AFTER: verify the subscription webhook
Hole 2 is the one AI tools write wrong most often, because the "happy path" works fine without a check. Here's a typical AI-written Next.js route:
// BEFORE: app/api/revenuecat/route.ts
export async function POST(req: Request) {
const { event } = await req.json();
if (event.type === "INITIAL_PURCHASE") {
await grantPro(event.app_user_id); // trusts anyone who calls this URL
}
return Response.json({ ok: true });
}
RevenueCat lets you set an authorization header value in the dashboard. It sends that value with every webhook. Check it before doing anything:
// AFTER
export async function POST(req: Request) {
const auth = req.headers.get("authorization");
if (!process.env.RC_WEBHOOK_SECRET || auth !== `Bearer ${process.env.RC_WEBHOOK_SECRET}`) {
return new Response("Unauthorized", { status: 401 });
}
const { event } = await req.json();
if (event.type === "INITIAL_PURCHASE") {
await grantPro(event.app_user_id);
}
return Response.json({ ok: true });
}
Keep the secret in an environment variable, never in the app bundle. See environment variables. The same idea protects payment webhooks too: Stripe webhook security.
The curl test
Run this against your own app, never someone else's. It sends a fake purchase with no secret:
curl -i -X POST https://your-app.com/api/revenuecat \
-H "Content-Type: application/json" \
-d '{"event":{"type":"INITIAL_PURCHASE","app_user_id":"test-user"}}'
You want 401 Unauthorized. If you get 200 and the test user becomes Pro, the webhook is open.
For hole 1, log in as user A, copy a claim ID, then request it with user B's token. You want 403 or 404, never the data.
If you vibe-code this
A short checklist to paste into your AI tool before you ship a claims app:
- Every claim query filters by the logged-in user's ID, taken from the session.
- The subscription webhook checks a secret and rejects everything else.
- Analytics events contain IDs and actions only, never form fields.
- Tokens live in secure storage (Keychain or Keystore), not AsyncStorage.
- Claim data is deleted or trimmed once a claim is filed, with a stated retention period.
Also rate-limit your login and form endpoints, so bots can't hammer them. See API rate limiting.
Building a claims or finance app with AI? Email [email protected] for a vibe-code security audit.
Key takeaway
Payout shows how fast one person can ship a money-making app with AI. Apps that file forms for people hold sensitive data, though. Check ownership on every record, verify every webhook, and keep personal data out of places it doesn't need to be.
More case studies: Vibe-coded apps making money · Security basics: Vibe coding security guide