Not affiliated with AWS
← Back to Attack Library

Privilege Escalation

iam:SetDefaultPolicyVersion (lossy)

An attacker with iam:SetDefaultPolicyVersion switches a managed policy to any older version that broadens their access, even when the switch strips permissions other attached principals rely on.

Required Permissions

  • iam:SetDefaultPolicyVersion
  • iam:ListPolicyVersions
  • iam:GetPolicyVersion

Description

iam:SetDefaultPolicyVersion changes which stored version of a managed policy is active. Unlike the safe variant, this one accepts a target version that drops permissions the current default grants, in exchange for broader net access.

The hackaws agent lists versions on each customer-managed policy attached to the caller, reads each non-default version, and compares its expanded action set to the current default's. It keeps only versions that grant at least one action the current default does not and lack at least one action the current default has. Among those qualifying versions, it picks the one that gains the most new permissions, weighting new IAM and STS actions higher than other services, and breaking ties on the version that drops the fewest existing permissions. That trade is the whole point: the safe variant refuses it, this one takes it.

Use this only when the safe variant finds no superset candidate and the assessment accepts that attached workloads may break to prove the escalation path. Before applying the switch, the agent skips candidates that would strip the caller's own iam:SetDefaultPolicyVersion on this policy. The printed cleanup command would then be one the caller cannot run.

Impact

Every principal attached to the policy picks up the new version's permissions and loses whatever the current default granted that the new version does not. Workloads that depend on the dropped actions start seeing AccessDenied immediately. If the dropped actions include iam:SetDefaultPolicyVersion for a principal that was relying on this policy for it, that principal cannot revert the change from inside the policy. Rollback then requires another identity that still holds the permission on this policy ARN.

Detection

Alert on SetDefaultPolicyVersion events and diff the new default against the previous one. Flag any switch where the new default removes actions, resources, or statements. Pair the event with ListPolicyVersions and GetPolicyVersion reconnaissance calls that precede it. Monitor for broken workloads shortly after a version switch: a sudden spike in AccessDenied on actions a policy used to grant is a strong lagging signal.

Mitigation

Delete old policy versions after tightening a policy so there is nothing lossy to roll back to. Deny iam:SetDefaultPolicyVersion from non-admin principals through an SCP. Apply permission boundaries so a restored version cannot grant more than the boundary allows. Keep policy changes under code review in a CI pipeline rather than letting runtime identities flip the default pointer.