Security guides for apps built with AI
AI tools make it easy to ship an app, and just as easy to leave the door open. Each guide covers one problem we keep finding: how to tell if you have it, why it matters, and the fix.
Checklists
Databases
- Firebase security rules open to everyone: how to fix 'allow read, write: if true' Firestore, Realtime Database or Storage rules set to 'if true', or left in test mode, let anyone read and write your data. Here's how to check and fix them. Firebase · Firestore · Cloud Storage · Realtime Database
- Supabase says RLS is disabled: what it means and how to fix it Row Level Security off on a Supabase table means anyone with your public key can read or change every row. Here's how to check and fix it. Supabase · Lovable · Bolt
- Supabase SECURITY DEFINER functions: how they skip RLS and how to lock them down A Postgres function marked SECURITY DEFINER runs with its owner's rights and ignores RLS. In the public schema, anyone can call it through /rest/v1/rpc. Here is how to fix that. Supabase · Postgres · Lovable · Bolt · Cursor
- Supabase storage bucket is public: how to lock down uploaded files Files in a public Supabase Storage bucket can be opened by anyone with the link. Here's how to check, switch to private buckets, and add storage policies. Supabase · Lovable · Bolt · Next.js
Secrets & keys
- I committed my .env or API key to GitHub: what to do now Deleting a committed secret doesn't remove it from git history. Rotate the key first, then clean the history and turn on secret scanning. Steps inside. GitHub · Git · Lovable · Bolt · Cursor
- Is it safe that my Firebase apiKey is public? The apiKey in your Firebase web config is not a secret, so a public one is normal. What protects your data is Security Rules and App Check. Service account keys are different. Firebase · Firestore · Google Cloud · Lovable · Bolt · Cursor
- Secret API key in frontend code (OpenAI, Anthropic, Stripe, Resend): how to fix it VITE_ and NEXT_PUBLIC_ variables are copied into your public JavaScript. If a secret API key is there, rotate it and call the provider from a server route. OpenAI · Anthropic · Stripe · Resend · Next.js · Vite · Lovable · Bolt
- Supabase service_role key exposed in frontend code: how to fix it The Supabase service_role (or sb_secret_) key bypasses RLS. If it's in your frontend or a public repo, rotate it now and move it server-side. Supabase · Lovable · Bolt · Cursor · Next.js · Vite
Logins & access
- Admin page only hidden in the UI: how to enforce admin access properly Hiding an admin button or route in React doesn't stop anyone calling your API. Here's how to find the gap and enforce roles on the server or with RLS. React · Next.js · Supabase · Lovable · Bolt · Cursor
- Are Next.js Server Actions public? How to secure 'use server' functions Server Actions are public POST endpoints. Hiding the button from non-admins does not stop anyone calling the action. Here's how to check and secure yours. Next.js · React · Cursor · v0 · Vercel
- No rate limiting on login or your AI endpoint: how to add it Without rate limits, anyone can guess passwords, spam your reset emails or run up your OpenAI bill through your own API route. How to check and fix it. Next.js · Vercel · Supabase · OpenAI · Anthropic
- Password reset tokens that don't expire: how to build a safe reset flow Home-made password resets often use guessable or never-expiring tokens, trust the Host header, or reveal which emails exist. Here is how to fix each one, or skip it by using your auth provider. Next.js · Node.js · Express · Cursor · Claude · Lovable · Bolt
- Signup without email verification: why it's a risk and how to require it If anyone can sign up with any email address and get in straight away, people can pose as others and abuse trials. Here is how to require verified emails in Supabase and Firebase. Supabase · Firebase · Next.js · Lovable · Bolt · Cursor
- Supabase getSession vs getUser: which one to use in server code supabase.auth.getSession() on the server reads the session from cookies without checking it. Use getUser() to protect routes, middleware and server components. Supabase · Next.js · Cursor · Lovable · Bolt
- Users can see other users' data by changing an ID: how to fix it Changing an ID in a URL or API request shows someone else's invoice or profile. This is IDOR. Here's how to test it with two accounts and fix it on the server. Next.js · Supabase · Prisma · Lovable · Bolt · Cursor
Payments
- Stripe webhook signature not verified: how to fix it If your Stripe webhook skips the Stripe-Signature check, anyone can fake a payment event and get paid features for free. How to verify it, with code. Stripe · Next.js · Express · Supabase
- Trusting prices from the browser: how to secure your Stripe checkout If your checkout accepts the price, amount or discount from the browser, buyers can set their own price. Send Price IDs and look the price up on the server. Stripe · Next.js · Lovable · Bolt
Code & input
- dangerouslySetInnerHTML and XSS: stop user content running as code in your app If your React or Next.js app renders user text, markdown or AI output as HTML, someone can plant a script in it. Here's how to check your app and fix it. React · Next.js · Vue · Cursor · Lovable · Bolt
- File upload accepts anything: how to secure uploads in a Next.js or Supabase app An upload form with no type or size checks can host scripts on your domain, run up your storage bill, or overwrite files. Here's how to check and fix it. Next.js · Supabase · Firebase · Lovable · Bolt · Cursor
- Server-side request forgery (SSRF) in link preview and import-from-URL features If your server fetches a URL a user typed, they can point it at your internal network or cloud metadata. Here is how to check your own app and fix it. Node.js · Next.js · Vercel · AWS
- SQL injection in Prisma, Supabase and Node apps: fixing string-built queries Building SQL with template literals or string concatenation lets users change your query. Here's how to find raw queries in your app and make them safe. Prisma · Drizzle · Supabase · PostgreSQL · Next.js · Cursor
- Users can edit fields they shouldn't: fixing mass assignment in Prisma and Supabase If your update route passes the whole request body to the database, users can set their own role, credits or plan. Here's how to find it and fix it. Prisma · Supabase · Next.js · Express · Cursor · Lovable
AI features
- AI suggested an npm or PyPI package that doesn't exist: what to do AI coding tools sometimes invent package names, and attackers register those names with malware. Here is how to check a package before you install it. npm · PyPI · Cursor · Claude · Lovable · Bolt
- Prompt injection in AI apps: how to protect a chatbot or AI agent you built Text from users, web pages, emails or uploads can give your LLM orders. There is no complete fix, but these steps limit what an attacker can reach. OpenAI API · Claude API · Vercel AI SDK · Supabase
Hosting & config
- CORS allows any origin: what it means and how to fix it Access-Control-Allow-Origin set to * or copied from the request, especially with credentials, lets other websites read your API. How to check and use an allow-list. Next.js · Express · nginx · Supabase
- Is your .env file or .git folder public? How to check and fix it A .env file, .git folder, backup or source map served by your website can hand over your keys and code. How to check your own site and lock it down. nginx · Next.js · Vite · Docker
- Missing security headers: what to add and how (Next.js, Vercel, nginx) A starter set of security headers (CSP, HSTS, nosniff, frame-ancestors, Referrer-Policy, Permissions-Policy) with copy-paste config for Next.js, Vercel and nginx. Next.js · Vercel · nginx
- Unprotected cron jobs and internal API routes: how to lock them down on Vercel and Supabase Routes like /api/cron/send-emails, /api/seed or /api/debug are public URLs. Here's how to check yours and protect them with a secret, or remove them. Vercel · Next.js · Supabase · Cursor · Lovable · Bolt
- Vercel and Netlify preview deployments are public: how to lock them down Every branch you push gets its own live URL, often connected to your production database. Here is how to check yours and protect previews. Vercel · Netlify · Next.js · Supabase