Home / Labs / Security

A security checklist to run before you launch an AI-built app

Ten checks, in the order we run them. Each one says what to look for, how to test it on the running app, and what counts as a pass. Print it, tick it, and keep the answers.

An open lined notebook with a pen and a metal clip on a white desk
Key takeaways
  • Test the running application, not just the code. Most serious problems only appear when you log in as different people and try to cross the lines on purpose.
  • Ten checks cover most of the risk: secrets, permissions, login and sessions, database queries, inputs and uploads, components, configuration, abuse limits, personal data, and backups.
  • Write down each result, with the date and who ran it. A checklist that leaves no record cannot be repeated or shown to a customer.
  • Run it again after every large change, and at least every few months. Security is a routine, not a launch event.

How to use this checklist

You are about to put an app in front of real customers, and it was written largely by AI assistants. This is the list we use to decide whether it is ready. It is written so that a business owner can follow the reasoning and a developer can carry out the tests.

Three ground rules make it work. First, the person who checks should not be the person who built it, and certainly not the same AI assistant: a builder reads what they meant to write, a reviewer reads what is there. Second, test the live behaviour: open the app in a browser, make real accounts, and try things. Third, keep a record. For each check, note the date, who did it, what was tried, and the result. When a customer asks how the software was reviewed, that note is your answer.

Each item below follows the same pattern: why it matters, how to test it, and what a pass looks like. Use a test copy of the app with invented data wherever you can, and never run these tests against a system you do not own.

1. Secrets are not in the code

Why it matters. Passwords, keys and tokens left in the code, in the pages sent to visitors or in the history of the repository can be used by anyone who finds them, and automated programs look for them constantly.

How to test.

  • Run a secret-scanning tool over the whole repository, including its past versions, not only the latest files. Several free tools exist for this.
  • Open the app in a browser, view the page source and the downloaded scripts, and search them for keys, tokens and passwords.
  • Check where the live secrets are kept: in the server's protected settings or a secrets manager, never in the code.

A pass looks like. No secrets found anywhere in the code or its history, and the live ones stored outside the code. Any secret that was ever exposed has been replaced, not just removed, because removing a line does not erase it from the past.

2. Every user sees only what they should

Why it matters. Logging in proves identity. It does not decide what a person may read or change. This is the commonest serious flaw in AI-built apps and the one that most often leaks other customers' data.

How to test. Create two ordinary accounts, A and B, and one administrator.

  • As A, open one of your own records and note its address. Log in as B and paste that address. B must be refused.
  • Repeat for every kind of record: invoices, documents, messages, profiles, uploads.
  • Try the same with actions rather than pages: can B change or delete something that belongs to A by altering a request?
  • As an ordinary user, try to open the administrator's pages directly by typing their addresses.
  • Log out and try to open internal pages and files without logging in at all.

A pass looks like. Every attempt to reach another person's data, or a higher role's functions, is refused, and the refusal is consistent across every screen. It also helps if the rules are enforced in one central place, so that a new screen cannot forget them.

3. Login and sessions are sound

Why it matters. Weak login handling lets attackers guess passwords, steal sessions or stay logged in after the real user has left.

How to test.

  • Check that passwords are stored in a form that cannot be reversed, and ask the builder how. "Hashed with a modern, slow method" is the right kind of answer.
  • Try repeated wrong passwords. The app should slow down or lock out the attempts.
  • Log in, then log out, and press the browser's back button. Nothing private should reappear, and the old session must no longer work.
  • Check that sessions end after a reasonable time, that the "remember me" option is limited, and that password reset links expire and work only once.
  • If you offer two-step verification, test that it cannot be skipped by going straight to the next page.

A pass looks like. Guessing is slowed down, sessions end properly, reset links are single-use, and nothing sensitive is stored in a place the browser exposes.

4. Database questions are asked safely

Why it matters. If the app builds database queries by gluing in what a user typed, a visitor can change the query and read or destroy data.

How to test.

  • Ask the builder to confirm that every query uses parameters, the safe way of passing values, and ask to see a few examples.
  • Run a static analysis tool over the code. It flags queries built from text.
  • Type a lone apostrophe, quotation marks and strange symbols into search boxes and forms. A well-built app treats them as ordinary text and never shows a database error.

A pass looks like. No query is built by joining user text, and odd input produces a polite message instead of an error page.

5. Inputs and uploads are checked on the server

Why it matters. Checks that exist only in the browser can be bypassed in seconds. Anything shown back to other people must be cleaned, or one visitor can plant a script that runs for everyone.

How to test.

  • Enter a short piece of harmless markup, for instance text in angle brackets, into every field that is later displayed. It must appear as plain text, not be interpreted.
  • Submit empty, very long and unexpected values. The server must refuse them gracefully.
  • For file uploads, try a wrong file type, a very large file and a file with a misleading name. Only the types you expect, up to a sensible size, should be accepted.
  • Confirm that uploaded files are stored away from the code and are never opened in a way that could run them.

A pass looks like. The server rejects what it did not expect, displays user text safely and handles files cautiously.

6. The app's building blocks are real, current and pinned

Why it matters. An app is mostly made of other people's components. AI assistants sometimes suggest components that do not exist, and attackers publish harmful look-alikes under the invented names. Old components also carry known weaknesses.

How to test.

  • Ask for the full list of components and check that each is a real, established one from its official source. A component with a handful of downloads and a name that is almost, but not quite, a famous one deserves suspicion.
  • Confirm that versions are fixed, so an update cannot arrive unnoticed.
  • Run the dependency audit that comes with your platform, or a free scanner, and read the results.
  • Decide who is responsible for updating components, and how often.

A pass looks like. Every component is identified and justified, nothing with a known serious weakness is left in place, and someone owns the updates.

7. The live configuration is hardened

Why it matters. Development settings left switched on in production expose internals: detailed error pages, test accounts, open debugging tools.

How to test.

  • Make the app fail on purpose, for example by opening an address that does not exist or sending bad input. The error shown to visitors should be short and generic, with the details kept in private logs.
  • Check that the site uses an encrypted connection everywhere and that plain connections are redirected.
  • Look at the response headers with a free online checker, and confirm that the standard protective headers are present.
  • List every address the app answers to, including admin pages, test routes and status pages, and confirm each is intentional and protected.
  • Check that cross-site access is limited to the sites that should have it, not open to everyone.
  • Remove default and test accounts.

A pass looks like. Production behaves like production: quiet errors, encrypted traffic, protective headers, and no leftover test doors.

8. The app can withstand abuse, not just use

Why it matters. A program can repeat an action thousands of times. Without limits, a login can be guessed, a contact form can be used to send spam, and a search can slow the whole service to a crawl.

How to test.

  • Send the same request many times in quick succession to the login, sign-up, password-reset and contact forms. The app should slow down, refuse or require extra proof after a threshold.
  • Look for features that send email or messages on behalf of visitors, and check that they are capped and cannot be aimed at third parties.
  • Check that public forms have simple protections against automated posting, such as limits per visitor and a hidden field that a human never fills.
  • Confirm that the app records failed attempts so they can be seen.

A pass looks like. Repetition is slowed or stopped, forms cannot be turned against other people, and abuse leaves a trace.

9. Personal data is minimal, protected and understood

Why it matters. The law expects you to know what personal data you hold, why you hold it and how long you keep it. A prototype is not exempt.

How to test.

  • Make a plain list of every kind of personal data the app collects, where it is stored and who can see it. If you cannot make the list, that is the first finding.
  • Remove what you do not need. Data you never collected cannot be leaked.
  • Check the logs: they must not contain passwords, full card details or whole personal records.
  • Confirm that development and test copies use invented data, and that nobody pasted real customer information into an AI tool to make a test more realistic.
  • Make sure the privacy notice matches what the app actually does, and that there is a way to delete or export a person's data on request.

A pass looks like. You can say what you hold and why, the logs are clean, test environments use fake data, and the notice is truthful.

10. You can recover, and you have proved it

Why it matters. The worst security incident is the one you cannot recover from. A backup that has never been restored is a hope, not a plan.

How to test.

  • Confirm that backups run automatically, that they are stored away from the live server and that they are protected from tampering.
  • Actually restore one into a clean environment and check that the app starts and the data is complete. Time how long it takes.
  • Write down, in a few lines, what to do if the app is attacked or the data is lost: who is called, what is switched off, who tells the customers, and who tells the authorities if personal data is affected.
  • Check that the app records enough to reconstruct what happened: who logged in, who changed what, and when.

A pass looks like. A tested restore, a short written plan and logs that let you reconstruct events.

Making it a routine, and who does what

A one-off review ages quickly, because every new feature can reopen an old problem. A few habits keep the checklist alive without turning it into a project.

  • Run the automated checks on every change. Secret scanning, component scanning and static analysis can be wired into the process that publishes the app, so a failing result stops the release.
  • Keep changes small. Large AI-generated changes are the hardest to review. Ask for work in pieces that a person can read.
  • Repeat items 2, 3 and 8 after any significant change to permissions, login or public forms. They are the ones most easily broken by a rewrite.
  • Set a date. Run the whole list again every few months and after any incident, and keep the dated records together.
  • Separate the roles. One person or team builds, another reviews, and the owner signs off. For apps that handle payments or sensitive data, or in regulated fields, bring in an outside professional.
A one-line sign-off"On this date, [name] tested the running application against the ten checks, found these issues, fixed them on these dates and confirmed the fixes by repeating the tests." That sentence, backed by your notes, is what turns a vague feeling of safety into something you can show.

What this checklist does not cover

No list is complete. This one is deliberately focused on the problems that are most common in AI-built apps and that a careful, non-specialist team can test. It does not replace a penetration test by specialists, a review of your legal obligations, or the particular standards that apply in your industry. Think of it as the minimum sensible bar before launch, and as a way to have a better conversation with whoever does the deeper review.

If you would like a second pair of eyes on an app built this way, we can run the checks on the live application and give you a plain-language report: what is fine, what must be fixed before launch, and what can wait.

Common questions

How long does the checklist take?

For a small app, a careful first run takes a day or two, mostly on permissions and the abuse tests. Later runs are much quicker, especially if the automated checks are already in place.

Can I do it myself if I am not technical?

You can do a good part of it: the two-account permission test, the abuse tests, the data list and the restore drill are all within reach with a little guidance. The code-level checks are better done by a developer who did not write the app.

Is it enough to run an automated scanner?

No. Scanners are useful for exposed keys and known-vulnerable components, but they rarely understand your business rules, so they miss permission problems. Use them as one layer.

What if a check fails?

Write it down, fix it, and repeat the same test until it passes. If many items fail in the same area, particularly permissions, it may be cheaper to rebuild that part than to patch every screen.

How often should we repeat it?

After every large change, after any incident, and at least every few months. The permission and login checks deserve a repeat whenever those parts of the app change.

Photo: Ann poan on Pexels

S

Softbee Labs. We build software and private AI for small and medium businesses, and write down what we learn along the way. See how we work.

One useful email a month.

New articles and experiments from the Labs, in plain language. You can leave at any time.