← Back to Blog

I Told an AI to Break Into My Own App. It Found the Front Door Open.

I asked an AI to attack my own app like a stranger would. It found open wallet functions, a leaky file bucket and more. Here's what I fixed and how to run the same test.

By · · blog

I Told an AI to Break Into My Own App. It Found the Front Door Open.

Quick one before we start: AI Build Night is on tonight, 6pm London. Come along.

Yesterday I asked an AI to break into my own app. It found several ways in, and the fixes were live before the day finished. Then a second pass found more.

The app is SalesM8, the sales coaching platform I built. It had just been relaunched with proper billing, team invites and a heap of new features. It looked great. It demoed great. And I had no idea whether a stranger with a browser and a free afternoon could walk straight into someone else's data.

That's the thing about building fast with AI. The speed is real. So is the pile of things nobody checked.

What I actually asked it to do

I didn't ask for "a security review". That gets you a polite checklist and a pat on the head. I told Viktor to act like a bloke who wants in. Pretend you've signed up for a free account. Pretend you're a paying customer who wants to see another customer's stuff. Pretend you're nobody at all, no login. Try every door and write down which ones open.

Then I went and made a cuppa.

What it found

Here's the list from the first wave, in plain English.

A team ID you could swap. Every account belongs to a team, and the app trusted the team ID the browser sent over. Change that ID and you could, in theory, jump into a different team. The fix: the server now works out your team from who you are, and ignores what you claim.

Wallet-credit functions anyone could call. SalesM8 has a usage wallet, so heavy AI users can top up. The functions that add credit to that wallet were open to people who weren't logged in. Nobody had abused it. The log has no sign of anything. But "nobody has abused it yet" is a terrible security policy.

Another customer's integration keys. The app lets people connect their own tools, and those connections hold secrets. One route let a logged-in user ask for a connection by ID without checking it was theirs. That's the classic one, and it's the nasty one.

A file bucket that was far too friendly. Chat attachments sat in storage that anyone with the right link pattern could read. Now they're private, and the app hands out short-lived signed links instead.

Email relays with no bouncer. A few functions that send email were open to the public. That's how your sending domain ends up on a spam list with your name on it.

But here's the thing: not one of those is clever. That's the point. They're the boring, obvious gaps you leave when you build fast, and they're exactly what a bored attacker checks first.

The part that surprised me

Look, the reporting was wrong too, and it looked fine on screen.

The day before, I'd run a separate stress test on the numbers. Dashboards showed totals. Totals looked sensible. But the app was capping its queries at 1,000 rows, so any team with more than that got figures that were just plain short. No error, no warning. The leaderboard looked confident and was lying.

Same lesson, different costume. If a system fails loudly, you fix it by lunch. If it fails politely, you find out when a customer's manager asks why the numbers don't match their CRM.

So that got fixed as well. Manager views now scope properly to the manager's own team, win rate is calculated one way everywhere instead of three slightly different ways, and I deleted a few placeholder figures that had no business being in a real product.

How it ran, start to finish

So it ran in three waves across two days:

  1. Wave one: reporting accuracy. Row caps, team scope, fake figures.
  2. Wave two: the proper attack pass. Team hijack, open wallet functions, the integration keys, the bucket, the email relays.
  3. Wave three: hardening. Captcha on signup, stronger password rules, re-asking for your password before sensitive changes, and a "remove member" action that checks who's asking.

Every fix went live as its own small change, so if one broke something I could roll back that one thing and not the lot. No secrets needed rotating, because nothing in the logs showed anyone had been in.

What I'd tell you to do

You probably don't run a SaaS app. But you almost certainly have something built in a hurry, whether that's a client portal, a booking form wired to a spreadsheet, a Zapier chain, or a GHL workflow that texts people. The same rules apply.

Ask for the attack, not the review. "Is this secure?" gets you a yes. "Here's my setup, how would you get in as a stranger? As a customer? As a disgruntled ex-employee?" gets you a list.

Test as each kind of user. Most holes live between roles. The admin can do it, the customer can't, and nobody checked what the customer can do by guessing a URL.

Check what's public by default. Storage, forms, webhooks, email senders. If it can be reached without a login, assume someone will reach it.

Look for things that fail without telling anyone. A wrong number that nobody notices is worse than a crash.

Fix in small pieces. One change, one check, one deploy. Boring, and it works.

And here's my honest take, mate. AI is a brilliant builder and a rubbish auditor of its own work, because it wants to please you. The trick is to flip its job. Make it the villain for an hour. It's weirdly good at that.

Now the maths. The whole exercise cost me a couple of days of attention and a fair bit of coffee. A leaked customer key would have cost a lot more than that, and a lot more of my reputation.

Why I'm telling you this

Fair question. Telling the world my app had holes isn't the usual move. But I'd rather you hear it from me, with the fixes already live, than pretend I build perfect software. Nobody does. The difference between a tidy business and a messy one is whether somebody goes looking for the problems before the customers do.

And that's the whole job of an AI ops setup. Not to make things look automated. To make sure the boring checks happen every time without anyone remembering to run them. I've now got a health check running on that app on a schedule, so the next hole gets caught by a machine on a Tuesday and not by a customer on a Friday.

Come and watch me break something

Tonight's AI Build Night. 6pm London, live on Zoom, me building one of these systems from scratch while you watch. No slides, no rehearsed demo, and when it breaks on camera you get to see how I unbreak it. That's usually the useful bit. Grab a seat.

Brewed by Steven, poured by Viktor

About Steven Tann: Steven helps business owners build systems that run themselves using AI. After 10+ years helping 7,000+ businesses and building his own autonomous operations, he's the bloke who actually does it, not just talks about it. Find out more at steventann.com.

Tags: Small Business Automation, AI for Small Business, Practical AI, Security, AI Ops