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).
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?state_machine) ==
Workflow
emit
| source type | Workflow |
|---|---|
| target type | MachineIdentity |
| source | ?state_machine |
| target | ?role |
| 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). |
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.