Vibe Coding Security Checklist for Bug Bounty Hunters
"Vibe coding" ships features fast: chat with a model, paste the scaffold, deploy. Plenty of those apps land on bug bounty platforms with polished UI and soft edges. You are not auditing the AI. You are auditing the shortcuts left behind.
Spot the fingerprint
Clues show up in boring places. Identical error strings across unrelated routes. CRUD handlers that all take a client-supplied userId. README files that still say "replace this secret." Framework starter kits with demo auth still wired to production.
Mobile and desktop wrappers around a hastily generated API are common too. The UI looks custom; the API looks like yesterday's tutorial. Source maps in production, default Neon or Supabase project names in JS bundles, and copy-pasted OpenAPI descriptions with example.com hosts are soft tells—not proof by themselves, but enough to slow down and test ownership.
Checklist that finds real bugs
Work this list with two accounts and a proxy:
- Object IDs in URLs or bodies — swap resource ids; expect 403, not 200 with the other user's data.
- Role claims in JWTs or local storage — change
roleorplanclient-side and replay; server must re-check. - File upload paths — generated code often stores under predictable names or skips content-type checks.
- Webhook and callback routes — unsigned or shared-secret-in-query is a recurring paste error.
- CORS and cookie flags —
Access-Control-Allow-Origin: *with credentialed APIs still appears in rushed deploys. - Debug and admin mounts —
/api/debug, Swagger without auth, default Prisma studio tunnels, leftover/api/test. - Secrets in the client bundle — service keys, Supabase service roles, or Firebase admin snippets shipped to the browser.
- Mass assignment — PUT bodies accept
isAdmin,balance, orownerIdbecause the model mirrored the schema.
Stop when you have a clean A/B proof. Volume scanning without reading responses wastes the advantage vibe-coded apps give you: shallow, consistent mistakes.
Where AI-assisted code usually fails authz
I've seen generators emit "get record by id" helpers that never take the session user as a filter. Every feature reuses the helper. One missing where: { userId: session.id } becomes a product-wide IDOR.
Also watch orchestration routes: a single /api/ai/run that accepts arbitrary tool names or URLs. That is not theoretical—paste-friendly examples teach it. Rate limits and idempotency keys are often missing on those routes too; do not turn that into a DoS report unless the program wants it—use it as a hint the endpoint was never hardened.
Report like an engineer reviewing a PR
Name the missing server-side check, show the generated-looking pattern if relevant, and suggest the invariant ("authorization must use session identity, never body userId"). Skip lectures about AI. Triage cares about the break.
One more habit: compare the generated OpenAPI or route list against what the UI actually calls. Orphan routes left from an earlier chat session are often where auth middleware was never wired.
Vibe-coded targets reward hunters who read diffs and defaults. Use the checklist, then go deep on the first broken invariant you confirm.