CloudFormation provisions AWS resources via templates. Attackers abuse CreateStack with PassRole to escalate privileges, extract secrets from templates and outputs, and leverage Custom Resources for arbitrary code execution.
CloudFormation uses JSON/YAML templates to declaratively provision AWS resources as stacks. Templates may contain hardcoded secrets, IAM policies, and infrastructure details that attackers can extract via GetTemplate.
CloudFormation can assume a service role to create resources. If a user has iam:PassRole and cloudformation:CreateStack, they can pass an AdministratorAccess role and create any resource, effectively escalating to admin.
StackSets deploy stacks across multiple accounts and regions simultaneously. Custom Resources invoke Lambda functions or SNS topics during stack operations, enabling arbitrary code execution within the deployment pipeline.
CloudFormation with iam:PassRole is one of the most reliable privilege escalation paths in AWS. Templates leak secrets, StackSets amplify blast radius across accounts, and Custom Resources execute arbitrary code.
aws cloudformation describe-stacksaws cloudformation get-template \
--stack-name TargetStackaws cloudformation list-stack-resources \
--stack-name TargetStackaws cloudformation list-exportsaws cloudformation describe-stack-events \
--stack-name TargetStackaws cloudformation create-stack \
--stack-name privesc-stack \
--template-body file://backdoor-template.yaml \
--role-arn arn:aws:iam::ACCOUNT:role/CFNAdminRole \
--capabilities CAPABILITY_NAMED_IAMaws cloudformation get-template \
--stack-name ProductionStack \
--template-stage Originalaws cloudformation describe-stacks \
--query 'Stacks[].Outputs[].[OutputKey,OutputValue]' \
--output tableaws cloudformation create-stack \
--stack-name custom-res \
--template-body file://custom-resource.yaml \
--role-arn arn:aws:iam::ACCOUNT:role/CFNRole \
--capabilities CAPABILITY_IAMaws cloudformation create-stack-set \
--stack-set-name backdoor-stackset \
--template-body file://backdoor.yaml \
--permission-model SERVICE_MANAGED \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=true \
--capabilities CAPABILITY_NAMED_IAMaws cloudformation list-exports \
--query 'Exports[].[Name,Value]' \
--output table{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"iam:PassRole"
],
"Resource": "*"
}]
}CreateStack + PassRole with no resource constraint allows passing AdministratorAccess role to CloudFormation for full privilege escalation
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::ACCOUNT:role/CFN-LimitedRole",
"Condition": {
"StringEquals": {
"iam:PassedToService": "cloudformation.amazonaws.com"
}
}
}]
}PassRole restricted to a specific least-privilege role and only for CloudFormation service
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "cloudformation:*",
"Resource": "*"
}]
}Full access allows GetTemplate (secret extraction), CreateStackSet (multi-account compromise), and stack deletion
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyCFNWithoutApprovedRole",
"Effect": "Deny",
"Action": [
"cloudformation:CreateStack",
"cloudformation:CreateStackSet"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"cloudformation:RoleArn": [
"arn:aws:iam::*:role/Approved-CFN-Role"
]
}
}
}]
}SCP enforces only approved service roles can be used with CloudFormation stack creation
Never use AdministratorAccess for CloudFormation service roles. Scope to only the resources the stack needs.
aws iam create-role --role-name CFN-LimitedRole \
--assume-role-policy-document file://cfn-trust.json
# Trust: {"Service": "cloudformation.amazonaws.com"}Use Organization SCPs to deny CreateStack unless a pre-approved service role is specified.
Run drift detection regularly to catch out-of-band changes to stack resources, especially IAM.
aws cloudformation detect-stack-drift \
--stack-name ProductionStackPrevent updates to critical resources like IAM roles and security groups within stacks.
aws cloudformation set-stack-policy --stack-name Prod \
--stack-policy-body '{"Statement":[{"Effect":"Deny","Action":"Update:*","Principal":"*","Resource":"LogicalResourceId/AdminRole"}]}'Scan templates with cfn-lint, cfn-nag, or Checkov before deployment to catch secrets and misconfigurations.
cfn_nag_scan --input-path template.yamlPrevent accidental or malicious deletion of critical stacks.
aws cloudformation update-termination-protection \
--enable-termination-protection \
--stack-name ProductionStackAWS CloudFormation Security Card • Toc Consulting
Always obtain proper authorization before testing