Back to journal

‣ Software ‣ 7 min read

Vibe-coded app security: the checklist to run before real users arrive

Built it with Lovable, Bolt, Cursor or Replit? Before real customers, real data or real money arrive, run these twelve checks. Most take minutes, and each one comes with the test to prove it.

Kryspin Parchliniak
Kryspin Parchliniak Co-Founder & Lead Developer · 31 October 2026
A pre-launch security checklist beside an AI-built app on a laptop

AI builders have made it normal to go from idea to working app in a weekend. That is a real achievement, and we are not going to pretend otherwise.

What has not changed is the list of things that go wrong when strangers start using software. The tools are good at the parts you can see. The parts you cannot see are where the trouble is, and they look exactly the same in a safe app as in an exposed one.

This is the checklist we work through at the start of every rescue, whichever tool the app came from. It is broader than our Supabase RLS walkthrough, which goes deep on one item. Here the aim is coverage: twelve checks, each with a way to prove it rather than assume it.

If you only have two minutes, our production readiness check scores the big ones. If you have an afternoon, keep reading.

When this list starts to matter

Not on day one. A prototype that only you and a few testers use does not need hardening, and spending money on it is premature.

It starts to matter the moment any of these is true:

  • People who are not you are signing up
  • The app stores personal data: names, emails, addresses, anything uploaded
  • Money moves through it, or it calls a paid API on your account

Once one of those is true, every item below is worth an hour.

Accounts and sign-in

1. Every page and endpoint checks who is asking

AI-generated apps often protect pages by hiding them. The link disappears when you are signed out, but the page, or the API behind it, still answers if you ask directly.

Test: sign out, then paste the URL of an account page or an admin screen straight into the browser. Then open the network tab while signed in, copy a request the app makes, and replay it from a private window with no session. Anything that comes back with data is unprotected.

2. Password reset and email change cannot be hijacked

Reset links should expire, work once, and be tied to the account that requested them. Changing the email on an account should require the current password or a confirmation sent to the old address. Otherwise anyone who gets into a session for a minute can take the account permanently.

Test: request two reset links and check the first stops working. Use a link twice. Try changing your email without re-entering your password.

3. Admin is a role the server checks

"Is this user an admin?" should be answered by the database or the server, never by a flag the browser sends or a field the user can edit on their own profile.

Test: look at the request that loads or updates your profile. If there is a role, is_admin or similar field in it, try changing it.

Data

4. The database enforces who sees what

This is the one that matters most, and the one we find broken most often. On Supabase it means row-level security on every table, with policies that tie each row to its owner. On other stacks it means the server filters every query by the signed-in user, rather than trusting an ID from the URL.

Test: two browsers, two accounts. In the second, try to load the first account's records by changing an ID in the URL or in a replayed request. If anything comes back, your access rules live in the interface. Our Lovable and Supabase security guide has the SQL to find every unprotected table and every policy that is too loose.

5. Uploaded files are private unless meant to be public

Storage buckets have their own rules, separate from your tables, and they are the thing most often forgotten. Invoices, ID documents and anything a customer uploaded should not sit in a bucket that serves files to anyone with the link.

Test: upload a file as one user, copy its URL, and open it in a private window. Then check each bucket's settings for "public".

6. Inputs have limits

A form that accepts any length of text, or an upload that accepts any file of any size, is an easy way to fill your storage or your bill. Set maximum sizes, allowed file types and sensible length limits on the server, not just in the form.

Secrets and money

7. No secret keys in the front end

Anything in the JavaScript the browser downloads is public. That includes keys pasted into a prompt "just to get it working".

Test: open developer tools, search all sources for service_role, sk_live, sk- and the first few characters of each key in your dashboard. Anything you find has to be rotated, not just deleted, because it has been readable since the day it shipped.

8. The server decides the price

If the amount, quantity or discount arrives from the browser and is charged as sent, a customer can change it. The server should look up what things cost and calculate the total itself.

Test: in the network tab, find the request that starts checkout. If you can see a price in it, try lowering it.

9. Payment webhooks are verified

Your app learns that a payment succeeded from a webhook. If it does not verify the signature on that request, anyone who finds the URL can tell your app they have paid. Stripe, and most other providers, sign every webhook so you can check it genuinely came from them.

10. Anything that costs you money is rate limited

Sign-up, login, password reset, anything that sends an email or a text, and anything that calls an AI API. Without a limit, one script can run up a bill or lock out your users in an evening. This matters most for edge functions and API routes that call paid services on your account.

Test: submit the same form twenty times quickly. If all twenty go through, so would twenty thousand.

Running it

11. You have restored a backup

Backups being switched on is not the same as backups working. Restore one into a separate project, check the data is all there, and write down how long it took. That number is how long you would be down on your worst day.

12. You would know if something went wrong

Errors should go somewhere a person will see them, and logs should be kept long enough to answer "who accessed this, and when?" If you ever had to report a breach, under UK GDPR that is within 72 hours of becoming aware of it, and you cannot assess what happened without logs.

While you are here, check the dependencies. AI builders pin whatever versions were current on the day the code was written, and nobody updates them afterwards. Running npm audit takes a minute and tells you whether any of them have known problems.

What to do with the results

Sort what you found into three piles.

Fix today: exposed keys (rotate them), tables or buckets anyone can read, prices the browser can set. These are the ones that turn into incidents.

Fix before launch: unprotected endpoints, unverified webhooks, missing rate limits, an untested backup.

Fix as you go: input limits, logging, dependency updates. Important, but nothing is on fire.

None of this means the app was a mistake or needs rebuilding. In most of the AI-built apps we review, the application code is a reasonable starting point. What is missing is the protection around it, and that is days of work, not months. If you are weighing up the bigger question of whether to keep the codebase at all, we have written about when to keep an AI-built app and when to rebuild.

If you would rather hand it over

We do this every week. Send us the code through our Lovable page and a senior developer will come back within two working days with a written review: what is risky, what is fine, and what fixing it would cost. It is free, and the report is yours either way.

If you go ahead, the two-week sprint is £1,950 for a small codebase and covers everything on this list, fixed rather than just reported. Larger codebases are quoted in the review. For the wider picture of getting live, see what it takes to take a Lovable app to production.

Common questions

Are vibe-coded apps secure?
They can be, but not by default. AI builders are good at making the happy path work and much less reliable at the protection around it: database access rules, secrets, payment handling and rate limits. None of that is visible from the outside, so an app can look finished while being wide open. The checks in this post find the common gaps in an afternoon.
Is a Bolt app any safer than a Lovable app?
Not inherently. The tools differ in how they generate code, but the gaps we find are the same across Lovable, Bolt, Cursor and Replit: access rules enforced in the interface rather than the database, keys in the front end, and prices the browser decides. The checklist applies to all of them.
What is the most important security check for a Lovable and Supabase app?
Whether row-level security is switched on for every table and actually restricts each row to its owner. Sign in as two users in two browsers and try to read the first user's data from the second. If you can, fix that before anything else on this list.
When should I get a professional security review?
Before the first real customer, real personal data or real payment, whichever comes first. A prototype with no users does not need one yet. Once people are trusting the app with their details or their money, the cost of a review is small next to the cost of a breach.

Share this article

LinkedIn X
Kryspin Parchliniak

Written by

Kryspin Parchliniak, Co-Founder & Lead Developer

Kryspin co-founded 628 Studio and leads development and architecture. He reads every rescue codebase himself, from the Leicester and Huddersfield studios.

Start a project

Build it.
With us.

Tell us what's holding your business back. We'll work with you to design and build what fixes it.

Tell us what's holding your business back.

Luke Jagger

Co-Founder & Lead Designer

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.