aws-cfn-execute-changeset-approve-path

cloudformation:ExecuteChangeSet alone (approver role, no CreateChangeSet): can apply an attacker-authored pending change set if one already exists - CONDITIONAL on attacker-authored change set being present.

derived aws emits CanModifyCode

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} HasPermission {'stack': None}

where

node_type(?stack) == BuildWorker # AWS::CloudFormation::Stack ?principal has EFFECTIVE cloudformation:ExecuteChangeSet on ?stack ?principal does NOT have cloudformation:CreateChangeSet on ?stack (pure approver) ?stack has RoleARN set exists a pending change set on ?stack created by a different (potentially attacker-controlled) principal

emit

source typeIdentity
target typeCompute
source?principal
target?stack
permissionscloudformation:ExecuteChangeSet
conditionsattacker_authored_changeset
state logicCONDITIONAL(attacker_authored_changeset) — this edge is only meaningful if an attacker-authored change set is already pending on the stack. Without the attacker- authored change set, ExecuteChangeSet alone applies a trusted change set and is not code injection. ACTIVE only when (a) a change set authored by an attacker-controlled principal exists in REVIEW_IN_PROGRESS status AND (b) the approver principal can execute any pending change set without reviewing the template diff. Inherits weakest with the contributing change set evidence.

Narrative

{principal.name} can execute pending change sets on stack {stack.name} (cloudformation:ExecuteChangeSet); if an attacker-authored change set is already pending, approving it applies the attacker's template as the stack's service role.

Raw rule rules/derived/aws/cloudformation.yaml

id: aws-cfn-execute-changeset-approve-path
emits: CanModifyCode
description: "cloudformation:ExecuteChangeSet alone (approver role, no CreateChangeSet): can apply an\
  \ attacker-authored pending change set if one already exists \u2014 CONDITIONAL on attacker-authored\
  \ change set being present."
match:
- - principal: null
  - HasPermission
  - stack: null
where:
- 'node_type(?stack) == BuildWorker  # AWS::CloudFormation::Stack'
- ?principal has EFFECTIVE cloudformation:ExecuteChangeSet on ?stack
- ?principal does NOT have cloudformation:CreateChangeSet on ?stack (pure approver)
- ?stack has RoleARN set
- exists a pending change set on ?stack created by a different (potentially attacker-controlled) principal
emit:
  source_type: Identity
  target_type: Compute
  source: ?principal
  target: ?stack
  permissions:
  - cloudformation:ExecuteChangeSet
  conditions:
  - attacker_authored_changeset
  state_logic: "CONDITIONAL(attacker_authored_changeset) \u2014 this edge is only meaningful if an attacker-authored\
    \ change set is already pending on the stack. Without the attacker- authored change set, ExecuteChangeSet\
    \ alone applies a trusted change set and is not code injection. ACTIVE only when (a) a change set\
    \ authored by an attacker-controlled principal exists in REVIEW_IN_PROGRESS status AND (b) the approver\
    \ principal can execute any pending change set without reviewing the template diff. Inherits weakest\
    \ with the contributing change set evidence."
  confidence: 0.7
  derived_from:
  - cloudformation:ExecuteChangeSet EFFECTIVE on ?stack
  - ?stack RoleARN is set
  - pending attacker-authored change set on ?stack
  false_positive_note: Strictly weaker (0.7 prior) than the combined CreateChangeSet+ExecuteChangeSet
    path. Do NOT emit ACTIVE for a clean, trusted change set approved in normal workflow. This path only
    matters in threat models where a separate attacker-controlled principal can CREATE change sets (social
    engineering, compromised pipeline, SaaS integration). cicd-chains / can-execute-as propagate to CanExecuteAs
    only when ACTIVE.
  narrative: '{principal.name} can execute pending change sets on stack {stack.name} (cloudformation:ExecuteChangeSet);
    if an attacker-authored change set is already pending, approving it applies the attacker''s template
    as the stack''s service role.'
move · open · esc close