Most automated security tooling has a depth problem it does not advertise. It is excellent at finding the node (a single misconfiguration, a single injectable parameter, a single exposed endpoint) and it reports each node as an isolated finding with an isolated severity. What it almost never models is the edge: the move from one node to the next, especially the move that crosses a domain boundary. A web bug that becomes an infrastructure foothold. An infrastructure foothold that becomes a cloud-control-plane takeover. The edges are where the breach lives, and the edges are exactly what a single-issue scanner is structurally blind to.
This piece is about the chain that crosses a business-logic primitive into a cloud-admin primitive. It is the highest-impact, lowest-detected attack shape we see, and it is the one our own validation work spent the most time learning to model. By the end you should understand why a stack of clean medium-severity findings can still be a critical breach, what the decision tree looks like from the operator's chair, and the four-part discipline (Find, Prove, Fix, Verify) that closes the chain rather than the individual links. Verifiable security.
The attack pattern in one paragraph
A business-logic primitive is a capability the application intends to offer (upload a file, share a link, invite a user, render a template, import a config) that an attacker uses in an unintended sequence to gain a capability the application never intended to grant. A cloud-admin primitive is any move that touches the control plane underneath the application: reading instance metadata, assuming a role, listing a secrets store, calling a cloud API with the workload's own identity. The chain that matters takes the first kind of primitive and walks it, step by step, into the second. Each step on its own is a medium. The step that crosses the boundary, from "I can make the application do something for me" to "I can make the cloud do something for me," is the one that converts a contained application bug into an account-wide compromise. Commodity scanners score each step independently, see a row of mediums, and never compute the product. The operator computes the product first and works backward to find the cheapest path to it.
The structural reason this shape is under-modeled is mechanical. Chain-aware tools that do exist almost always implement chains as short, single-domain sequences: web→web, or cloud→cloud. They rarely author the cross-domain edge (web→infra, infra→cloud) because authoring it requires holding two mental models (the application's logic and the cloud's trust graph) at the same time. The nodes are cheap to enumerate. The cross-domain edges are expensive to reason about. So they don't get reasoned about, and the deepest, most dangerous chains stay invisible.
Why this still ships in 2026
If deep chains are the breaches that make the news, why is single-issue depth still the industry default? Three structural reasons, each of which a CISO can verify against their own toolchain in an afternoon.
- Severity is computed per-finding, never per-path. CVSS scores a vulnerability in isolation, and every scanner inherits that framing. A scanner that finds an over-permissive upload, a readable metadata endpoint, and an over-scoped service token will emit three separate rows (medium, medium, medium) and a triage queue sorts them below the one "high" it found elsewhere. Nothing in the tool computes that those three mediums, in sequence, equal a critical. The math that matters is the product of the path, and the tooling only ever does the sum of the nodes.
- Chain depth is capped by design, and the cap is shallow. When chaining exists at all, it is short. In our own audit of charting engines, including a review of our internal corpus, we found chain definitions that supported a theoretical depth of ten steps but in practice shipped only single-domain sequences no longer than four, and not one that crossed a business-logic primitive into an infrastructure or cloud primitive. The engine could express the deep chain; nobody had authored it. That is the gap in miniature: the capability exists, the content does not.
- The two halves of the chain live in two different teams. The application bug is the AppSec team's problem. The cloud trust graph is the platform team's problem. The metadata endpoint that bridges them belongs to neither, so the bridge never gets a ticket. The attacker, who reports to no one, treats the boundary as the most interesting part of the map.
The attacker decision tree
The seven-step decision tree an operator walks from a business-logic primitive to cloud-admin. Each step alone is a medium; the crossing of step 3 → step 4 is where contained becomes catastrophic.
The decisive observation is at the junction between step 3 and step 4. Steps 1 through 3 are all inside the application's blast radius: bad, but bounded. The instant step 4 succeeds and the operator is holding the workload's own cloud identity, the blast radius stops being "this application" and becomes "everything this account can touch." That is the boundary crossing. A single-issue scanner that found the upload bug (a medium), the metadata exposure (a medium), and the over-scoped role (a medium) reported three mediums and a clean overall posture. The operator who walked the tree owns the account.
How the famous breaches were chains, not bugs
The two mass-exploitation events most CISOs remember from the 2023 cycle are usually filed in memory as "a single critical CVE." Both were chains, and reading them as chains is the whole point.
MOVEit Transfer, CVE-2023-34362. The Cl0p campaign against MOVEit is remembered as "an SQL injection," but the data theft was a sequence. The entry was a SQL injection in the managed-file-transfer web application, itself a business-logic surface, a product whose entire job is to accept and move files for authenticated partners. That injection was used to reach the database, infer and manipulate session and account state, and ultimately deploy a web shell (the human2.aspx artifact) that gave durable server-side execution. From there the operators enumerated the file store the appliance was built to hold and exfiltrated it at scale across hundreds of organizations. No single step is the breach. The injection without the session manipulation is a contained bug; the session manipulation without the web-shell persistence is noise; the web shell without the data store behind it is an empty foothold. CISA's advisory AA23-158A documents the multi-stage tradecraft, not a one-shot exploit. The lesson: the product was a business-logic primitive (move my files) and the chain walked it into mass data theft.
Atlassian Confluence, CVE-2023-22515. This one is even more instructive because the entry primitive is pure business logic. The flaw was a broken-access-control / privilege-escalation issue that let an unauthenticated attacker reach the application's setup state, the workflow Confluence exposes once, at install time, to create the first administrator. By manipulating that state, an attacker could create their own administrator account on a fully provisioned, in-production server. That is not memory corruption; it is the application doing exactly what its setup logic was written to do, invoked at a moment it should have been impossible to invoke. CISA advisory AA23-289A describes the follow-on: with admin in hand, operators chained into further access and, on many instances, into the host and the surrounding environment. The setup-state bug is the business-logic primitive; admin-on-the-app is the pivot; whatever the Confluence host could reach in its network and cloud context is the cloud-admin destination.
Both stories share the same skeleton as the decision tree above. A primitive the product was designed to offer, pushed one notch past its intent, becomes a foothold; the foothold is walked toward identity and infrastructure; the infrastructure is walked toward the data and the durable access. A scanner that scored the entry bug a 7 and moved on missed the entire chain, because the chain was the breach.
A composite real-world walk
To make the boundary crossing concrete, here is a composite engagement, with details synthesized across several real validation cases, no single customer. The target is a mid-market SaaS platform: a document-collaboration product running on containerized workloads in a public cloud, multi-tenant, with a partner-upload feature for ingesting customer documents.
Step 1, the primitive. The partner-upload form accepts a file and a "destination folder" string. The folder string is a business-logic field: it tells the application where, inside the tenant's storage, to file the document. It was never meant to be a path. The operator notices it is reflected into a server-side storage path with weak normalization.
Step 2, past intent. Supplying a destination of ../../tmp/x writes the uploaded file outside the tenant's intended prefix. By itself, a medium: an arbitrary-write inside the container, scary but contained. The scanner that found it tagged it "path traversal, medium, remediate."
Step 3, host context. The operator does not stop at the write. They use it to drop a small handler that the application's own templating step will render, converting the write into server-side execution, and from that execution they do the one thing the upload bug was never scored for: they issue a request to the cloud metadata endpoint.
# From inside the workload, after converting the write into execution:
$ curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/
app-uploader-role
$ curl -s http://169.254.169.254/latest/meta-data/iam/\
security-credentials/app-uploader-role
{
"AccessKeyId": "ASIA...redacted...",
"SecretAccessKey": "....redacted....",
"Token": "....redacted....",
"Expiration": "2026-05-14T19:40:00Z"
}
Step 4, lift the identity. The metadata endpoint answered. The operator now holds the workload's own IAM role credentials for app-uploader-role. This is the boundary crossing. They are no longer attacking the application; they are authenticated to the cloud account as the workload.
Step 5, enumerate the identity. The role was provisioned years ago by an engineer who needed "upload to a bucket" and granted a little extra to avoid a second ticket. The operator enumerates and finds the role can read a deployment parameter store and, critically, can sts:AssumeRole into a CI role used for blue/green deploys.
$ aws sts get-caller-identity
{ "Arn": "arn:aws:sts::1234:assumed-role/app-uploader-role/i-0ab..." }
# The over-scoped grant nobody re-reviewed:
$ aws iam list-role-policies --role-name app-uploader-role
$ aws ssm get-parameters-by-path --path /deploy/ --with-decryption
# → CI role ARN + a deploy token in a SecureString parameter
$ aws sts assume-role --role-arn arn:aws:iam::1234:role/ci-deployer \
--role-session-name x
# → credentials for a role that can write to the artifact bucket
# AND read the production secrets store
Steps 6 and 7, cloud-admin and objective. The CI role can read the production secrets store, which holds the database master credentials and a long-lived key. From a partner-upload form's "destination folder" field, the operator has reached the production database credentials and a durable cloud identity for persistence. Seven steps. Forty minutes. Four findings, namely path traversal (medium), templating-side execution (high in isolation but never connected to the upload), metadata reachable from the workload (medium), and over-scoped role with AssumeRole (medium), that three separate scanner reports listed as unrelated rows on unrelated pages.
This is why "we ran a scan and it came back mostly mediums" is not reassurance. A row of mediums that share an attacker-walkable edge is a critical that nobody added up.
What we observe in customer environments
We are honest about the limits of our visibility: we validate the assets a customer flags into scope, and we model chains, we do not exhaustively model every conceivable path. With that caveat, the pattern across recent engagements is consistent.
- The workload-identity boundary is the most common crossing. Where we could reach server-side execution from an application primitive, a reachable metadata endpoint or mounted cloud credential was present far more often than the application team expected, because the application team was not the team that provisioned the workload.
- Over-scoped roles are the rule, not the exception. The workload identity almost always carried at least one permission beyond its job, whether a stray
AssumeRole, a readable parameter store, or a wildcard on a bucket, granted once, never re-reviewed. The single most valuable was anAssumeRoleinto a CI/deploy role, because deploy roles are over-trusted by construction. - The chain was invisible to the customer's existing tooling. In the cases where the customer had prior scan reports, the individual nodes were usually present in those reports as scattered mediums. The edge that connected them, and the severity that edge implied, was in none of them.
The honest read: deep, domain-crossing chains are the highest-impact finding class we produce and the one most reliably missed by single-issue tooling. They are also the most defensible to fix, because cutting any single edge breaks the whole chain.
What to do about it: cut the edges, not just the nodes
The good news in chain defense is leverage: you do not have to remediate every node to kill the breach. You have to cut the cross-domain edges. Severing the step-3-to-step-4 crossing, the boundary into cloud identity, collapses the entire tree even if the entry bug survives.
Chain-defense contract: six edges to cut
- Make the metadata endpoint unreachable from application code paths. Enforce IMDSv2 with a hop limit of 1 (or the equivalent metadata-server hardening on your cloud), so a request proxied through an application bug cannot reach
169.254.169.254. This single control severs the most common boundary crossing in the tree. - Scope every workload identity to exactly its job, and re-review on a clock. No
AssumeRolethe workload does not need at runtime, no readable secrets store it does not read in normal operation, no wildcards. The over-scoped role is the edge that turns a foothold into account-wide reach. - Forbid
PassRole/AssumeRoleinto deploy and CI roles from runtime workloads. Deploy roles are the fast path to cloud-admin. A runtime workload should never be able to assume one. - Treat any application primitive that touches the filesystem, a template engine, or an outbound request as a potential SSRF/RCE bridge, and isolate it. Upload, import, render, fetch, and config-load are the step-1 primitives in real chains. Sandbox them and deny their egress to internal ranges.
- Re-score findings by reachable path, not by isolated CVSS. Build or buy a triage step that asks, for every cluster of mediums on the same asset, "does an attacker-walkable edge connect these?" A row of mediums on a shared edge is a critical.
- Validate the whole chain end to end, not the links. A clean per-node scan is not proof the chain is broken. Prove the boundary crossing fails by attempting it, in a controlled, evidence-producing way, and re-attempting it after the fix.
A row of mediums that share an attacker-walkable edge is a critical that nobody added up. The breach is in the edges, not the nodes.
The practical first move for a CISO this week is the cheapest one in the list: confirm IMDSv2 with hop-limit 1 is enforced across your fleet, and pull the IAM policy on every internet-facing workload's role to confirm it cannot AssumeRole into anything. Those two checks, done honestly, cut the two most common edges in every chain we walk.
How Celvex catches this
Find. Prove. Fix. Verify.
We enumerate the nodes like everyone, then we model the edges. The scanner asks, for each application primitive, whether it can reach server-side execution, and for each foothold, whether it can reach workload identity and the cloud control plane.
A confirmed chain ships a Proof Capsule that documents the full path, the entry primitive, every edge, and the boundary crossing into cloud identity, with the exact requests, in a controlled non-destructive replay against staging.
The Capsule's remediation block names the cheapest edge to cut, usually the metadata hardening or the over-scoped role, so the customer kills the whole chain with one change instead of remediating every node.
After the fix, we re-walk the chain. The boundary crossing fails, the path is severed, and the dashboard records a verified-fix event with the broken edge for the auditor record.
Where we sit honestly on the autonomy curve: today our corpus models named cross-domain chains, application-primitive to server-side execution to workload identity to cloud-admin, and ships a reproducible Capsule for each crossing it confirms. Our near-term work is breadth: authoring more cross-domain edges so the engine, which already supports deep branched chains, has the content to walk them. We do not claim to model every conceivable path. We do claim to model the boundary crossing that the single-issue scanners structurally cannot: the one that turns a row of mediums into the breach.
Bottom line
The breaches that define a year are almost never one bug. MOVEit was a business-logic file-transfer surface walked into mass data theft; Confluence was a setup-state logic flaw walked into administrator-on-a-live-server and beyond. Both were deep chains that crossed a primitive the product was built to offer into infrastructure and identity the product was never meant to expose. Commodity scanners score the nodes and miss the edges, cap chain depth shallow, and split the two halves of the chain across two teams that never meet at the boundary. The fix is leverage: cut the cross-domain edges by hardening the metadata endpoint, scoping the workload identity, and forbidding the deploy-role assumption, and the whole tree collapses even if the entry bug survives. Then prove the crossing fails, and verify the proof held.
Verifiable security. Find it. Prove it. Fix it. Verify the fix held. That is what we ship.
Sources
- NVD: CVE-2023-34362 (MOVEit Transfer SQL injection)
- CISA AA23-158A: #StopRansomware: CL0P Exploitation of MOVEit
- NVD: CVE-2023-22515 (Atlassian Confluence privilege escalation)
- CISA AA23-289A: Exploitation of Atlassian Confluence CVE-2023-22515
- NVD: CVE-2023-3519 (Citrix ADC/Gateway unauthenticated RCE, web-shell chain)
- OWASP: Server-Side Request Forgery (the metadata-endpoint bridge)
- AWS: Configuring the Instance Metadata Service (IMDSv2, hop limit)
- CELVEX Group: Proof Capsule format
Find out what your mediums add up to.
Free Exposure Check, no signup required. We model the cross-domain edges, not just the nodes, and ship a Proof Capsule for the highest-confidence chain we can walk against your scoped assets.
Run a Free Scan →