← Back to Attack Research

The deputy problem never left: cloud privilege escalation through delegated trust

A confused deputy is a privileged component tricked into using its authority for a caller who was never entitled to it. It is a 1988 idea, and in 2026 it still hands attackers someone else's cloud role. Here is the mechanism across AWS cross-account trust and a fresh Azure Monitor privilege-escalation CVE, and how to find it before someone else does.

In 1988 Norm Hardy named a bug that has never gone away: the confused deputy. A privileged program is tricked into misusing its authority for a caller who was never entitled to it. It is not broken in the classic sense; it does exactly what it was built to do, but it cannot tell whose behalf it is acting on. Move that into the cloud and the deputy becomes an IAM role, a managed service, or a third-party integration you deliberately handed a slice of your trust. When that delegation carries no per-tenant discriminator, the deputy will act for an attacker as readily as it acts for you. This is CWE-441 (Unintended Proxy or Intermediary) and its cousin CWE-863 (Incorrect Authorization), and in 2026 it is still a live path to privilege escalation across both major clouds.

The deputy problem outlives every re-architecture because delegation is not a defect you can remove. It is a feature every cloud sells: a monitoring service that pages your on-call, a backup vendor that reads your buckets, your own automation assuming a role in a sibling account. Each is a decision to let a more privileged component act on your instruction, and each is safe only if the deputy can prove the instruction came from you before it spends your authority.

The class in one paragraph

A confused deputy is a privileged intermediary that performs a sensitive action for a requester without verifying the request was truly authorized for that context. The privilege belongs to the deputy; the intent is supposed to belong to you; the vulnerability is the gap where the deputy conflates the two. Nothing about the deputy is subverted at the code level, which is why these findings survive code review, single-account penetration tests, and vendor security questionnaires. The flaw lives in the trust boundary between two components, not inside either one.

Azure Monitor: CVE-2026-41105

Microsoft assigned CVE-2026-41105 to an elevation-of-privilege issue in Azure Monitor's Action Groups, the component that decides who gets notified and which automated response fires when an alert triggers. The MSRC advisory, published around 8 May 2026 and rated near CVSS 8.1, describes an elevation of privilege in which the Action Group notification and authorization handling let a lower-privileged principal drive privileged operations, moving from a reader-level position toward modifying Action Groups and the alerting they govern. Microsoft publishes limited root-cause detail here, so we will not invent internal mechanics it did not disclose. What matters is the shape: a principal with read-level access gained leverage over a configuration surface it was never granted, because a privileged handler trusted the request more than it should. That shape is a confused deputy, and the fix is the ordinary one: install the update and tighten Action Group RBAC.

AWS cross-account trust: the mechanism in full

The Azure item shows the pattern at the level Microsoft published. The AWS cross-account version shows the mechanism in full, because it is public and it is a configuration class rather than a single CVE. Here is how it goes wrong.

Suppose you run Account A and use a third-party service in Account B. To let B act for you, you create an IAM role in A whose trust policy names B's account as a Principal allowed to call sts:AssumeRole. B's automation then assumes your role and does its job. The catch is that B is a deputy for many customers at once. If your trust policy only asks "is the caller Account B?", the answer is yes for every operation B runs for anyone. As Praetorian's research puts it, the deputy "cannot differentiate between a legitimate target of a privileged action and an incorrect target." An attacker who is a customer of B, or who drives B's portal and learns your role ARN, submits your account ARN and gets B to assume your role.

The intended fix is a per-tenant discriminator called the sts:ExternalId. You add a Condition to your trust policy requiring that the assume call carry a specific external ID, a value B assigns uniquely to you and passes on every AssumeRole it makes for your account. An attacker who does not know your external ID cannot make B assume your role, even when B's automation is willing to try. The safeguard only holds when it is done correctly, and correctly is a narrow target. Praetorian tested ninety vendors and found 37 percent had not implemented the external ID correctly, and another 15 percent had interface protections that were never enforced on the server. A guessable default, a customer-selectable value, or an external ID that is not validated server-side collapses the control. The rule is blunt: only the trusted third party should generate external IDs, they should be cryptographic and non-modifiable, and the deputy must verify the customer actually uses the assigned value.

THE CONFUSED DEPUTY, CROSS-ACCOUNT EDITION attacker ---> [ Vendor Account B ] "assume the role for account A" (knows A's (the deputy) submits A's account ARN role ARN) | | sts:AssumeRole v [ Role in Account A ] | trust policy asks only: "is caller Account B?" --> YES | v attacker now holds A's role in A's tenant WITH sts:ExternalId condition: trust policy asks: "is caller B AND ExternalId == secret-for-A?" attacker does not know A's ExternalId --> DENIED

Same root cause on both clouds: delegated trust with no per-tenant discriminator. The external ID is the discriminator. Conceptual, not from any specific tenant.

The two stories share one sentence: delegated trust without a per-tenant discriminator lets a privileged component act for the wrong requester. On Azure that discriminator was missing inside a managed service's authorization handling, and Microsoft fixed it in code. On AWS it is a condition you own in your own trust policy, and you fix it in configuration. The cloud differs. The class does not.

The security question is never whether to delegate. It is whether the deputy can prove the instruction came from you, and only you, before it spends your authority.

How to recognize your exposure

You do not need to reproduce any exploit to know whether you carry this risk. Delegated trust is declared, not hidden, so the exposure is readable from policy and role metadata you already hold.

How Celvex catches this

Find. Prove. Fix. Verify.

Find

A read-only enumeration of your cloud trust graph surfaces cross-account roles with no external-ID condition, broad principals, and privileged managed-service surfaces reachable by low-privilege identities, all without exercising the escalation.

Prove

In an authorized account we demonstrate the assume path without the external ID, or the privileged operation driven from a reader principal. The trust-policy evidence becomes an Ed25519-signed Proof Capsule you or your auditor can reproduce offline.

Fix

The capsule names the remediation: install the Azure update and tighten Action Group RBAC, add sts:ExternalId conditions and scope the Principal in AWS trust policies, and enforce least privilege on delegated automation.

Verify

We re-attempt the assume call or the privileged operation and confirm it is now denied, then audit CloudTrail and Azure activity logs for any prior abuse. The finding closes with the verified-fix event on record.

Close the confused-deputy gap

The deputy problem is nearly four decades old, and it keeps resurfacing because delegation is what the cloud is for. The discipline is to make each deputy prove that a privileged action was truly requested by the principal entitled to request it, and to check that proof on the server, every time. Do that, and delegation stays a feature. Skip it, and you have handed a stranger the right to act as you.

Verifiable security. Find it. Prove it. Fix it. Verify the fix held. That is what we ship.

Sources

Who can assume your roles, and can they prove it is you?

Free Exposure Check, no signup required. We map your cross-account and cross-tenant trust, flag the roles missing a per-tenant discriminator, and ship a signed Proof Capsule for the highest-confidence finding.

Run a Free Scan →