Sample report · a made-up company
A team of six runs an online course site with a monthly subscription. It has 12,400 members, and 2,100 of them pay every month. They built it in two months with an AI coding tool, without a developer, and launched this spring.
Member data lives in an outside database service (Supabase), payments go through a card payment provider, and an "AI study helper" that answers members' questions runs on an outside AI company, billed by usage. They asked for a check because data leaks kept making the news and nobody had ever looked at their service.
As it stood, anyone could read the details of all 12,400 members, and a stolen key could run up thousands of dollars in AI charges within days. We fixed the three most urgent problems, checked again, and both were closed. The first screen on phones also went from 8.4 seconds to 2.3 seconds.
| Risk | What was wrong | If left alone | After the fix |
|---|---|---|---|
| Red | 1. Member data open to anyone Without logging in, anyone could read and change the names, emails, phone numbers, courses and payment history of all 12,400 members | Someone could copy or alter the whole member list | Green Outside requests are refused |
| Red | 2. The admin master key inside the website files The files every visitor downloads contained the admin key | That key can read and delete every record | Green Key replaced and kept only on the company's server |
| Red | 3. Change a number, see someone else's receipt Changing the number at the end of a receipt link showed another member's name, address and amount paid | Members can see each other's details | Green Only your own receipt opens |
| Red | 4. The AI key exposed, with no limit The AI study helper's key was also in the website files, with no usage limit or alert | If someone takes it, a bill of about $230 a month can turn into tens of thousands of dollars in days | Green Limits and alerts set, key kept on the company's side |
| Yellow | 5. The admin screen Anyone who knew the address got the login screen, and wrong passwords were never blocked | Someone can try passwords leaked from other sites until one works | Green Locked for 15 minutes after 5 wrong tries, plus a phone check |
| Yellow | 6. A fake "payment complete" works The site never checked whether the payment provider's notice was genuine | Paid courses can be opened without paying | Green Fake notices are refused |
| Yellow | 7. Slow on phones On a slow connection, 8.4 seconds before the first screen appeared, and 6.2 MB downloaded up front | Visitors stare at a white screen and leave | Green 2.3 seconds, 0.9 MB |
| Yellow | 8. The database service's October 30 change From that day, new tables cannot be read by the site unless they are opened up on purpose | A new feature added with an AI tool quietly stops working | Green Opening new tables is now part of the build steps, tested in advance |
Change 8 does not make anything riskier. It just breaks features if you don't know about it. It also does not close problems like number 1 that are already open.
We fixed the remaining 5 to 8 later the same week.
| Problem | Why it happened | How we fixed it | Time taken |
|---|---|---|---|
| 1. Member data | Each feature added with the AI tool created new tables, but the "see only your own" lock was only on the first two. The five later tables had no lock at all | Put "own records only" and "admin only" locks on all seven tables, and moved admin features to the company's server | 1.5 days |
| 2. Master key | To build the admin screen quickly, the website used the admin key directly | Issued a new key and retired the old one. The new key lives only on the company's server | Half a day |
| 3. Other members' receipts | Receipts were looked up by number alone, with no check that the number belonged to the logged-in member | Check the owner every time a receipt opens, and use numbers that are hard to guess instead of counting up | 1 day |
| 4. AI charges | The website called the AI company directly, with no usage limit | Route calls through the company's server, with 50 a day per member, a monthly cap and an alert at 80% of the cap. Key replaced too | 1 day |
| 5. Admin screen | Left as it was first built | Lock for 15 minutes after 5 wrong tries. Admins confirm on their phone after the password | Half a day |
| 6. Payment notices | The part that checks the notice's signature was empty | Check the signature, then ask the payment provider for the payment status before opening the course | Half a day |
| 7. Phone speed | The first screen pre-loaded part of an intro video (about 3 MB) and used 12 photos at full size | Load the video only when tapped, shrink photos to phone size, load what the first screen needs first | 2 days |
| 8. October 30 change | It was a change on the service's side, and nobody saw the notice | Make "open the new table" part of every build step, and switch the new setting on early to test | Half a day |
| Item | Before | After | How we checked |
|---|---|---|---|
| Member data readable without login | All 12,400 members | 0 | Requested each of the seven tables from outside. All refused |
| Secret keys in the website files | 2 | 0 | Searched all website files again. The old keys are refused |
| Other members' receipts | Open | Refused | Two test members tried each other's numbers |
| AI usage | No limit | 50 a day per member · monthly cap · alert at 80% | Checked that request 51 is blocked and the alert email arrives |
| Guessing admin passwords | Unlimited tries | Locked 15 minutes after 5 wrong tries · phone check | Entered a wrong password six times |
| Fake payment notice | Paid course opened | Refused | Sent an unsigned notice and an altered one |
| First screen on phones | 8.4 seconds | 2.3 seconds | Simulated a slow phone connection, measured three times, took the middle value |
| Download for the first screen | 6.2 MB | 0.9 MB | Same method |
| New features after October 30 | Could stop working | Working | Switched the new setting on early and created a new table |
After the fixes we went through sign-up, paying for a course, watching it, asking the AI study helper and logging in as admin in a real browser. Everything worked.
These are the real incidents we used to pick the problems above. The numbers match the problems in the table. Items marked "reported" were checked through news coverage only.