AI-generated applications fail in predictable ways, and most of them are security failures. This is the checklist we would run before any AI-built app meets real users.
Ask two questions about every feature
Most application security reduces to two questions. Who is allowed to do this, and what does doing it expose? A model will happily build the screen for a feature and skip both answers, because the screen is what you asked for.
Walk your features and answer both out loud. The places where the answer is a shrug are the places to look first.
Secrets: assume the browser is public
Anything the front end needs is public by definition. The model often does not distinguish a value that is safe to expose, such as a Stripe publishable key or a Supabase anon key, from one that is not, such as a Stripe secret key, a Supabase service_role key, an OpenAI key or a database password.
- Search the source and the built bundle for key prefixes: sk-, sk_live, service_role, AKIA, ghp_, AIza.
- Check that an .env file is not committed, and check the repository history as well as the current tree.
- Confirm that only variables meant to be public use the public prefix (NEXT_PUBLIC_, VITE_, REACT_APP_).
- Rotate anything that was ever exposed. Deleting the line does not un-leak it, because the history keeps it.
Database rules: the biggest single gap
Supabase and Firebase put a database one API call away from the browser. That is the point of them, and it is also why row-level rules carry all of the authorization weight. A table with rules disabled, or set to allow everything, is a public database with a nice name.
Turn on Row Level Security in Supabase or Security Rules in Firestore, then write a rule per table or collection. Confirm the rules by trying to read someone else's data with the public key. The same applies to file storage: a public bucket leaks every file it holds, including the ones you did not mean to upload.
Sessions and sign-in
- Session cookies should be httpOnly, secure and same-site, so a script cannot read them and they are never sent over plain HTTP.
- Rate limit sign-in and password reset, and expire sessions rather than keeping them forever.
- Make a password reset single-use and short-lived.
- If you support email codes or magic links, make sure they expire and can only be used once.
- Turn on multi-factor authentication where the platform offers it, at least for administrators.
Third-party keys and the test and live boundary
- Live payment keys on a staging URL let anyone who finds them move real money.
- Test keys on production mean your customers' payments fail, quietly.
- Keep a staging project in the same service, separate from production, so the two sets of keys never mix.
- Publishable keys are fine in the browser, as long as the data behind them is protected.
Transport and headers
- Serve everything over HTTPS and redirect plain HTTP to it.
- Send Strict-Transport-Security so a browser refuses to downgrade to HTTP.
- Send a Content-Security-Policy where you can, to blunt injected scripts.
- Set X-Content-Type-Options to nosniff and a sensible Referrer-Policy.
- Do not advertise your stack more than you need to in response headers.
Error messages and debug output
A helpful error is a helpful map. Stack traces, database errors and framework debug pages tell an attacker the exact shape of your internals. In production, log the detail on the server and show the user a plain sentence.
Check the error pages themselves. A default 404 or 500 page often reveals the framework and its version for free.
Leftover demo and admin surfaces
- Seeded admin logins, sample customer rows and demo endpoints should not exist in production.
- Remove or protect admin and debug routes you no longer use.
- Check that a test or staging hostname is not publicly reachable and indexed.
A 30-minute pre-launch pass
- 01
Search the bundle for secrets
Download what the browser gets and grep it for key prefixes. This catches the most damaging mistake in seconds.
- 02
Call your API without a session
Pick your three most sensitive endpoints and call them with no credentials. Anything that answers is a problem.
- 03
Read someone else's data
With the public key, try to read a record that belongs to another account. If it comes back, your rules are open.
- 04
Check the cookies
Look at what sign-in sets, and confirm the flags on each cookie.
- 05
Skim the headers
Confirm HTTPS, HSTS and a few sane defaults on your most important pages.
- 06
Run a black-box review
An external review of the running site covers secrets, headers, sessions, exposed endpoints and the launch checks in one pass, with evidence for each finding.
The short version
Security for an AI-built app is not a rewrite. It is a short list of questions, asked before real users arrive.