Some years ago we tested a payments flow for a regional e-commerce business. Their scanners were clean — genuinely clean, a tidy report with nothing above informational. They were proud of it, and reasonably so. Then one of our testers noticed that the discount code applied at checkout was validated on the client side but trusted on the server, and that with a single intercepted request you could stack the same code until the price approached zero. No injection, no exploit in the classic sense. Just a piece of business logic that assumed the customer was honest.
No scanner on earth would have found that, because a scanner doesn't know the app is a shop, doesn't know what a discount is meant to do, and has no concept of "customer being dishonest." That's the whole problem with relying on tools to secure applications, and it's worth being blunt about it.
What scanners are actually good at
Let's be fair to the tooling first, because we use it too. Automated application scanners — SAST, DAST, dependency checks — are genuinely useful. They catch known-bad patterns at scale: the unsanitised input, the outdated library with a published CVE, the obvious misconfiguration. They raise the floor. For any team shipping code, running them is basic hygiene, and skipping it is negligence.
But raising the floor is not the same as securing the building. Scanners are pattern-matchers. They find the vulnerabilities they've been taught to recognise, and they are blind to anything that depends on understanding intent — what the application is supposed to do, and therefore what it means to abuse it.
The bugs that actually cause breaches
If you look at how real application compromises happen, a striking proportion come from a small family of flaws that scanners handle poorly or not at all.
There's broken authorisation — the object reference that lets one user pull up another user's records by changing a number in the URL. We find some version of this in a large share of the applications we test, and it's a scanner's blind spot because from the tool's perspective the request looks perfectly valid; it just belongs to the wrong person.
There's business-logic abuse, like the discount stacking above, or a funds-transfer flow that can be raced, or a multi-step process that can be completed out of order to skip a check. There are abuse cases where a legitimate feature is used in an illegitimate sequence. And there are pure design flaws, where the vulnerability isn't in any single line of code but in the architecture — the decision to trust something that shouldn't be trusted.
None of these show up as a red line in a scan report. All of them can end a business's day.
This is why source-code review still earns its place
There's a persistent belief that if the automated tools are clean and the app is "pentested," the code itself doesn't need looking at. In our experience that's exactly backwards for anything that matters — a payments system, a healthcare portal, an authentication service.
A manual secure code review does the reasoning a tool can't. A reviewer traces how untrusted input actually flows through the application, checks authorisation at every object and every action rather than just at the login page, reads the token and session handling for logic gaps, and — crucially — reads the business logic the way an attacker would, looking for the sequence of legitimate steps that produces an illegitimate result. It's slower and more expensive than running a scan, and for the systems where a breach would be catastrophic, it's worth every dirham.
Cover the whole surface, not just the website
One more thing the "run a scanner" mindset misses: modern applications aren't just web pages. The real business logic increasingly lives in the APIs behind them, and APIs are where we find some of the most serious authorisation failures precisely because teams assume the mobile app or single-page front end is the only client that will ever call them. It isn't. Anyone can call an API directly, and when the front end was doing the security, direct calls walk straight past it.
Mobile apps add their own problems. They ship secrets and logic onto devices you don't control, and "hardcoded credentials in a mobile binary" is a finding we still make more often than anyone would like. A serious application security programme covers web, API, and mobile as one surface, because attackers certainly will.
How to actually reduce application risk
The practical answer isn't tools or people — it's both, in the right order. Run the scanners continuously; they're cheap and they clear out the obvious. But for anything where a breach would genuinely hurt, put a skilled human on it: someone who will validate exploitability instead of forwarding a raw scan, who will read the code and the logic, and who will tell you not how many findings there are but which ones an attacker would actually use.
And insist on that last distinction. A report that lists two hundred issues sorted by CVSS is a scanner's output with a logo on it. A report that says "here are the three ways someone takes over an account, and here's how you close them" is the work of someone who understood your application. Only one of those is worth paying for.
Spend your testing budget where a breach would hurt most
Nobody has an unlimited testing budget, so the practical question is where to put the expensive manual effort. The answer is to follow the blast radius. Rank your applications not by how new or how visible they are, but by what happens if they're compromised. The payment flow, the authentication service, the API that exposes customer records, the healthcare portal handling patient data — these deserve real human review and source-code reading, because a logic flaw in any of them is a business-ending event, and those are exactly the flaws scanners miss. The marketing microsite with no sensitive data behind it can live on automated scanning; it simply isn't worth a consultant's week. We often see the budget spread evenly across everything, which sounds fair and is actually a mistake — it under-tests the things that matter and over-tests the things that don't. Concentrate the depth where the consequences are severe, keep the scanners running everywhere as a baseline, and you get far more risk reduction for the same money than a flat, even coverage ever delivers.
If you're shipping anything that handles money, identity, or sensitive data, it's worth having someone read it the way an attacker would.
