DEV Community

Bala Paranj
Bala Paranj

Posted on

The Blind Spot of Every Cloud Config Scanner

✓ Human-authored analysis; AI used for formatting and proofreading.

Checking setting vs Checking combination

Cloud breach post-mortems have no single misconfiguration. Instead, a handful of individually-defensible settings line up into a path: a role that can be assumed, that happens to have more permissions than its caller, reachable from a service that happens to be exposed. Each link looks reasonable in isolation. The risk lives in the wiring.

The 2019 Capital One breach is the canonical example. It was not one catastrophic toggle, but a chain: a misconfigured WAF, an instance role with broad S3 permissions, and the connectivity to walk from one to the other. Every individual component had a plausible reason to exist. The damage came from how they composed.

Almost all the tools evaluate one setting at a time.

How config scanners work

A cloud security posture scanner such as Prowler, Checkov, Trivy's config mode, the built-in CSPM in your cloud console runs a library of checks. Each check asks a yes/no question about a single resource: Is this bucket public? Is this security group open to 0.0.0.0/0? Does this policy grant iam:*?

This model is useful. It is fast, it parallelizes, it maps to compliance frameworks, and it catches the dumb mistakes that still cause most incidents.

There is a class of risk config scanning cannot express, and it shows up in the breach reports. The risk that is a property of the relationship between two resources, not of either resource alone. A check that looks at one node at a time has no place to put an edge.

The maintainers of one of the best open-source scanners in the space have been documenting this exact limitation, in public, for three years.

Exhibit A: the privilege-escalation check that can't see escalation

Prowler is a widely-used open-source security tool. If the best maintained scanner in the category hits this wall, the wall is structural, not a quality problem with one project. Their issue tracker is candid. It tells a three-year story about a single check: iam_policy_allows_privilege_escalation.

April 2023 (#2220). A user reports the check is inaccurate. A maintainer agrees: some actions don't allow privilege escalation by themselves "without some others," and proposes a fix. Maintain tuples of actions that are dangerous only in combination. A contributor immediately points out that the proper solution is the graph-based approach that pmapper uses: model the principals and policies as a graph and find the paths. The maintainer acknowledges they'd need "a matrix because you need the combination of several permissions."

To make a node-by-node check correct, the proposed fix is to manually encode the edges — which combinations of nodes are dangerous together. That is the whole problem.

July 2023 (#2636). A contributor states: it's "a very rudimentary check," and it "only checks for if you have one of the relevant permissions, not… the correct combination to exploit a certain path." A maintainer concedes the check "is not accurate and we need to modify their logic."

November 2024 (#5731). Same check, new false positive. It flags a policy that's scoped safely, because the check "does not differentiate between resource restrictions." The recommended remedy: add it to the mutelist. The tool can't reason about scope, so the human suppresses the wrong answer by hand.

April 2026 (#10703). A maintainer explains why a privilege-escalation detection is left commented out in the codebase: the library "doesn't evaluate resource scope or conditions… It checks every policy regardless of resource constraints." Turning it on "would flag every policy that grants sts:AssumeRole… basically half of any production AWS environment." So it stays off. The fix is deferred indefinitely.

June 2026 (#11466). The same failure mode, now on GCP: a check false-positives because the resource model doesn't carry enough surrounding state to make the call. Different cloud, same shape — that is the point. This isn't a bug in one check. This happens when you ask a node to answer a question about an edge.

Why this is structural, not a backlog item

If you see these issues as "Prowler has some open bugs." That misses it. The maintainers aren't failing to fix a defect. They're running into the boundary of the model. The engineering answer in #10703 is the tell: enabling the precise check would flag half of production, because without the relationship context (what can this role reach, and does it out-permission its caller?), the only choices are to over-report or to stay silent. There's no accurate setting on a node-only dial.

You can see the same issues on feature requests. Recent asks include:

Every one of these is a relationship problem: resource A is safe only in light of resource B. Every one is filed as a request for "another check," because a single-setting scanner offers no other vocabulary. The community is describing edges. The tool can only add nodes.

The cost you're already paying

There's a downstream tax here that is measurable. Across the same tracker, well over a hundred distinct issues are about suppressing findings — mute rules, allowlists, exceptions. Some of those are legitimate accepted-risk decisions. But a real share are corrections: the tool flagged something that was safe in context, and the operator had to hand-wave it away. The maintainers' own prescribed fix for a node-analysis false positive, as in #5731, is "add it to the mutelist."

Every one of those entries is the model's blind spot externalized onto a human. The scanner can't tell that a broad-looking policy is fine because of where it can be used. So a person spends an afternoon proving it and writing a suppression rule. Multiply by every team running the tool.

Thinking in edges

The alternative is a different primitive. Instead of asking "is this setting bad," you model the environment as a graph — resources as nodes, trust and reachability and permission as edges. Ask whether a path exists from something an attacker can touch to something they shouldn't reach.

pmapper does this for IAM. BloodHound pioneered for Active Directory. Prowler contributor in #2220 was gesturing at three years ago. Once the relationships are first-class, the questions that were impossible become natural: Can this exposed function reach a role that can read the customer-data bucket? That's one query over a graph. It's not expressible at all as a per-resource yes/no.

The scope of this argument

It proves a narrow premise: evaluating cloud settings one at a time cannot capture risks that exist only in their combination. The maintainers of a leading scanner have said so, repeatedly, about their own tool, for three years. That premise is solid.

It does not, by itself, prove that any particular graph-based product is the answer, or that node-based scanning is obsolete. Config scanners catch a huge volume of real, simple problems and will remain table stakes. The claim is additive, not replacement: there is a category of risk — the compound, relational kind that dominates breach reports — that the dominant model structurally cannot see, and that gap is worth a different tool sitting alongside the scanner you already run.

The takeaway for a security engineer: when you triage your next pile of CSPM findings, notice how many you suppress because the finding is "technically true but safe in context." That suppression rate is your node-model tax. The findings you wish the tool had raised, the ones about how two safe-looking things combine into one dangerous path are the ones it was never built to find.

Top comments (0)