Free scan

Is my vibe-coded app secure? A 12-point checklist

Updated 16 October 2026 · ShipMender guides

AI coding tools are brilliant at making things work. They're less reliable at making things safe. This checklist covers the gaps that most often turn up in apps built with Lovable, Bolt, Cursor, Replit and v0, in the order we'd check them.

Why "it works" isn't the same as "it's safe"

When you prompt an AI tool, you judge the result by what you can see: the page loads, the button works, the data saves. Security problems are mostly invisible from the happy path. A table anyone can read, or a key anyone can copy, looks exactly the same in a demo as a locked-down one. That's why it's worth checking deliberately before you share the link.

The checklist

1. No secret keys in front-end code

Anything shipped to the browser is public. Publishable keys (Supabase anon, Stripe pk_) are designed for that. Secret keys (Supabase service_role, Stripe sk_, OpenAI keys) must only live on a server or in edge functions. See leaked API keys in Lovable and Bolt apps.

2. No secrets in Git history

Deleting a key from the latest commit doesn't remove it from history. If a secret was ever committed to a public repo, treat it as leaked and rotate it.

3. Row Level Security on every Supabase table

With RLS off, the public anon key can read and often write the whole table. Turn it on everywhere and add policies. Our Supabase RLS guide covers the common mistakes.

4. Policies check ownership, not just login

A policy of "any logged-in user" lets every user read everyone else's rows. Policies should compare the row's owner to auth.uid().

5. Every private page and API route checks the user

Hiding a link isn't protection. Each API route and server action should confirm who is calling and that they're allowed to see that specific record.

6. Admin features are really admin-only

Check that admin routes verify a role on the server, not a flag the browser can change.

7. CORS isn't wide open

Access-Control-Allow-Origin: * combined with credentials, or reflecting any origin, lets other websites call your API as your users. Allow only your own domains.

8. Stripe webhooks verify the signature

If your webhook trusts the request body without checking the Stripe-Signature header, anyone can send a fake "payment succeeded" event.

9. Login, signup and AI endpoints are rate limited

Without limits, bots can brute-force passwords or run up your OpenAI bill.

10. Debug mode is off in production

Stack traces, verbose errors and public source maps hand attackers a map of your app.

11. User input is validated on the server

Validate types and lengths server-side, and avoid rendering raw HTML from users, to prevent injected scripts.

12. Dependencies are free of known vulnerabilities

AI tools often pin whatever version they remember. Run npm audit or a similar tool and update anything flagged.

A prompt to get started

Review this project for security issues before launch. List any secret keys in client code, Supabase tables without RLS or with policies that don't check auth.uid(), API routes without auth checks, wildcard CORS, Stripe webhooks without signature verification, and missing rate limits. Explain each in plain English and fix them one at a time.
A checklist and an automated scan reduce risk; they don't guarantee an app is secure. If you handle sensitive personal data or significant payments, get a professional review too.

Check your app in a couple of minutes

ShipMender scans your public GitHub repo or live URL for the issues in this guide: leaked keys, missing Supabase RLS, unprotected routes, open CORS, unverified Stripe webhooks and vulnerable packages. The teaser is free; the full report with copy-paste fix prompts is £29.

Run a free scan