Back to Checks
Unattached customer managed IAM policy does not allow '*:*' administrative privileges
iam_customer_unattached_policy_no_administrative_privileges
Service: iamSeverity: medium
OfficialBuilt-inVerified
Categories:identity-access
Resource Type:AwsIamPolicy
Customer-managed IAM policies that are unattached are evaluated for statements granting full administrative access using *:* wildcards.
The focus is on policies whose documents include unrestricted actions on all resources.
Risk
An unattached policy with *:* can be attached accidentally or maliciously, granting account-wide control. Attackers could read sensitive data (confidentiality), alter or delete resources (integrity), and disrupt services (availability), enabling rapid privilege escalation and lateral movement.
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks iam_customer_unattached_policy_no_administrative_privilegesRecommendation
Remove or redesign these policies to enforce least privilege:
- Avoid
*in actions/resources; scope precisely and use conditions - Apply permissions boundaries and SCPs as guardrails
- Require peer review and policy validation before attachment
- Use analysis tools to refine permissions and delete unused policies
Remediation
CLI
aws iam create-policy-version --policy-arn <example_resource_arn> --set-as-default --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"iam:GetAccountSummary","Resource":"*"}]}'Terraform
# IAM policy without '*:*' administrative privileges
resource "aws_iam_policy" "<example_resource_name>" {
name = "<example_resource_name>"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = "iam:GetAccountSummary" # Critical: specific action, not '*'
Resource = "*" # Critical: avoids '*:*' admin privileges
}
]
})
}NativeIaC
# CloudFormation: managed policy without administrative '*:*' privileges
Resources:
<example_resource_name>:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: iam:GetAccountSummary # Critical: use a specific action instead of '*'
Resource: "*" # Critical: combined with specific action, avoids '*:*'Other
1In the AWS Console, go to IAM > Policies
2Find the unattached customer managed policy and choose it
3Click Edit policy > JSON
4Remove any statement that allows Action "*" on Resource "*", or replace it with a specific action (e.g., "iam:GetAccountSummary")
5Save changes
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.policy import check_admin_access
class iam_customer_unattached_policy_no_administrative_privileges(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies.values():
# Check only for cutomer unattached policies
if not policy.attached and policy.type == "Custom":
report = Check_Report_AWS(metadata=self.metadata(), resource=policy)
report.region = iam_client.region
report.status = "PASS"
report.status_extended = f"{policy.type} policy {policy.name} is unattached and does not allow '*:*' administrative privileges."
if policy.document:
if check_admin_access(policy.document):
report.status = "FAIL"
report.status_extended = f"{policy.type} policy {policy.name} is unattached and allows '*:*' administrative privileges."
findings.append(report)
return findings