feat(IAM): add new check iam_group_administrator_access_policy (#4831)

Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com>
This commit is contained in:
Rubén De la Torre Vico
2024-08-22 16:14:45 +02:00
committed by GitHub
parent fc03188bfb
commit dec3e652c5
4 changed files with 173 additions and 0 deletions
@@ -0,0 +1,30 @@
{
"Provider": "aws",
"CheckID": "iam_group_administrator_access_policy",
"CheckTitle": "Ensure No IAM Groups Have Administrator Access Policy",
"CheckType": [],
"ServiceName": "iam",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "high",
"ResourceType": "AwsIamGroup",
"Description": "This check ensures that no IAM groups 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 groups 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_groups_manage.html",
"Remediation": {
"Code": {
"CLI": "aws iam detach-group-policy --group-name <groupname> --policy-arn arn:aws:iam::aws:policy/AdministratorAccess",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/IAM/group-with-privileged-access.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": ""
}
@@ -0,0 +1,27 @@
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_group_administrator_access_policy(Check):
def execute(self) -> List[Check_Report_AWS]:
findings = []
for group in iam_client.groups:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = group.arn
report.resource_id = group.name
report.status = "PASS"
report.status_extended = (
f"IAM Group {group.name} does not have AdministratorAccess policy."
)
for policy in group.attached_policies:
if policy["PolicyName"] == "AdministratorAccess":
report.status = "FAIL"
report.status_extended = f"IAM Group {group.name} has AdministratorAccess policy attached."
break
findings.append(report)
return findings
@@ -0,0 +1,116 @@
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_group_administrator_access_policy:
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_group_administrator_access_policy.iam_group_administrator_access_policy.iam_client",
new=IAM(aws_provider),
):
# Test Check
from prowler.providers.aws.services.iam.iam_group_administrator_access_policy.iam_group_administrator_access_policy import (
iam_group_administrator_access_policy,
)
check = iam_group_administrator_access_policy()
result = check.execute()
assert len(result) == 0
@mock_aws
def test_no_admin_groups(self):
iam = client("iam", region_name=AWS_REGION_EU_WEST_1)
group_arn = iam.create_group(GroupName="test_group")["Group"]["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_group_administrator_access_policy.iam_group_administrator_access_policy.iam_client",
new=IAM(aws_provider),
):
# Test Check
from prowler.providers.aws.services.iam.iam_group_administrator_access_policy.iam_group_administrator_access_policy import (
iam_group_administrator_access_policy,
)
check = iam_group_administrator_access_policy()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "IAM Group test_group does not have AdministratorAccess policy."
)
assert result[0].region == AWS_REGION_EU_WEST_1
assert result[0].resource_id == "test_group"
assert result[0].resource_arn == group_arn
@mock_aws
def test_admin_groups(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 the test group
group_arn = iam_client.create_group(GroupName="test_group")["Group"]["Arn"]
# Attach the AdministratorAccess policy to the test group
iam_client.attach_group_policy(GroupName="test_group", 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_group_administrator_access_policy.iam_group_administrator_access_policy.iam_client",
new=IAM(aws_provider),
):
# Test Check
from prowler.providers.aws.services.iam.iam_group_administrator_access_policy.iam_group_administrator_access_policy import (
iam_group_administrator_access_policy,
)
check = iam_group_administrator_access_policy()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "IAM Group test_group has AdministratorAccess policy attached."
)
assert result[0].region == AWS_REGION_EU_WEST_1
assert result[0].resource_id == "test_group"
assert result[0].resource_arn == group_arn