Pre-launch checklists, platform-specific playbooks, and step-by-step fixes for the bugs your AI keeps shipping. Built for people who ship with Lovable, Bolt, Cursor, Supabase, and Next.js — not security engineers.
The single most important thing on this page. Every step takes minutes. Skipping any of them is the difference between a clean weekend and a 3am rotation of every credential you own.
Ten things to verify before you put a URL on the internet. Tick them off as you go — your progress saves locally.
AI tools create tables without RLS. Run `SELECT tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public'` and turn it on everywhere — then write a policy for every table you turned it on for.
Supabase RLS playbookThe service_role key bypasses RLS. It should never appear in code prefixed NEXT_PUBLIC_, in client components, or in your bundled JavaScript. Search your repo for it.
API key exposureRun `git log --all --full-history -- .env` and `gitleaks detect`. If anything shows up, rotate every secret it touched — assume it's public.
For every route that takes an ID, verify the authenticated user actually owns the resource before returning it. AI ships these without the check ~80% of the time.
IDOR explainedIf you must render user HTML, run it through DOMPurify first. Most uses can be replaced with plain text rendering — the AI added it because the prompt looked easier that way.
XSS in ReactNo string concatenation in SQL. Ever. Use the query builder, prepared statements, or your ORM's parameter binding. Search for backtick template strings in `.from(` or `.query(`.
SQL injectionDeny by default. Have an allow-list of public routes and require a session everywhere else. Double-check middleware actually runs on the routes you think it does.
Add `Strict-Transport-Security`, `Content-Security-Policy`, `X-Frame-Options`, and `Referrer-Policy`. Vercel and Netlify both support these in their config files.
No `Access-Control-Allow-Origin: *` on authenticated endpoints. List your real domains. AI tends to default to wildcard because it makes the demo work.
After you've done all of the above, prove it. Paste your URL into Flowpatrol and check that nothing on the OWASP Top 10 trips. The scanner is the second pair of eyes you don't have.
Run a free scanThe bugs are the same, but every platform ships its own defaults, footguns, and workarounds. Pick yours.
RLS, anon keys, and the policies your AI never wrote.
170+ Lovable apps were exposed via the same bug. Here's the fix.
What Bolt scaffolds, what it skips, and what to add before launch.
Editor-side risks: prompt injection, MCP, and what your IDE can leak.
Middleware, server actions, and the bypasses that ship with templates.
Your AI's tool calls are an attack surface. Lock them down.
You scanned. You found something. Each card is a one-screen fix recipe — what's broken, what to do, and the walkthrough that proves it.
Bug · Tables are exposed via the anon key with no row-level filtering.
Fix · Enable RLS, then write `auth.uid() = user_id` policies for every table.
Bug · Routes return any record by ID without ownership checks.
Fix · Add `where user_id = auth.uid()` to every query that takes an ID.
Bug · Service keys, Stripe keys, or OpenAI keys ended up in client bundles.
Fix · Move them to server-only env, rotate them, and re-deploy.
Bug · `dangerouslySetInnerHTML` renders untrusted HTML directly.
Fix · Render as text, or sanitize with DOMPurify before injecting.
Bug · String-concatenated SQL queries built from user input.
Fix · Use parameter binding or your ORM's query builder. Never concatenate.
Bug · Mass assignment on signup lets anyone register as admin.
Fix · Allowlist fields on the server. Never spread `req.body` into a user record.
Bug · OTP verification is client-checked or skippable via response tampering.
Fix · Verify on the server, lock the account state, and rate-limit attempts.
Bug · The "upgrade plan" call accepts the new tier from the client.
Fix · Always derive plan state from your billing provider webhook, never from the request.
Reference material, conceptual framing, and longer reads — for when you have a coffee and want to actually understand what you just shipped.
The canonical security list, rewritten for people who ship with Lovable and Bolt.
IDOR, RLS, XSS, SSRF, SQLi — 30+ security terms in plain English.
What we found scanning 100 apps shipped with AI tools. The pattern is depressing.
What can your agent actually destroy? A framework for thinking about damage.
Lockfiles, audits, and the 39-minute window that mattered. Practical hardening.
The handoff problem in AI development, and how to close the loop.
The questions we get most from builders shipping AI-generated apps. Each answer also lives in the page schema so AI search engines can quote it directly.
Start with the pre-launch checklist on this page. It walks through the ten checks that catch over 90% of the bugs we find in AI-built apps: enabling Row Level Security on every Supabase table, moving the service_role key off the client, sanitizing HTML rendering, parameterizing every SQL query, adding ownership checks on every /api/{id} route, locking down CORS, setting security headers, and verifying with a Flowpatrol scan. Each step links to a deeper guide.
Row Level Security (RLS) is the PostgreSQL feature Supabase uses as its primary access control mechanism. When RLS is enabled on a table, every query is filtered by policies you write — for example "users can only see rows where user_id matches auth.uid()". Without RLS, the anon key (which is meant to be public) gives full read and write access to your entire database. In our scan of 100 vibe-coded apps, 68% of Supabase-backed apps had missing or broken RLS. See the Supabase playbook in the platforms section above for the fix.
Yes — but only if Row Level Security is enabled on every table and the policies are correct. The anon key is designed to live in your client JavaScript. Its safety depends entirely on RLS doing its job. The service_role key is the opposite: it bypasses all RLS and must never appear in client code, NEXT_PUBLIC_ environment variables, or your bundled JavaScript.
IDOR (Insecure Direct Object Reference) is the most common bug in AI-generated APIs. It happens when a route like GET /api/orders/{id} returns the order without checking that the authenticated user actually owns it. To fix it, add a where-clause that filters by the current user — for example WHERE user_id = auth.uid() — to every query that takes an ID. The fix recipes section above links to a full walkthrough.
The OWASP Top 10 is the security industry's canonical list of the most critical web application security risks, maintained by the Open Worldwide Application Security Project. It applies one-for-one to AI-built apps — the bugs are exactly the same, AI just ships them faster. We wrote a builder-friendly version at /owasp-top-10 that explains each category in plain English with the actual code your AI ships and how to fix it.
No. These guides are written specifically for builders shipping with AI tools — Lovable, Bolt, Cursor, v0, Replit, Claude — not for security professionals. Every recipe is one screen long, every checklist item takes minutes, and every guide assumes you're a creator or founder, not a penetration tester.
Every claim on this page is grounded in standards, official docs, or named CVEs. If you want the source material, here it is.
Last reviewed and updated 7 April 2026 · Maintained by the Flowpatrol Team
Reading the field manual is half of it. The other half is proving your app actually does what the checklist says. Paste a URL.