Back to Checks
Customer managed IAM policy does not allow actions that can lead to privilege escalation
iam_policy_allows_privilege_escalation
Service: iamSeverity: high
OfficialBuilt-inVerified
Categories:identity-accessprivilege-escalation
Resource Type:AwsIamPolicy
Customer-managed IAM policies are evaluated for permissions that enable privilege escalation, including creating or updating policies, altering role trust, attaching higher-privilege policies, or using iam:PassRole to obtain broader access.
Risk
Privilege-escalation permissions let principals assume higher-privilege roles or attach admin policies, impacting:
- Confidentiality via unauthorized data access/exfiltration
- Integrity by modifying policies, configs, or logs
- Availability through resource deletion or disabling controls
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks iam_policy_allows_privilege_escalationRecommendation
Apply least privilege to customer policies:
- Avoid wildcards in
ActionandResource - Remove or tightly scope
iam:PassRole, policy attach/update, and trust-policy changes - Use conditions like
iam:PassedToServiceand tags to constrain use - Enforce permissions boundaries and SCPs
- Separate duties with change review
Remediation
CLI
aws iam create-policy-version --policy-arn <example_resource_id> --set-as-default --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Action":"*","Resource":"*"}]}'Terraform
resource "aws_iam_policy" "<example_resource_name>" {
name = "<example_resource_name>"
# Critical: Deny all actions so the policy cannot allow privilege escalation
policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Effect = "Deny",
Action = "*",
Resource = "*"
}]
})
}NativeIaC
Resources:
<example_resource_name>:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Deny # Critical: Denies all actions so the policy cannot allow privilege escalation
Action: "*"
Resource: "*"Other
1In the AWS Console, go to IAM > Policies
2Open the customer managed policy showing FAIL
3Click Edit policy > JSON
4Remove any Allow statements that enable privilege-escalation actions (for example broad wildcards like "iam:*" or actions such as creating/updating/attaching policies, PassRole, or AssumeRole on wildcards)
5Save changes so the policy no longer allows those actions
6Re-run the check to confirm it passes
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
from prowler.providers.aws.services.iam.lib.privilege_escalation import (
check_privilege_escalation,
)
class iam_policy_allows_privilege_escalation(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies.values():
if policy.type == "Custom":
if not policy.attached and not iam_client.provider.scan_unused_services:
continue
report = Check_Report_AWS(metadata=self.metadata(), resource=policy)
report.region = iam_client.region
report.status = "PASS"
report.status_extended = f"Custom Policy {report.resource_arn} does not allow privilege escalation."
policies_affected = check_privilege_escalation(
getattr(policy, "document", {})
)
if policies_affected:
report.status = "FAIL"
report.status_extended = (
f"Custom Policy {report.resource_arn} allows privilege escalation using the following actions: {policies_affected}".rstrip()
+ "."
)
findings.append(report)
return findingsReferences
- https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege
- https://bishopfox.com/blog/privilege-escalation-in-aws
- https://github.com/RhinoSecurityLabs/Security-Research/blob/master/tools/aws-pentest-tools/aws_escalate.py
- https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/
- https://labs.reversec.com/posts/2025/08/another-ecs-privilege-escalation-path