October 6, 2026 路 #20
The role any account can assume
A vendor asked for this trust policy so their product can read one bucket. What is wrong?
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "AWS": "*" },
"Action": "sts:AssumeRole"
}]
}Next puzzle in UTC
One try. The first answer sticks.
How to fix it
Principal AWS star without a Condition lets any account call sts:AssumeRole. Name the vendor account and require sts:ExternalId.
This is the confused deputy problem in one block. The role trusts everyone. A stranger creates their own AWS account, calls AssumeRole on your ARN, and then uses whatever the identity policy allows. If that policy was written "just for the integration" and still says s3:* on *, they have your buckets.
Vendors ask for this because it is easy to paste. The safe version names their account and requires an external id they cannot set for a different customer. The external id stops a different customer of the same vendor from tricking the vendor into using your role.
Fix
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111122223333:root" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "acme-prod-7f3a" }
}
}
Generate the external id. Do not let the vendor pick a value they reuse for every customer. Scope the identity policy to one bucket prefix, not the trust policy's account.