Wildcard iam:PassRole Escalates via Lambda UpdateFunction
01 Incident diagnostics
- The Symptom
- CloudTrail shows unexplained UpdateFunctionConfiguration calls changing a function's Role parameter, followed shortly by an Invoke event. Security teams notice API calls originating from a Lambda execution role with permissions far broader than the function's stated purpose, or GuardDuty raises a PrivilegeEscalation:IAMUser finding tied to lambda.amazonaws.com as the passed-to service.
- Detection
- Run: aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=UpdateFunctionConfiguration --max-results 50 and inspect requestParameters.role for unexpected ARNs. Cross-reference with: aws iam simulate-principal-policy --policy-source-arn --action-names iam:PassRole lambda:UpdateFunctionConfiguration --resource-arns arn:aws:iam:::role/* to confirm the wildcard grant resolves to Allow.
- Root Cause
- The attached IAM policy contains a statement such as {"Effect":"Allow","Action":"iam:PassRole","Resource":"*"} with no iam:PassedToService or resource-ARN restriction. Paired with lambda:UpdateFunctionConfiguration or lambda:CreateFunction, this lets any caller swap an existing function's execution role for one they cannot otherwise assume directly. Because Lambda's runtime credential endpoint (169.254.170.2) issues STS tokens for whatever role is attached at invocation time, calling Invoke immediately materialises those elevated credentials inside attacker-controlled code.
- Prevention
- Scope every iam:PassRole grant to explicit role ARNs with an iam:PassedToService condition matching lambda.amazonaws.com only. Deploy a Service Control Policy denying iam:PassRole unless that condition is present. Enforce permission boundaries on all Lambda execution roles capping maximum achievable privilege, and add IAM Access Analyzer's unused-access findings to a weekly review so wildcard PassRole grants surface before they're exploited.
- Blast Radius
- Every IAM role in the account becomes passable to Lambda, including cross-service roles never intended for compute workloads
- Any function updated this way retains the elevated role until manually reverted, creating a persistent backdoor
- Downstream resources reachable by the assumed role (S3, RDS, Secrets Manager, other Lambda functions) inherit exposure
- CI/CD deploy roles with this pattern let a single compromised pipeline stage pivot to full account control
- Cross-account trust relationships attached to the elevated role extend the blast radius beyond the originating account
Apply the intervention
Before you execute
Confirm the incident scope, obtain approved privileged access, and capture the current configuration before applying changes.
Potentially destructive change. Confirm scope, backup and rollback access before copying these commands.
Fix commands and configuration
1. Identify affected functions: aws lambda list-functions --query "Functions[?Role=='arn:aws:iam:::role/AdminEquivalentRole']" 2. Revert the role immediately: aws lambda update-function-configuration --function-name --role arn:aws:iam:::role/ 3. Pull the offending policy: aws iam get-policy-version --policy-arn --version-id 4. Replace the wildcard statement with a scoped condition: aws iam create-policy-version --policy-arn --policy-document file://scoped-passrole.json --set-as-default, where scoped-passrole.json restricts Resource to named execution-role ARNs and adds "Condition":{"StringEquals":{"iam:PassedToService":"lambda.amazonaws.com"}} 5. Audit for other misuse: aws accessanalyzer start-policy-generation --policy-generation-details principalArn= 6. Rotate any credentials the invoked function may have exfiltrated: aws iam create-access-key / delete stale keys, and invalidate active STS sessions where possible via role trust policy update.Verify, roll back or escalate
Verify recovery
Repeat the detection checks after the intervention and confirm that the original symptom no longer occurs.
Rollback
Stop if impact increases. Restore the captured pre-change configuration or approved backup, then reassess before retrying.
Escalate when
Escalate to the platform owner or security incident lead when recovery is unavailable, scope is uncertain, or privileged access cannot be verified.