mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 04:51:51 +00:00
feat(iam): add new check to ensure user does not have policies with admin access (#4802)
This commit is contained in:
committed by
GitHub
parent
8129b174f1
commit
78042063cb
+30
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "iam_user_administrator_access_policy",
|
||||
"CheckTitle": "Ensure No IAM Users Have Administrator Access Policy",
|
||||
"CheckType": [],
|
||||
"ServiceName": "iam",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "high",
|
||||
"ResourceType": "AwsIamUser",
|
||||
"Description": "This check ensures that no IAM users in your AWS account have the 'AdministratorAccess' policy attached. IAM users with this policy have unrestricted access to all AWS services and resources, which poses a significant security risk if misused.",
|
||||
"Risk": "IAM users with administrator-level permissions can perform any action on any resource in your AWS environment. If these permissions are granted to users unnecessarily or to individuals without sufficient knowledge, it can lead to security vulnerabilities, data leaks, data loss, or unexpected charges.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws iam detach-user-policy --user-name <username> --policy-arn arn:aws:iam::aws:policy/AdministratorAccess",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/IAM/admin-permissions.html",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Replace the 'AdministratorAccess' policy with more specific permissions that follow the Principle of Least Privilege. Consider implementing IAM roles such as 'IAM Master' and 'IAM Manager' to manage permissions more securely.",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
from typing import List
|
||||
|
||||
from prowler.lib.check.models import Check, Check_Report_AWS
|
||||
from prowler.providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_user_administrator_access_policy(Check):
|
||||
def execute(self) -> List[Check_Report_AWS]:
|
||||
findings = []
|
||||
for user in iam_client.users:
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = iam_client.region
|
||||
report.resource_arn = user.arn
|
||||
report.resource_id = user.name
|
||||
report.resource_tags = user.tags
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"IAM User {user.name} does not have AdministratorAccess policy."
|
||||
)
|
||||
for policy in user.attached_policies:
|
||||
if policy["PolicyName"] == "AdministratorAccess":
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"IAM User {user.name} has AdministratorAccess policy attached."
|
||||
)
|
||||
break
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
from json import dumps
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_aws
|
||||
|
||||
from tests.providers.aws.utils import AWS_REGION_EU_WEST_1, set_mocked_aws_provider
|
||||
|
||||
|
||||
class Test_iam_user_administrator_access_policy:
|
||||
@mock_aws
|
||||
def test_no_users(self):
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_user_administrator_access_policy.iam_user_administrator_access_policy.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.iam.iam_user_administrator_access_policy.iam_user_administrator_access_policy import (
|
||||
iam_user_administrator_access_policy,
|
||||
)
|
||||
|
||||
check = iam_user_administrator_access_policy()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_no_admin_users(self):
|
||||
iam_client = client("iam", region_name=AWS_REGION_EU_WEST_1)
|
||||
# Create non-admin user
|
||||
user_arn = iam_client.create_user(UserName="non-admin-user")["User"]["Arn"]
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_user_administrator_access_policy.iam_user_administrator_access_policy.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_administrator_access_policy.iam_user_administrator_access_policy import (
|
||||
iam_user_administrator_access_policy,
|
||||
)
|
||||
|
||||
check = iam_user_administrator_access_policy()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "IAM User non-admin-user does not have AdministratorAccess policy."
|
||||
)
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
assert result[0].resource_id == "non-admin-user"
|
||||
assert result[0].resource_arn == user_arn
|
||||
assert result[0].resource_tags == []
|
||||
|
||||
@mock_aws
|
||||
def test_admin_user(self):
|
||||
iam_client = client("iam", region_name=AWS_REGION_EU_WEST_1)
|
||||
|
||||
# Create the AdministratorAccess policy
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{"Effect": "Allow", "Action": "*", "Resource": "*"}],
|
||||
}
|
||||
|
||||
policy_arn = iam_client.create_policy(
|
||||
PolicyName="AdministratorAccess",
|
||||
PolicyDocument=dumps(policy_document),
|
||||
Path="/",
|
||||
)["Policy"]["Arn"]
|
||||
|
||||
# Create admin user
|
||||
user_name = "admin-user"
|
||||
user_arn = iam_client.create_user(UserName=user_name)["User"]["Arn"]
|
||||
|
||||
# Attach AdministratorAccess policy
|
||||
iam_client.attach_user_policy(
|
||||
UserName=user_name,
|
||||
PolicyArn=policy_arn,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_user_administrator_access_policy.iam_user_administrator_access_policy.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_administrator_access_policy.iam_user_administrator_access_policy import (
|
||||
iam_user_administrator_access_policy,
|
||||
)
|
||||
|
||||
check = iam_user_administrator_access_policy()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "IAM User admin-user has AdministratorAccess policy attached."
|
||||
)
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
assert result[0].resource_id == user_name
|
||||
assert result[0].resource_arn == user_arn
|
||||
assert result[0].resource_tags == []
|
||||
Reference in New Issue
Block a user