frontdoor rule · FD013

Cross-account IAM role with no ExternalId

Cross-account trust with no ExternalId

Amazon Web ServicesUpdated Source on GitHub

Severity: high. Medium when organizations:ListAccounts was denied, because frontdoor cannot then prove the account is a stranger — and the finding says so rather than overstating it.

What it means

A role in your account trusts another AWS account, and the only thing required to assume it is knowing the role ARN. An ARN is not a secret: it appears in Terraform, in documentation, in support tickets, and in the vendor's own setup instructions.

This is the confused deputy problem, and it is the reason sts:ExternalId exists.

What an attacker does

They do not attack you. They are another customer of the same vendor.

  1. A monitoring vendor asks every customer to create a role trusting the vendor's AWS account.
  2. An attacker signs up for that vendor as a customer.
  3. In their own vendor configuration, they enter your role ARN.
  4. The vendor, acting exactly as designed, assumes your role and hands the attacker the data.

Every step is authorised. Nothing in your account looks unusual: the caller is the vendor account you deliberately trusted.

How to fix it

Require an external id — a value the vendor generates uniquely for you:

jsonc
"Condition": {
  "StringEquals": { "sts:ExternalId": "a-value-the-vendor-generated-for-you" }
}

Three rules about it:

  • Ask the vendor for it. Every vendor that asks for a cross-account role has one, usually shown next to the setup instructions.
  • Never invent it yourself. The protection comes from the vendor binding that value to your tenant on their side.
  • Never reuse it across vendors.

If the caller is one of your own accounts, an external id is the wrong tool. Name the specific role ARN instead:

jsonc
"Principal": { "AWS": "arn:aws:iam::444455556666:role/deployer" }

When this does not fire

frontdoor does not fire on a trust to a sibling account inside your own AWS Organization. The confused-deputy scenario needs a third party, and there isn't one when the third party is you.

frontdoor answers this once, when you run it; Secorvia checks it continuously across every account you connect, on a free tier that needs no card.