How not to leak customer data

← All posts

How not to leak your customers' data from a vibe-coded app

By Kai Khalid, Nairobi · · 6 min read

ShareLinkedInXWhatsAppFacebook

In October 2026, MyBroadband reported that a South African coffee franchise had exposed company data through an internal dashboard built with an AI coding tool. The dashboard had a login screen. According to the report and the forum post that first disclosed it, the data was sent to the browser along with the login page. Anyone who opened the page source could read it. MyBroadband says the app was taken down after it asked for comment.

I'm not writing this to pile on. I build with AI tools myself here in Nairobi, including my own website and my own AI agents, and I have made early mistakes of my own. The point is that this failure is easy to make and easy to catch. Here is what I check before anything I build goes live.

Why vibe-coded apps leak

AI coding tools optimise for "it works on screen". If you ask for a dashboard with a login, you will get something that looks like a dashboard with a login. Whether the data is actually protected depends on where the checks run and where the data is loaded. Those details are invisible unless you look for them.

Isometric diagram of a vibe-coded app. A server sends all customer records into the browser, where a login panel stands in front of data that is already loaded and visible in the page source.
Diagram 1. The login screen that hides nothing.

The most common failure modes I see:

  • The whole dataset is bundled into the HTML or JavaScript and the login only hides it visually.
  • API keys or database keys sit in front-end code where anyone can copy them.
  • The database is reachable directly from the browser with no row-level rules.
  • There is no limit on how many requests one visitor can make.
Isometric diagram of four leak points in a vibe-coded app: data loaded into the page, a secret key in front-end code, a database the browser can reach directly with no row rules, and a server with no request limit.
Diagram 2. Four places vibe-coded apps leak.

The checklist

Isometric diagram of a safer setup. The browser goes through an edge rate limit to server-side checks and a database with row-level security, with access logs beside the server, and only the rows the user needs return to the browser.
Diagram 3. What safe looks like.

1. View source and watch the network tab

Open your live site in a private window without logging in. Right-click and choose "View page source". Search for words that appear in your real data: a customer name, a store, an amount. Then open your browser's developer tools, go to the Network tab and reload. Look at every response. If you can see data you would want behind a login, so can everyone else.

2. Keep secrets out of the front end

Anything shipped to the browser is public. Database passwords, service keys and private API keys belong in environment variables on the server, for example Railway variables or your host's equivalent. Be careful with build tools that expose any variable with a public prefix to the client. Run a secret scanner such as Gitleaks over your repository before you push.

3. Authenticate and authorise on the server

A login form in the browser decides nothing. The server must check who the user is (authentication) and what they may see (authorisation) before it sends any data. Test this by calling your API directly without a session. It should refuse.

4. Turn on row-level security

If you use Supabase, enable row-level security on every table and write policies for each one. If you use Firebase, write security rules and avoid leaving test-mode rules in production. Without these, a public key in the browser can be enough to read the whole database.

5. Send only what the user needs

Don't load the full dataset and filter it in the browser. Query on the server and return only the rows and fields that user is entitled to. This is data minimisation in practice, and it also makes the app faster.

6. Add rate limits

Login and data endpoints should limit repeated requests from one source. Most hosts and CDNs offer this (I moved my own site to Cloudflare recently), for example Cloudflare rate limiting rules.

7. Log access

Record who accessed what and when, and keep the logs somewhere you can actually search. If something goes wrong, you will need to know what was exposed and to whom. Avoid writing personal data into the logs themselves.

8. Scan your dependencies

AI tools pull in packages freely. Run npm audit or your language's equivalent and switch on Dependabot if your code is on GitHub.

9. Ask the AI for a security review, then verify

It is worth asking your coding assistant to review the project against the OWASP Top 10 and to explain where authentication happens. Treat its answer as a starting point. Confirm each claim with checks 1 and 3 above.

If your app handles personal data, data protection law applies however it was built. In Kenya that is the Data Protection Act, 2019, overseen by the Office of the Data Protection Commissioner. In South Africa it is the Protection of Personal Information Act (POPIA), overseen by the Information Regulator. Both require you to protect personal data with appropriate security measures and to notify the regulator (and, where required, affected people) after a breach. Kenya's Act requires notifying the ODPC within 72 hours of becoming aware of a breach that poses a real risk of harm (section 43). POPIA requires notification as soon as reasonably possible. Read the official texts or take advice for your situation.

When I was Jambojet's de facto Data Protection Officer, the most useful habit was simple: know what personal data you hold, why you hold it and who can reach it. That habit transfers directly to anything you build with AI.

The 10-minute pre-launch check

Before you share a URL with anyone, including your own team:

  1. Open the site logged out, view source, search for real data. (2 min)
  2. Reload with the Network tab open and read every response. (2 min)
  3. Search the code for "key", "secret", "password" and "token". (1 min)
  4. Call one API endpoint without a session and confirm it is refused. (1 min)
  5. Confirm row-level security or security rules are on for every table. (2 min)
  6. Confirm the app returns only the fields each user needs. (1 min)
  7. Write down who to call and what to do if data leaks. (1 min)

Ten minutes will not make an app secure. It will catch the most embarrassing mistakes before anyone else does.

FAQ

Is vibe coding unsafe?

No more than any other way of writing software. The risk comes from shipping code nobody has reviewed. The same checks apply whoever or whatever wrote it.

My app has a login page. Isn't that enough?

Only if the server checks the login before sending data. If the data is already in the page source or JavaScript, the login only hides it.

Can I ask the AI to make my app secure?

You can and should ask it to review the code. Then verify the result yourself with the view-source and direct-API checks.

Do data protection laws apply to internal tools and MVPs?

Yes. If the tool processes personal data, Kenya's Data Protection Act and South Africa's POPIA apply regardless of the app's size or stage.

What should I do if I find my app has leaked data?

Take it offline or lock it down, work out what was exposed and for how long, and check your notification obligations. Kenya's Act requires notifying the ODPC within 72 hours of becoming aware of a breach that poses a real risk of harm (section 43); you can use the ODPC breach form. In South Africa, notify the Information Regulator as soon as reasonably possible. Get legal advice early.

Let's talk

ShareLinkedInXWhatsAppFacebook

Done

Local page

This site keeps a few things in your browser. Functional is always on. Analytics tells me how people use the site, and stays off until you turn it on. Read the Privacy notice.