aws-sf-exposes-exec-role-cred

A state machine exposes its execution role's credentials to any code injected into a Task state (AWS SDK calls are made with the execution role's session).

derived aws emits ExposesCredential

match

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

{'state_machine': None} ExecutesAs {'role': None}

where

node_type(?state_machine) == Workflow

emit

source typeWorkflow
target typeMachineIdentity
source?state_machine
target?role
conditionsservice_state
state logicACTIVE when the state machine ExecutesAs edge is ACTIVE (state machine exists and has a configured execution role). CONDITIONAL(service_state) when the state machine is being created but the role binding is not yet confirmed. BLOCKED if the ExecutesAs edge is BLOCKED (e.g., state machine or role is deleted).

Narrative

State machine {state_machine.name} makes all Task state AWS service calls using {role.name}'s credentials; attacker code injected into the definition (via states:UpdateStateMachine) runs as {role.name} for every Task state.

Raw rule rules/derived/aws/stepfunctions.yaml

id: aws-sf-exposes-exec-role-cred
emits: ExposesCredential
description: A state machine exposes its execution role's credentials to any code injected into a Task
  state (AWS SDK calls are made with the execution role's session).
match:
- - state_machine: null
  - ExecutesAs
  - role: null
where:
- node_type(?state_machine) == Workflow
emit:
  source_type: Workflow
  target_type: MachineIdentity
  source: ?state_machine
  target: ?role
  permissions: []
  conditions:
  - service_state
  state_logic: ACTIVE when the state machine ExecutesAs edge is ACTIVE (state machine exists and has a
    configured execution role). CONDITIONAL(service_state) when the state machine is being created but
    the role binding is not yet confirmed. BLOCKED if the ExecutesAs edge is BLOCKED (e.g., state machine
    or role is deleted).
  derived_from:
  - <ExecutesAs edge_id ?state_machine -> ?role>
  false_positive_note: "Not an escalation by itself. This edge expresses the fact that code execution\
    \ in any Task state (or a malicious definition injected via UpdateStateMachine) runs with the execution\
    \ role's AWS credentials \u2014 the session token is used by the Step Functions service to make the\
    \ AWS SDK calls defined in Task states. The attack path value comes from combining this with CanModifyCode\
    \ (B1) or CanCreateWorkloadAs (B2). Unlike Lambda, the execution role credentials are not directly\
    \ accessible to a worker's code \u2014 they are used by the Step Functions service on the caller's\
    \ behalf. An injected Task state calling arn:aws:states:::aws-sdk:sts:getCallerIdentity can exfiltrate\
    \ the caller identity, confirming the role in use, but direct credential retrieval requires an HTTP\
    \ endpoint target."
  narrative: State machine {state_machine.name} makes all Task state AWS service calls using {role.name}'s
    credentials; attacker code injected into the definition (via states:UpdateStateMachine) runs as {role.name}
    for every Task state.
move · open · esc close