aws-codedeploy-create-deployment-rce-on-fleet
Create a deployment with an attacker-controlled revision; hook scripts run as root on every EC2/on-prem instance in the deployment group, yielding fleet-wide command execution.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanModifyCode {'deploygroup': None}
{'deploygroup': None} CanExecuteCommand {'vm': None}
where
node_type(?deploygroup) ==
AutomationService
?deploygroup.provider_type == AWS::CodeDeploy::DeploymentGroup
?deploygroup.compute_platform in [Server, OnPremise]
node_type(?vm) == VirtualMachine
emit
| source type | Identity |
|---|---|
| target type | VirtualMachine |
| source | ?principal |
| target | ?vm |
| permissions | codedeploy:CreateDeployment |
| conditions | iam_permission service_state |
| state logic | ACTIVE when ?principal has effective codedeploy:CreateDeployment on the deployment group AND can supply an attacker-controlled revision (S3 key, GitHub ref, or inline AppSpec not restricted by a resource condition locking the revision source), AND the CodeDeploy agent is registered and running on ?vm (service_state). CONDITIONAL(service_state) when the agent's health/ registration is unconfirmed. CONDITIONAL(iam_permission) when codedeploy:CreateDeployment is not yet confirmed as effective. BLOCKED if an SCP or permission boundary denies codedeploy:CreateDeployment at this scope. Do NOT emit for ECS or Lambda compute platforms — lifecycle hook scripts in that model do not execute as root OS commands on a VirtualMachine. |
Narrative
{principal.name} can create a CodeDeploy deployment to group {deploygroup.name} (codedeploy:CreateDeployment) with an attacker-controlled AppSpec, executing arbitrary lifecycle hook scripts as root on every target instance including {vm.name}, yielding fleet-wide command execution.
Raw rule rules/derived/aws/codedeploy.yaml
id: aws-codedeploy-create-deployment-rce-on-fleet
emits: CanExecuteCommand
description: Create a deployment with an attacker-controlled revision; hook scripts run as root on every
EC2/on-prem instance in the deployment group, yielding fleet-wide command execution.
match:
- - principal: null
- CanModifyCode
- deploygroup: null
- - deploygroup: null
- CanExecuteCommand
- vm: null
where:
- node_type(?deploygroup) == AutomationService
- ?deploygroup.provider_type == AWS::CodeDeploy::DeploymentGroup
- ?deploygroup.compute_platform in [Server, OnPremise]
- node_type(?vm) == VirtualMachine
emit:
source_type: Identity
target_type: VirtualMachine
source: ?principal
target: ?vm
permissions:
- codedeploy:CreateDeployment
conditions:
- iam_permission
- service_state
state_logic: "ACTIVE when ?principal has effective codedeploy:CreateDeployment on the deployment group\
\ AND can supply an attacker-controlled revision (S3 key, GitHub ref, or inline AppSpec not restricted\
\ by a resource condition locking the revision source), AND the CodeDeploy agent is registered and\
\ running on ?vm (service_state). CONDITIONAL(service_state) when the agent's health/ registration\
\ is unconfirmed. CONDITIONAL(iam_permission) when codedeploy:CreateDeployment is not yet confirmed\
\ as effective. BLOCKED if an SCP or permission boundary denies codedeploy:CreateDeployment at this\
\ scope. Do NOT emit for ECS or Lambda compute platforms \u2014 lifecycle hook scripts in that model\
\ do not execute as root OS commands on a VirtualMachine."
confidence: 0.9
derived_from:
- ?principal CanModifyCode ?deploygroup
- ?deploygroup CanExecuteCommand ?vm
false_positive_note: "(a) Only EC2/on-prem (compute_platform == Server / OnPremise) deployment groups\
\ run AppSpec hook scripts as root OS commands. ECS deployments shift task-set traffic (no fleet RCE);\
\ Lambda deployments invoke hook Lambda functions (use CanInvoke path instead). (b) The principal\
\ must control the REVISION CONTENT (AppSpec + artifact), not merely trigger a deployment locked to\
\ a trusted S3 bucket via a resource condition. If the effective grant is locked to a specific S3\
\ revision key (codedeploy:RevisionSource condition), the principal can only trigger a clean deployment\
\ \u2014 downgrade CanModifyCode to CONDITIONAL/BLOCKED and this edge inherits it. (c) Fleet scope:\
\ emit one edge per concrete VM in the group's target set, or a fleet-scoped edge; never claim fleet-wide\
\ RCE if the group targets a single instance or a segregated sandbox."
narrative: '{principal.name} can create a CodeDeploy deployment to group {deploygroup.name} (codedeploy:CreateDeployment)
with an attacker-controlled AppSpec, executing arbitrary lifecycle hook scripts as root on every target
instance including {vm.name}, yielding fleet-wide command execution.'