AI coding agents (Claude Code, Cursor, Windsurf, Copilot) can scaffold an entire Next.js + Supabase + Stripe SaaS in an afternoon. They also repeat the exact same production security mistakes across almost every repository they touch.
While building vibe-shield (https://github.com/avivgerz-hue/vibe-shield)—an open-source, 92-rule static security scanner CLI and MCP server for TypeScript apps—and running it against public Next.js + Supabase repositories, the same high-severity bugs kept showing up.
Here are the 8 highest-risk patterns to check before you deploy, and how to catch them automatically in one command:
npx -y @vibefoundry/vibe-shield@latest scan .
1. Trusting Client-Supplied userId in /api/checkout (VSB-AUTH-001)
When you ask an AI agent to wire up a Stripe Checkout endpoint in Next.js, it almost always writes a POST handler that reads { priceId, userId } directly from await req.json() and passes that userId into client_reference_id or Stripe metadata—without calling supabase.auth.getUser() first.
Any caller can spoof another user's ID or trigger checkout mutations without a valid session. Always derive the user identity server-side from supabase.auth.getUser() and ignore client-supplied userId fields.
2. Verifying Stripe or Svix Webhooks Against Parsed JSON (req.json())
Webhook signature verification (stripe.webhooks.constructEvent or svix.verify) requires the exact raw request payload bytes (await req.text() or Buffer.from(await req.arrayBuffer())). AI agents frequently parse const body = await req.json() and then pass JSON.stringify(body) into the verifier—or write a custom crypto.createHmac check that omits timestamp tolerance, opening the endpoint to replay attacks.
3. Leaking SUPABASE_SERVICE_ROLE_KEY into Client Bundles (VSB-CLIENT-001)
The Supabase service_role key bypasses Row-Level Security (RLS) completely. If a file marked "use client" (or imported transitively by a client component) initializes a Supabase client with NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY or imports a server admin helper, every user's browser gets full admin access to your database.
4. Enabling RLS with USING (true) Policies (VSB-DB-002)
AI agents love fixing permission errors during development by generating a SQL migration that runs ALTER TABLE profiles ENABLE ROW LEVEL SECURITY; followed immediately by:
CREATE POLICY "Allow all" ON profiles FOR ALL USING (true) WITH CHECK (true);
Your table looks protected in the dashboard because RLS is toggled on, but any anonymous client with the public anon key can read, update, or delete every row.
5. Using supabase.auth.getSession() Instead of getUser() on the Server (VSB-AUTH-004)
In Next.js Server Actions and Route Handlers, supabase.auth.getSession() reads the session cookie without re-validating the JWT signature against Supabase Auth servers. Server-side authorization checks should always call await supabase.auth.getUser().
6. Unbounded Public LLM Routes Without Rate Limiting or Auth (VSB-AI-005)
An app/api/chat/route.ts endpoint that calls streamText or openai.chat.completions.create without authentication or rate limiting lets anyone drain your API credits in minutes.
7. Open Redirects in Auth Callback Routes (VSB-AUTH-006)
In app/auth/callback/route.ts, reading const next = searchParams.get('next') and calling NextResponse.redirect(new URL(next, request.url)) allows attackers to redirect users to an external phishing domain after OAuth login unless next is validated as a relative path starting with / (and not //).
8. Prompt Injection & Exfiltration in Third-Party SKILL.md and .cursorrules (VSB-MCP-001 – VSB-MCP-012)
Agent configuration files (SKILL.md, .cursorrules, .windsurfrules, CLAUDE.md, .mcp.json) execute with your coding agent's full shell and filesystem permissions. vibe-shield includes 12 dedicated agent-surface rules that scan for hidden Unicode instructions (U+200B, bidi overrides), .env credential reads paired with outbound curl/fetch exfiltration, and untrusted npx -y servers in .mcp.json.
Verify Your Entire Stack in Seconds (CLI + MCP + Agent Skills)
We built three open-source tools under VibeFoundry that work together as local CLIs, MCP servers, and Agent Skills:
-
vibe-shield (92-rule static security & MCP/Skill scanner):
- Run:
npx -y @vibefoundry/vibe-shield@latest scan . - GitHub: https://github.com/avivgerz-hue/vibe-shield
- Run:
-
ghost-qa (Autonomous headless Playwright browser QA across 8 runtime traps on Desktop, Tablet & Mobile):
- Run:
npx -y ghost-qa test http://localhost:3000 - GitHub: https://github.com/avivgerz-hue/ghost-qa
- Run:
-
unslop (72-rule UI & CSS design craft linter with WCAG 2.1 AA/AAA + APCA contrast math):
- Run:
npx -y unslop-mcp audit . - GitHub: https://github.com/avivgerz-hue/unslop
- Run:
If any of these catch a bug in your project, a star on GitHub is hugely appreciated!
Top comments (0)