Asad Ali
Taipei · overnight turnaround for US & EU Get an audit

It compiles.
It renders.
It's still wrong.

I'm a security researcher. I find the failures in AI-built apps that never throw an error.

Data anyone can overwrite · records that exist three times · gaps in what was never collected

PhDComputer science
5+ yrsCybersecurity research, building security products
10+ yrsWriting production code
2 yrsBuilding production apps through AI agents
Three faults that never throw an error. All three are things I check on every audit. select a specimen
create policy "anon_write" on venues
  for insert to anon with check (true);

create policy "anon_update" on venues
  for update to anon using (true);
What it looked like
Row-level security enabled. Policies written. Dashboard green.
What was actually true
The anonymous key shipped inside the frontend bundle could rewrite every row in the table. Twenty cities of data, editable by anyone who opened developer tools.

Does any of this sound like your app?

  • You're not sure whether one customer can see another customer's data, and you can't find out.
  • It was fast with test data and it crawls now that it's real.
  • You need to add one field and you're afraid to, because last time something unrelated broke.
  • The same customer, product or place appears more than once and nobody knows which row is real.
  • You're taking payments and you've never checked whether the price is decided on your server or in the customer's browser.
  • Signups look weak, and nobody has confirmed that your verification emails are actually arriving.
  • The app confidently returns something wrong, and there's no error anywhere to follow.
  • Your AI assistant keeps proposing fixes. Each one is plausible. None of them ends the problem.

What I fix

security · three ways in

start here

Security audit

A severity-ranked report of what's exposed: access control, data anyone can read or overwrite, secrets sitting in your client bundle, whether your checkout trusts a price the browser sent it, and what an attacker reaches once they have a login. The first pass is free and comes back within 48 hours. If there's nothing worth paying for, I'll tell you that.

free48 hours
most people want this

Review & remediation

I audit, then fix what I found and verify it's actually closed. You end up with a secured app, not a to-do list. Work happens on a branch, never straight on production, and you get a written record of exactly what was changed and what was left alone.

$600 – 1,500quoted after the audit

Security retainer

Ongoing review as you ship. Every new table, endpoint and integration adds surface, and the fastest way to reopen a hole I just closed is to build the next feature on top of it. Monthly re-check, with findings before they become incidents.

$250 – 400per month

while I'm in there

closest neighbour

App rescue

Bolt, Lovable, Replit, Cursor, v0. The app got built. Then it met real users and real data. I go through the parts the builder never checks: who can actually read and write your tables, what your public key is allowed to do, which queries fall over at volume, and why a schema change breaks three things it shouldn't touch.

$400 – 900

Coverage audits

The failure that isn't in your code and isn't in your schema. It's in what was never collected. Results that look complete because nothing can tell you what's missing from them. I work out what your data doesn't have, how badly it's distorting what users see, and what it costs to close the gap. In my own build this showed up as a dinner recommendation 43 km from the beach the app had just suggested — the code was right and the schema was right, but no coastal restaurants had ever been collected, so that was the closest thing that existed.

$250 – 600

Data cleanup and record matching

Deduplicating a customer list. Merging two catalogues. Matching one system's records to another's when the names disagree and half of them are spelled three ways. I build the match, score every decision by confidence, and hand back the near-ties for a human to look at rather than guessing on your behalf.

$200 – 600

AI workflow automation

Wiring a language model into a workflow takes an afternoon. Stopping it quietly producing nonsense at 3am is the actual job. I build the failure paths in: what happens when the model returns malformed output, when the API times out, when a field comes back empty and the next step doesn't notice. Lead capture into a CRM, document and email triage, scheduled reports, syncing two systems that disagree.

from $400retainer from $250/mo

How it works

  1. You give me a look.Read-only access is fine. A repo link, a project, or just a description of what's going wrong — whatever you're comfortable sharing.
  2. You get a written report within 48 hours.What's broken, how serious each item is, what it costs to fix. This part is free. If you take the report and fix it yourself, that's a good outcome.
  3. You choose what gets fixed.Fixed price agreed before any work starts, so the number can't move on you. If the audit turns up nothing worth paying for, I'll tell you that rather than invent work.

The first report costs nothing and takes 48 hours.

Get an audit

Three things I found the slow way

From two years building production apps almost entirely through AI coding agents — the same way most of my clients built theirs.

critical

A public key that could rewrite twenty cities

Security looked configured, and technically it was. Both the insert and update policies checked true, which meant the key sitting in every visitor's browser had full write access to the entire dataset. Nothing behaved strangely, because nobody had tried yet.

measuring nothing

A detector that would have flagged a quarter of anything

I specced a rule to catch overrated tourist traps. It fired on 27% of real venues, including five of the thirteen most famous places in the city. The maths explained why: as written, the same rule flags 28% of pure random noise. I killed it rather than ship a number that looked like a signal.

the finding was the failure

Half the records wouldn't match, and that was the answer

Matching 126 collected places against the live database recovered only 63. The instinct is to tune the matcher. The real answer was that the database had never held those kinds of records at all. The match rate wasn't a bug to fix, it was a map of what was missing.

Who you'd be working with

I built production apps the same way you built yours — prompting agents, shipping fast, trusting output that looked right. Then I spent two years finding everything that method gets wrong. Every fault on this page came out of that, and I found them because I was the one who had to live with them.

  • PhDComputer science
  • 5+ yrsCybersecurity research and building security products
  • 10+ yrsWriting production code
  • 2 yrsBuilding, breaking and repairing agent-built apps in production

No agency, no team, no account manager. You deal with the person doing the work. I'm in Taipei, which for most clients means you describe the problem at the end of your day and the report is waiting when you start the next one.

Tell me what's going wrong.

No call required. Describe the symptom in a couple of sentences and I'll tell you whether it's something I can help with.

Or email me directly: YOU@YOURDOMAIN.COM