The Vibe-Coded App Runs. That Doesn’t Mean It’s Safe.

In recent weeks, multiple founders have approached me saying “I built this with AI and it runs fine. But someone warned me about security vulnerabilities and performance bottlenecks, and I have no way to verify it”.

That blind spot is the real problem. When you can’t evaluate your own codebase, an app that feels smooth in testing can easily fall apart under real-world conditions.

“It works” as a test with one user in it

When you click through your own application you are the friendliest possible user. You use exactly as intended, follow the sequence you built, test with a. handful of database rows, and never try anything malicious.

That all changes the moment real users arrive, and it breaks completely when someone actively tries to exploit you.

So while saying “it works” is technically true, it is only measuring the demo path, the single route the code was generated to handle, and the only path anyone has ever walked.

Security, stability, and scale live everywhere else, and ‘everywhere else’ is 90% of the application.

Generated code does not fail at random. Large language models are tuned to finish the task in front of them. Wherever a prompt leaves room for interpretation the model simply produces the quickest path to something that looks finished.

That habit leaves a signature that you can spot immediately.

  • Input validation lives in the browser but vanishes on the server.
  • Database queries are written once and then called inside an unindexed loop.
  • APO keys and secrets end up hardcoded directly into whichever frontend file was open.
  • Rate limiting, caching and queues are missing entirely, because a prompt never asked for them and the single-user demo never required them.

None of this is exotic. Junior developers write the same code, and most seasoned engineers wrote it early in their careers.

The difference is volume and confidence. An AI model produces massive amounts of this code in seconds and never hesitates or flags the parts it wasn’t sure about.

What we look at first

Where the secrets are. In the repository, in the front-end bundle, and in the commit history where a key somebody rotated still sits in plain view. This goes first because it is the one finding that can be used against you while you are still reading the report.

Whether a server check sits behind every browser check. A disabled button is not a permission model. For each protected action the question is whether the API refuses the request when it arrives without your interface in front of it, and the answer is often no.

What is reachable, not what is present. Point an automated scanner at the code and you get hundreds of findings, most of them pure noise. The real work is tracing which vulnerabilities actully sit on a live production path. That is why our tool CodeScan focuses on reachability analysis rather than basic presence detection. A vulnerable function that nothing calls is simple housekeeping, but that same function sitting on your login path will ruin your weekend.

What happens on the thousandth request. Loops hit the database once per row, with no caching, no rate-limiting, and threads that race each other under any real concurrency. Compute waste is a cost problem right up until it becomes an availability problem, and the reflex fix is a bigger instance, which quietly pays that bill every month forever.

Which assumptions were single-use. Plenty of generated code assumes one person is using it at a time. Persistent connections, background jobs, file handling and anything holding state are where those assumptions surfaces, usually right in front of your first real traffic spike.

Whether it can be changed at all. This is the finding that outlasts the others. If nobody can say what a function connects to, then every other fix here is slower and riskier than it looks. We have explored this problem at length in our article, the code nobody can change.

Rescue is not a rewrite

The instinct, when seeing a list of flaws is to start over from scratch. That is almost always the expensive answer.

The application works and people are using it. The running code is the only true specification you have, throwing it away discards that logic entirely.

Our rescue process is much faster and more practical. We close vulnerabilities in order of active risk, fix performance where real traffic hits, and harden the architecture as the code evolves.

You keep a working product and remove its fragility, rather than trading a working application for six months of rebuilding.

What we will not tell you

That we found everything.

A review is a sampling exercise guided by risk, not a proof that nothing else is there. The honest output is a ranked list of what we found, what we could not reach with the access and time we had, and what we would look at next. Anyone who hands you a clean bill of health on an unfamiliar codebase has told you something useful about them rather than about your code.


If AI wrote your application and you have been told it has problems you cannot verify, that is an ordinary situation now and a fixable one. We take AI-assisted code to production as fixed-scope work, and a code review and security audit gives you the ranked list before you commit to anything. Get in touch or call 1300 840 340.

Similar Posts