A clean scan report is one of the most comfortable documents in security. It is also one of the most misread. "Zero criticals" does not mean "no critical weaknesses" — it means "no critical weaknesses of the kinds this tool is built to recognise." Those are very different claims, and the distance between them is where most real incidents live.

This is not a complaint about scanners. Automated scanning is genuinely excellent at what it does, and any serious programme should run it continuously. But every scanner — commercial, open, cloud, on-prem — shares the same five structural blind spots, because they follow from what scanning fundamentally is: comparing a target against a library of things someone already described. Here is each gap, why no amount of better tooling closes it, and what actually covers it.

1. Business-logic flaws

A scanner knows what a vulnerability looks like. It does not know what your application is for.

Consider a refund workflow where an employee can approve their own request, a discount code that stacks with itself, a multi-step checkout where skipping step two leaves the order in a paid-but-unpriced state, or a subscription downgrade that never revokes the premium entitlement. Every request in those flows returns HTTP 200. Nothing is malformed. No signature matches, because nothing in the traffic is anomalous — the application is doing precisely what it was coded to do. The defect is that what it was coded to do is wrong for the business.

No scanner can find these, because finding them requires knowing the rules the software is supposed to enforce, and those rules live in your head, your policies, and your contracts — not in any vulnerability database.

What covers it: threat modelling at design time, and human-led testing where the tester is briefed on the domain rules. This is the single strongest argument for penetration testing over scanning alone: you are paying for someone who can be told "a user must never approve their own refund" and then go try to do exactly that.

2. Broken access control

Access control is consistently at or near the top of the OWASP Top Ten, and it is systematically under-detected by automated tools for a simple reason: a scanner usually tests as one identity, and it has no model of who should be allowed to see what.

When a scanner requests a record and receives it, that is a success response. Whether the account it authenticated as had any business receiving that record is a question about your authorisation policy, not about the HTTP exchange. Object-level authorisation gaps, horizontal access between peer accounts, tenant-boundary leaks in multi-tenant systems, and privilege checks enforced only in the UI while the API accepts anything — all of these produce clean, well-formed, entirely unremarkable responses.

What covers it: testing with multiple accounts at different privilege levels and explicitly comparing what each can reach against what each should reach. This needs a deliberate authorisation matrix — one row per role, one column per resource — which is an artefact your team has to author. Server-side enforcement on every object reference is the fix; the matrix is how you prove it.

3. Findings that are only dangerous together

Scanners score findings in isolation. Attackers do not use them in isolation.

A verbose error page that leaks an internal hostname is informational. A directory listing on a staging path is low. An account-enumeration difference in a login response is low. A password-reset flow that accepts an email address you learned from the first finding is, on its own, working as designed. Each item sits below the threshold where anyone schedules remediation. Chained in order, they are a route in.

The severity model is the problem: it is additive when reality is multiplicative. Twenty lows on a report get triaged as "twenty lows," and the report offers no vocabulary for "these three, in this sequence, are one high."

What covers it: asking of every low-severity finding, "what does this enable?" rather than "how bad is this?" Reviewing findings as a graph rather than a list is difficult, tedious work, and it is exactly what a good tester does. It is also the reasoning gap we built VectSpor to attack — compound chain detection is one of its core ideas, though it is still pre-release and waitlist-gated, so treat that as a direction of travel rather than a recommendation.

4. Capacity and resource shape

Most scanners check whether an endpoint is vulnerable. Very few check whether it is expensive.

An endpoint can be perfectly correct, fully patched, injection-free — and still do a meaningful amount of database and framework work per call while having no rate limit in front of it. Availability risk of this kind is a property of the relationship between one route's cost and your total capacity. There is no CVE for "this search query is legitimately slow," and no signature for "this pool has fewer workers than you think," because these are facts about your deployment, not about any software package.

We have written about this at length from the defensive side, in the WordPress attack-surface map and in why sitting behind a CDN is not the same as being safe.

What covers it: measuring per-route cost under realistic concurrency and knowing your own pool limits, then rate-limiting by work done rather than by request count. Our DDoS mitigation work starts here, because you cannot set a meaningful threshold for traffic you have never measured.

5. Topology and environment exposure

The fifth blind spot is not in your application at all, which is precisely why application scanners never see it.

Edge protection assumes traffic arrives through the edge. If the origin is directly reachable — through a forgotten DNS record, a hostname disclosed in certificate transparency logs, or a management port exposed on the host — then the protection is decorative for anyone who takes thirty seconds to look. Adjacent classes: a staging environment with production data and weaker auth, an object-storage bucket whose permissions drifted, a CI runner holding deploy credentials, an expired-but-still-trusted internal certificate.

A scanner pointed at your domain tests the front door you told it about. It has no opinion about the other doors, because it was never told they exist.

What covers it: treating asset inventory as a security control. You cannot assess what you have not enumerated, and most organisations' real attack surface is meaningfully larger than their documented one. External attack-surface discovery, DNS hygiene, and origin-lockdown verification belong on a recurring schedule, not in a one-off project. This is core to how we approach threat intelligence and SOC operations.

What this means for a testing programme

Scanning answers "does this target match a known weakness?" — fast, cheap, and repeatable. It cannot answer "given how this specific system is built and what it is for, where would a thoughtful adversary push?" Both questions matter. Only one of them has a database.

The practical conclusion is not to distrust scanners; it is to stop treating scan coverage as security coverage. A balanced programme looks roughly like this:

  • Continuous automated scanning for known-vulnerability and patch hygiene — the volume work, run constantly, cheap per finding.
  • Periodic human-led testing scoped explicitly at logic, authorisation, and chaining — the classes above that no tool reaches.
  • Standing asset and capacity awareness so that topology drift and resource-shape risk are visible between engagements.

The most useful question to ask a vendor — or your own team — is not "how many vulnerabilities did we find?" but "which of these five classes did this activity actually cover?" A programme that can answer that honestly is in far better shape than one with a longer findings list.

If you want a second opinion on where your current coverage sits, that is the conversation our security practice exists for — talk to an engineer.

Everything above is defensive guidance for systems you own or are authorised to assess.