mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
feat(iam): Check inline policies in IAM Users, Groups & Roles for admin priv's (#2750)
Co-authored-by: Gerard Ocampo <gerard.ocampo@zelis.com> Co-authored-by: Pepe Fagoaga <pepe@verica.io>
This commit is contained in:
@@ -0,0 +1,628 @@
|
||||
from json import dumps
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client, session
|
||||
from moto import mock_iam
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.common.models import Audit_Metadata
|
||||
|
||||
AWS_ACCOUNT_NUMBER = "123456789012"
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
INLINE_POLICY_ADMIN = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{"Effect": "Allow", "Action": ["*"], "Resource": "*"}],
|
||||
}
|
||||
|
||||
INLINE_POLICY_NOT_ADMIN = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{"Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "*"}],
|
||||
}
|
||||
|
||||
ASSUME_ROLE_POLICY_DOCUMENT = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": {
|
||||
"Sid": "test",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"},
|
||||
"Action": "sts:AssumeRole",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class Test_iam_inline_policy_no_administrative_privileges:
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
session_config=None,
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=[AWS_REGION],
|
||||
organizations_metadata=None,
|
||||
audit_resources=None,
|
||||
mfa_enabled=False,
|
||||
audit_metadata=Audit_Metadata(
|
||||
services_scanned=0,
|
||||
expected_checks=[],
|
||||
completed_checks=0,
|
||||
audit_progress=0,
|
||||
),
|
||||
)
|
||||
|
||||
return audit_info
|
||||
|
||||
# Groups
|
||||
@mock_iam
|
||||
def test_groups_no_inline_policies(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Group
|
||||
group_name = "test_group"
|
||||
_ = iam_client.create_group(GroupName=group_name)
|
||||
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 0
|
||||
|
||||
@mock_iam
|
||||
def test_groups_admin_inline_policy(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Group
|
||||
group_name = "test_group"
|
||||
group_arn = iam_client.create_group(GroupName=group_name)["Group"]["Arn"]
|
||||
|
||||
# Put Group Policy
|
||||
policy_name = "test_admin_inline_policy"
|
||||
_ = iam_client.put_group_policy(
|
||||
GroupName=group_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 1
|
||||
assert results[0].region == AWS_REGION
|
||||
assert results[0].resource_arn == group_arn
|
||||
assert results[0].resource_id == policy_name
|
||||
assert results[0].resource_tags == []
|
||||
assert results[0].status == "FAIL"
|
||||
assert (
|
||||
results[0].status_extended
|
||||
== f"Inline policy {policy_name} for IAM identity {group_arn} allows '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_groups_no_admin_inline_policy(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Group
|
||||
group_name = "test_group"
|
||||
group_arn = iam_client.create_group(GroupName=group_name)["Group"]["Arn"]
|
||||
|
||||
# Put Group Policy
|
||||
policy_name = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_group_policy(
|
||||
GroupName=group_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 1
|
||||
assert results[0].region == AWS_REGION
|
||||
assert results[0].resource_arn == group_arn
|
||||
assert results[0].resource_id == policy_name
|
||||
assert results[0].resource_tags == []
|
||||
assert results[0].status == "PASS"
|
||||
assert (
|
||||
results[0].status_extended
|
||||
== f"Inline policy {policy_name} for IAM identity {group_arn} does not allow '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_groups_admin_and_not_admin_inline_policies(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Group
|
||||
group_name = "test_group"
|
||||
group_arn = iam_client.create_group(GroupName=group_name)["Group"]["Arn"]
|
||||
|
||||
# Put Group Policy NOT ADMIN
|
||||
policy_name_not_admin = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_group_policy(
|
||||
GroupName=group_name,
|
||||
PolicyName=policy_name_not_admin,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
|
||||
# Put Group Policy ADMIN
|
||||
policy_name_admin = "test_admin_inline_policy"
|
||||
_ = iam_client.put_group_policy(
|
||||
GroupName=group_name,
|
||||
PolicyName=policy_name_admin,
|
||||
PolicyDocument=dumps(INLINE_POLICY_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 2
|
||||
for result in results:
|
||||
if result.resource_id == policy_name_admin:
|
||||
assert result.region == AWS_REGION
|
||||
assert result.resource_arn == group_arn
|
||||
assert result.resource_id == policy_name_admin
|
||||
assert result.resource_tags == []
|
||||
assert result.status == "FAIL"
|
||||
assert (
|
||||
result.status_extended
|
||||
== f"Inline policy {policy_name_admin} for IAM identity {group_arn} allows '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
elif result.resource_id == policy_name_not_admin:
|
||||
assert result.region == AWS_REGION
|
||||
assert result.resource_arn == group_arn
|
||||
assert result.resource_id == policy_name_not_admin
|
||||
assert result.resource_tags == []
|
||||
assert result.status == "PASS"
|
||||
assert (
|
||||
result.status_extended
|
||||
== f"Inline policy {policy_name_not_admin} for IAM identity {group_arn} does not allow '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
# Roles
|
||||
@mock_iam
|
||||
def test_roles_no_inline_policies(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Role
|
||||
role_name = "test_role"
|
||||
_ = iam_client.create_role(
|
||||
RoleName=role_name,
|
||||
AssumeRolePolicyDocument=dumps(ASSUME_ROLE_POLICY_DOCUMENT),
|
||||
)
|
||||
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 0
|
||||
|
||||
@mock_iam
|
||||
def test_roles_admin_inline_policy(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Role
|
||||
role_name = "test_role"
|
||||
role_arn = iam_client.create_role(
|
||||
RoleName=role_name,
|
||||
AssumeRolePolicyDocument=dumps(ASSUME_ROLE_POLICY_DOCUMENT),
|
||||
)["Role"]["Arn"]
|
||||
|
||||
# Put Role Policy
|
||||
policy_name = "test_admin_inline_policy"
|
||||
_ = iam_client.put_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 1
|
||||
assert results[0].region == AWS_REGION
|
||||
assert results[0].resource_arn == role_arn
|
||||
assert results[0].resource_id == policy_name
|
||||
assert results[0].resource_tags == []
|
||||
assert results[0].status == "FAIL"
|
||||
assert (
|
||||
results[0].status_extended
|
||||
== f"Inline policy {policy_name} for IAM identity {role_arn} allows '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_roles_no_admin_inline_policy(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Role
|
||||
role_name = "test_role"
|
||||
role_arn = iam_client.create_role(
|
||||
RoleName=role_name,
|
||||
AssumeRolePolicyDocument=dumps(ASSUME_ROLE_POLICY_DOCUMENT),
|
||||
)["Role"]["Arn"]
|
||||
|
||||
# Put Role Policy
|
||||
policy_name = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 1
|
||||
assert results[0].region == AWS_REGION
|
||||
assert results[0].resource_arn == role_arn
|
||||
assert results[0].resource_id == policy_name
|
||||
assert results[0].resource_tags == []
|
||||
assert results[0].status == "PASS"
|
||||
assert (
|
||||
results[0].status_extended
|
||||
== f"Inline policy {policy_name} for IAM identity {role_arn} does not allow '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_roles_admin_and_not_admin_inline_policies(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Role
|
||||
role_name = "test_role"
|
||||
role_arn = iam_client.create_role(
|
||||
RoleName=role_name,
|
||||
AssumeRolePolicyDocument=dumps(ASSUME_ROLE_POLICY_DOCUMENT),
|
||||
)["Role"]["Arn"]
|
||||
|
||||
# Put Role Policy - NOT ADMIN
|
||||
policy_name_not_admin = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyName=policy_name_not_admin,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
# Put Role Policy - ADMIN
|
||||
policy_name_admin = "test_admin_inline_policy"
|
||||
_ = iam_client.put_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyName=policy_name_admin,
|
||||
PolicyDocument=dumps(INLINE_POLICY_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 2
|
||||
for result in results:
|
||||
if result.resource_id == policy_name_admin:
|
||||
assert result.region == AWS_REGION
|
||||
assert result.resource_arn == role_arn
|
||||
assert result.resource_id == policy_name_admin
|
||||
assert result.resource_tags == []
|
||||
assert result.status == "FAIL"
|
||||
assert (
|
||||
result.status_extended
|
||||
== f"Inline policy {policy_name_admin} for IAM identity {role_arn} allows '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
elif result.resource_id == policy_name_not_admin:
|
||||
assert result.region == AWS_REGION
|
||||
assert result.resource_arn == role_arn
|
||||
assert result.resource_id == policy_name_not_admin
|
||||
assert result.resource_tags == []
|
||||
assert result.status == "PASS"
|
||||
assert (
|
||||
result.status_extended
|
||||
== f"Inline policy {policy_name_not_admin} for IAM identity {role_arn} does not allow '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
# Users
|
||||
@mock_iam
|
||||
def test_users_no_inline_policies(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM User
|
||||
user_name = "test_user"
|
||||
_ = iam_client.create_user(
|
||||
UserName=user_name,
|
||||
)
|
||||
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 0
|
||||
|
||||
@mock_iam
|
||||
def test_users_admin_inline_policy(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM User
|
||||
user_name = "test_user"
|
||||
user_arn = iam_client.create_user(UserName=user_name,)[
|
||||
"User"
|
||||
]["Arn"]
|
||||
|
||||
# Put User Policy
|
||||
policy_name = "test_admin_inline_policy"
|
||||
_ = iam_client.put_user_policy(
|
||||
UserName=user_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 1
|
||||
assert results[0].region == AWS_REGION
|
||||
assert results[0].resource_arn == user_arn
|
||||
assert results[0].resource_id == policy_name
|
||||
assert results[0].resource_tags == []
|
||||
assert results[0].status == "FAIL"
|
||||
assert (
|
||||
results[0].status_extended
|
||||
== f"Inline policy {policy_name} for IAM identity {user_arn} allows '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_users_no_admin_inline_policy(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM User
|
||||
user_name = "test_user"
|
||||
user_arn = iam_client.create_user(UserName=user_name,)[
|
||||
"User"
|
||||
]["Arn"]
|
||||
|
||||
# Put User Policy
|
||||
policy_name = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_user_policy(
|
||||
UserName=user_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 1
|
||||
assert results[0].region == AWS_REGION
|
||||
assert results[0].resource_arn == user_arn
|
||||
assert results[0].resource_id == policy_name
|
||||
assert results[0].resource_tags == []
|
||||
assert results[0].status == "PASS"
|
||||
assert (
|
||||
results[0].status_extended
|
||||
== f"Inline policy {policy_name} for IAM identity {user_arn} does not allow '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_users_admin_and_not_admin_inline_policies(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM User
|
||||
user_name = "test_user"
|
||||
user_arn = iam_client.create_user(UserName=user_name,)[
|
||||
"User"
|
||||
]["Arn"]
|
||||
|
||||
# Put Group Policy - NOT ADMIN
|
||||
policy_name_not_admin = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_user_policy(
|
||||
UserName=user_name,
|
||||
PolicyName=policy_name_not_admin,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
# Put Group Policy - ADMIN
|
||||
policy_name_admin = "test_admin_inline_policy"
|
||||
_ = iam_client.put_user_policy(
|
||||
UserName=user_name,
|
||||
PolicyName=policy_name_admin,
|
||||
PolicyDocument=dumps(INLINE_POLICY_ADMIN),
|
||||
)
|
||||
# Audit Info
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_inline_policy_no_administrative_privileges.iam_inline_policy_no_administrative_privileges import (
|
||||
iam_inline_policy_no_administrative_privileges,
|
||||
)
|
||||
|
||||
check = iam_inline_policy_no_administrative_privileges()
|
||||
results = check.execute()
|
||||
assert len(results) == 2
|
||||
for result in results:
|
||||
if result.resource_id == policy_name_admin:
|
||||
assert result.region == AWS_REGION
|
||||
assert result.resource_arn == user_arn
|
||||
assert result.resource_id == policy_name_admin
|
||||
assert result.resource_tags == []
|
||||
assert result.status == "FAIL"
|
||||
assert (
|
||||
result.status_extended
|
||||
== f"Inline policy {policy_name_admin} for IAM identity {user_arn} allows '*:*' administrative privileges."
|
||||
)
|
||||
|
||||
elif result.resource_id == policy_name_not_admin:
|
||||
assert result.region == AWS_REGION
|
||||
assert result.resource_arn == user_arn
|
||||
assert result.resource_id == policy_name_not_admin
|
||||
assert result.resource_tags == []
|
||||
assert result.status == "PASS"
|
||||
assert (
|
||||
result.status_extended
|
||||
== f"Inline policy {policy_name_not_admin} for IAM identity {user_arn} does not allow '*:*' administrative privileges."
|
||||
)
|
||||
@@ -5,12 +5,34 @@ from freezegun import freeze_time
|
||||
from moto import mock_iam
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, is_service_role
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, Policy, is_service_role
|
||||
from prowler.providers.common.models import Audit_Metadata
|
||||
|
||||
AWS_ACCOUNT_NUMBER = "123456789012"
|
||||
TEST_DATETIME = "2023-01-01T12:01:01+00:00"
|
||||
|
||||
INLINE_POLICY_NOT_ADMIN = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{"Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "*"}],
|
||||
}
|
||||
|
||||
ASSUME_ROLE_POLICY_DOCUMENT = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": {
|
||||
"Sid": "test",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"},
|
||||
"Action": "sts:AssumeRole",
|
||||
},
|
||||
}
|
||||
|
||||
SECURITY_AUDIT_POLICY_ARN = "arn:aws:iam::aws:policy/SecurityAudit"
|
||||
READ_ONLY_ACCESS_POLICY_ARN = "arn:aws:iam::aws:policy/ReadOnlyAccess"
|
||||
SUPPORT_SERVICE_ROLE_POLICY_ARN = (
|
||||
"arn:aws:iam::aws:policy/aws-service-role/AWSSupportServiceRolePolicy"
|
||||
)
|
||||
ADMINISTRATOR_ACCESS_POLICY_ARN = "arn:aws:iam::aws:policy/AdministratorAccess"
|
||||
|
||||
|
||||
class Test_IAM_Service:
|
||||
# Mocked Audit Info
|
||||
@@ -547,7 +569,7 @@ class Test_IAM_Service:
|
||||
)
|
||||
iam.attach_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyArn="arn:aws:iam::aws:policy/ReadOnlyAccess",
|
||||
PolicyArn=READ_ONLY_ACCESS_POLICY_ARN,
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
@@ -561,14 +583,14 @@ class Test_IAM_Service:
|
||||
assert iam.roles[0].attached_policies[0]["PolicyName"] == "ReadOnlyAccess"
|
||||
assert (
|
||||
iam.roles[0].attached_policies[0]["PolicyArn"]
|
||||
== "arn:aws:iam::aws:policy/ReadOnlyAccess"
|
||||
== READ_ONLY_ACCESS_POLICY_ARN
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test__get_entities_attached_to_support_roles__no_roles(self):
|
||||
iam_client = client("iam")
|
||||
_ = iam_client.list_entities_for_policy(
|
||||
PolicyArn="arn:aws:iam::aws:policy/aws-service-role/AWSSupportServiceRolePolicy",
|
||||
PolicyArn=SUPPORT_SERVICE_ROLE_POLICY_ARN,
|
||||
EntityFilter="Role",
|
||||
)["PolicyRoles"]
|
||||
|
||||
@@ -595,11 +617,11 @@ class Test_IAM_Service:
|
||||
)
|
||||
iam_client.attach_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyArn="arn:aws:iam::aws:policy/aws-service-role/AWSSupportServiceRolePolicy",
|
||||
PolicyArn=SUPPORT_SERVICE_ROLE_POLICY_ARN,
|
||||
)
|
||||
|
||||
iam_client.list_entities_for_policy(
|
||||
PolicyArn="arn:aws:iam::aws:policy/aws-service-role/AWSSupportServiceRolePolicy",
|
||||
PolicyArn=SUPPORT_SERVICE_ROLE_POLICY_ARN,
|
||||
EntityFilter="Role",
|
||||
)["PolicyRoles"]
|
||||
|
||||
@@ -612,7 +634,7 @@ class Test_IAM_Service:
|
||||
def test__get_entities_attached_to_securityaudit_roles__no_roles(self):
|
||||
iam_client = client("iam")
|
||||
_ = iam_client.list_entities_for_policy(
|
||||
PolicyArn="arn:aws:iam::aws:policy/SecurityAudit",
|
||||
PolicyArn=SECURITY_AUDIT_POLICY_ARN,
|
||||
EntityFilter="Role",
|
||||
)["PolicyRoles"]
|
||||
|
||||
@@ -639,11 +661,11 @@ class Test_IAM_Service:
|
||||
)
|
||||
iam_client.attach_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyArn="arn:aws:iam::aws:policy/SecurityAudit",
|
||||
PolicyArn=SECURITY_AUDIT_POLICY_ARN,
|
||||
)
|
||||
|
||||
iam_client.list_entities_for_policy(
|
||||
PolicyArn="arn:aws:iam::aws:policy/SecurityAudit",
|
||||
PolicyArn=SECURITY_AUDIT_POLICY_ARN,
|
||||
EntityFilter="Role",
|
||||
)["PolicyRoles"]
|
||||
|
||||
@@ -753,3 +775,135 @@ nTTxU4a7x1naFxzYXK1iQ1vMARKMjDb19QEJIEJKZlDK4uS7yMlf1nFS
|
||||
|
||||
assert len(iam.saml_providers) == 1
|
||||
assert iam.saml_providers[0]["Arn"].split("/")[1] == saml_provider_name
|
||||
|
||||
# Test IAM User Inline Policy
|
||||
@mock_iam
|
||||
def test__list_inline_user_policies__(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM User
|
||||
user_name = "test_user"
|
||||
user_arn = iam_client.create_user(UserName=user_name,)[
|
||||
"User"
|
||||
]["Arn"]
|
||||
|
||||
# Put User Policy
|
||||
policy_name = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_user_policy(
|
||||
UserName=user_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.users) == 1
|
||||
assert iam.users[0].name == user_name
|
||||
assert iam.users[0].arn == user_arn
|
||||
assert iam.users[0].mfa_devices == []
|
||||
assert iam.users[0].password_last_used is None
|
||||
assert iam.users[0].attached_policies == []
|
||||
assert iam.users[0].inline_policies == [policy_name]
|
||||
assert iam.users[0].tags == []
|
||||
|
||||
# TODO: Workaround until this gets fixed https://github.com/getmoto/moto/issues/6712
|
||||
for policy in iam.policies:
|
||||
if policy.name == policy_name:
|
||||
assert policy == Policy(
|
||||
name=policy_name,
|
||||
arn=user_arn,
|
||||
version_id="v1",
|
||||
type="Inline",
|
||||
attached=True,
|
||||
document=INLINE_POLICY_NOT_ADMIN,
|
||||
)
|
||||
|
||||
# Test IAM Group Inline Policy
|
||||
@mock_iam
|
||||
def test__list_inline_group_policies__(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Group
|
||||
group_name = "test_group"
|
||||
group_arn = iam_client.create_group(GroupName=group_name,)[
|
||||
"Group"
|
||||
]["Arn"]
|
||||
|
||||
# Put User Policy
|
||||
policy_name = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_group_policy(
|
||||
GroupName=group_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
|
||||
iam_client.delete_policy
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.groups) == 1
|
||||
assert iam.groups[0].name == group_name
|
||||
assert iam.groups[0].arn == group_arn
|
||||
assert iam.groups[0].attached_policies == []
|
||||
assert iam.groups[0].inline_policies == [policy_name]
|
||||
assert iam.groups[0].users == []
|
||||
|
||||
# TODO: Workaround until this gets fixed https://github.com/getmoto/moto/issues/6712
|
||||
for policy in iam.policies:
|
||||
if policy.name == policy_name:
|
||||
assert policy == Policy(
|
||||
name=policy_name,
|
||||
arn=group_arn,
|
||||
version_id="v1",
|
||||
type="Inline",
|
||||
attached=True,
|
||||
document=INLINE_POLICY_NOT_ADMIN,
|
||||
)
|
||||
|
||||
# Test IAM Role Inline Policy
|
||||
@mock_iam
|
||||
def test__list_inline_role_policies__(self):
|
||||
# IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create IAM Role
|
||||
role_name = "test_role"
|
||||
role_arn = iam_client.create_role(
|
||||
RoleName=role_name,
|
||||
AssumeRolePolicyDocument=dumps(ASSUME_ROLE_POLICY_DOCUMENT),
|
||||
)["Role"]["Arn"]
|
||||
|
||||
# Put User Policy
|
||||
policy_name = "test_not_admin_inline_policy"
|
||||
_ = iam_client.put_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=dumps(INLINE_POLICY_NOT_ADMIN),
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.roles) == 1
|
||||
assert iam.roles[0].name == role_name
|
||||
assert iam.roles[0].arn == role_arn
|
||||
assert iam.roles[0].assume_role_policy == ASSUME_ROLE_POLICY_DOCUMENT
|
||||
assert not iam.roles[0].is_service_role
|
||||
assert iam.roles[0].attached_policies == []
|
||||
assert iam.roles[0].inline_policies == [policy_name]
|
||||
assert iam.roles[0].tags == []
|
||||
|
||||
# TODO: Workaround until this gets fixed https://github.com/getmoto/moto/issues/6712
|
||||
for policy in iam.policies:
|
||||
if policy.name == policy_name:
|
||||
assert policy == Policy(
|
||||
name=policy_name,
|
||||
arn=role_arn,
|
||||
version_id="v1",
|
||||
type="Inline",
|
||||
attached=True,
|
||||
document=INLINE_POLICY_NOT_ADMIN,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user