mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
feat(test): Remaining IAM tests (#1451)
This commit is contained in:
@@ -12,14 +12,18 @@ class iam_administrator_access_with_mfa(Check):
|
||||
report.resource_id = group.name
|
||||
report.resource_arn = group.arn
|
||||
report.region = iam_client.region
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Group {group.name} has no policies."
|
||||
|
||||
if group.attached_policies:
|
||||
admin_policy = False
|
||||
report.status_extended = (
|
||||
f"Group {group.name} provides non-administrative access."
|
||||
)
|
||||
for group_policy in group.attached_policies:
|
||||
if (
|
||||
group_policy["PolicyArn"]
|
||||
== "arn:aws:iam::aws:policy/AdministratorAccess"
|
||||
):
|
||||
admin_policy = True
|
||||
# users in group are Administrators
|
||||
if group.users:
|
||||
for group_user in group.users:
|
||||
@@ -30,27 +34,9 @@ class iam_administrator_access_with_mfa(Check):
|
||||
):
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"Group {group.name} provides administrator access to User {group_user.name} with MFA disabled."
|
||||
findings.append(report)
|
||||
elif (
|
||||
user["user"] == group_user.name
|
||||
and user["mfa_active"] == "true"
|
||||
):
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Group {group.name} provides administrator access to User {group_user.name} with MFA enabled."
|
||||
findings.append(report)
|
||||
else:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Group {group.name} provides administrative access but does not have users."
|
||||
findings.append(report)
|
||||
if not admin_policy:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Group {group.name} provides non-administrative access."
|
||||
)
|
||||
findings.append(report)
|
||||
else:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Group {group.name} has no policies."
|
||||
findings.append(report)
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
from json import dumps
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_administrator_access_with_mfa_test:
|
||||
@mock_iam
|
||||
def test_group_with_no_policies(self):
|
||||
iam = client("iam")
|
||||
group_name = "test-group"
|
||||
|
||||
arn = iam.create_group(GroupName=group_name)["Group"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa import (
|
||||
iam_administrator_access_with_mfa,
|
||||
)
|
||||
|
||||
check = iam_administrator_access_with_mfa()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == group_name
|
||||
assert result[0].resource_arn == arn
|
||||
assert search(
|
||||
f"Group {group_name} has no policies.", result[0].status_extended
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_group_non_administrative_policy(self):
|
||||
iam = client("iam")
|
||||
group_name = "test-group"
|
||||
policy_name = "policy1"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
policy_arn = iam.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
arn = iam.create_group(GroupName=group_name)["Group"]["Arn"]
|
||||
iam.attach_group_policy(GroupName=group_name, PolicyArn=policy_arn)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa import (
|
||||
iam_administrator_access_with_mfa,
|
||||
)
|
||||
|
||||
check = iam_administrator_access_with_mfa()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == group_name
|
||||
assert result[0].resource_arn == arn
|
||||
assert search(
|
||||
f"Group {group_name} provides non-administrative access.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_admin_policy_no_users(self):
|
||||
iam = client("iam")
|
||||
group_name = "test-group"
|
||||
|
||||
arn = iam.create_group(GroupName=group_name)["Group"]["Arn"]
|
||||
iam.attach_group_policy(
|
||||
GroupName=group_name,
|
||||
PolicyArn="arn:aws:iam::aws:policy/AdministratorAccess",
|
||||
)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa import (
|
||||
iam_administrator_access_with_mfa,
|
||||
)
|
||||
|
||||
check = iam_administrator_access_with_mfa()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == group_name
|
||||
assert result[0].resource_arn == arn
|
||||
assert search(
|
||||
f"Group {group_name} provides administrative access but does not have users.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_admin_policy_with_user_without_mfa(self):
|
||||
iam = client("iam")
|
||||
group_name = "test-group"
|
||||
user_name = "user-test"
|
||||
iam.create_user(UserName=user_name)
|
||||
arn = iam.create_group(GroupName=group_name)["Group"]["Arn"]
|
||||
iam.attach_group_policy(
|
||||
GroupName=group_name,
|
||||
PolicyArn="arn:aws:iam::aws:policy/AdministratorAccess",
|
||||
)
|
||||
iam.add_user_to_group(GroupName=group_name, UserName=user_name)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa import (
|
||||
iam_administrator_access_with_mfa,
|
||||
)
|
||||
|
||||
check = iam_administrator_access_with_mfa()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_id == group_name
|
||||
assert result[0].resource_arn == arn
|
||||
assert search(
|
||||
f"Group {group_name} provides administrator access to User {user_name} with MFA disabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_various_policies_with_users_with_and_without_mfa(self):
|
||||
iam = client("iam")
|
||||
group_name = "test-group"
|
||||
user_name_no_mfa = "user-no-mfa"
|
||||
user_name_mfa = "user-mfa"
|
||||
policy_name = "policy1"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
mfa_device_name = "mfa-test"
|
||||
mfa_serial_number = iam.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName=mfa_device_name
|
||||
)["VirtualMFADevice"]["SerialNumber"]
|
||||
iam.create_user(UserName=user_name_no_mfa)
|
||||
iam.create_user(UserName=user_name_mfa)
|
||||
iam.enable_mfa_device(
|
||||
UserName=user_name_mfa,
|
||||
SerialNumber=mfa_serial_number,
|
||||
AuthenticationCode1="123456",
|
||||
AuthenticationCode2="123466",
|
||||
)
|
||||
policy_arn = iam.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
arn_group = iam.create_group(GroupName=group_name)["Group"]["Arn"]
|
||||
iam.attach_group_policy(GroupName=group_name, PolicyArn=policy_arn)
|
||||
iam.attach_group_policy(
|
||||
GroupName=group_name,
|
||||
PolicyArn="arn:aws:iam::aws:policy/AdministratorAccess",
|
||||
)
|
||||
iam.add_user_to_group(GroupName=group_name, UserName=user_name_no_mfa)
|
||||
iam.add_user_to_group(GroupName=group_name, UserName=user_name_mfa)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
from providers.aws.services.iam.iam_administrator_access_with_mfa.iam_administrator_access_with_mfa import (
|
||||
iam_administrator_access_with_mfa,
|
||||
)
|
||||
|
||||
check = iam_administrator_access_with_mfa()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_id == group_name
|
||||
assert result[0].resource_arn == arn_group
|
||||
assert search(
|
||||
f"Group {group_name} provides administrator access to User {user_name_no_mfa} with MFA disabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
@@ -0,0 +1,134 @@
|
||||
import datetime
|
||||
from csv import DictReader
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_avoid_root_usage:
|
||||
@mock_iam
|
||||
def test_root_not_used(self):
|
||||
raw_credential_report = r"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated
|
||||
<root_account>,arn:aws:iam::123456789012:<root_account>,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,true,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
credential_lines = raw_credential_report.split("\n")
|
||||
csv_reader = DictReader(credential_lines, delimiter=",")
|
||||
credential_list = list(csv_reader)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage import (
|
||||
iam_avoid_root_usage,
|
||||
)
|
||||
|
||||
service_client.credential_report = credential_list
|
||||
check = iam_avoid_root_usage()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"Root user in the account wasn't accessed in the last",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == "arn:aws:iam::123456789012:<root_account>"
|
||||
|
||||
@mock_iam
|
||||
def test_root_password_used(self):
|
||||
password_last_used = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=2)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
||||
raw_credential_report = rf"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated
|
||||
<root_account>,arn:aws:iam::123456789012:<root_account>,2022-04-17T14:59:38+00:00,true,{password_last_used},not_supported,not_supported,false,true,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
credential_lines = raw_credential_report.split("\n")
|
||||
csv_reader = DictReader(credential_lines, delimiter=",")
|
||||
credential_list = list(csv_reader)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage import (
|
||||
iam_avoid_root_usage,
|
||||
)
|
||||
|
||||
service_client.credential_report = credential_list
|
||||
check = iam_avoid_root_usage()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"Root user in the account was last accessed", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == "arn:aws:iam::123456789012:<root_account>"
|
||||
|
||||
@mock_iam
|
||||
def test_root_access_key_1_used(self):
|
||||
access_key_1_last_used = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=2)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
||||
raw_credential_report = rf"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated
|
||||
<root_account>,arn:aws:iam::123456789012:<root_account>,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,true,N/A,{access_key_1_last_used},N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
credential_lines = raw_credential_report.split("\n")
|
||||
csv_reader = DictReader(credential_lines, delimiter=",")
|
||||
credential_list = list(csv_reader)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage import (
|
||||
iam_avoid_root_usage,
|
||||
)
|
||||
|
||||
service_client.credential_report = credential_list
|
||||
check = iam_avoid_root_usage()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"Root user in the account was last accessed", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == "arn:aws:iam::123456789012:<root_account>"
|
||||
|
||||
@mock_iam
|
||||
def test_root_access_key_2_used(self):
|
||||
access_key_2_last_used = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=2)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
||||
raw_credential_report = rf"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated
|
||||
<root_account>,arn:aws:iam::123456789012:<root_account>,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,true,N/A,N/A,N/A,N/A,false,N/A,{access_key_2_last_used},N/A,N/A,false,N/A,false,N/A"""
|
||||
credential_lines = raw_credential_report.split("\n")
|
||||
csv_reader = DictReader(credential_lines, delimiter=",")
|
||||
credential_list = list(csv_reader)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage import (
|
||||
iam_avoid_root_usage,
|
||||
)
|
||||
|
||||
service_client.credential_report = credential_list
|
||||
check = iam_avoid_root_usage()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"Root user in the account was last accessed", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == "arn:aws:iam::123456789012:<root_account>"
|
||||
@@ -16,7 +16,7 @@ class iam_disable_30_days_credentials(Check):
|
||||
report.resource_id = user.name
|
||||
report.resource_arn = user.arn
|
||||
report.region = iam_client.region
|
||||
if user.password_last_used and user.password_last_used != "":
|
||||
if user.password_last_used:
|
||||
time_since_insertion = (
|
||||
datetime.datetime.now()
|
||||
- datetime.datetime.strptime(
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import datetime
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_disable_30_days_credentials_test:
|
||||
@mock_iam
|
||||
def test_iam_user_logged_30_days(self):
|
||||
password_last_used = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=2)
|
||||
).strftime("%Y-%m-%d %H:%M:%S+00:00")
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import (
|
||||
iam_disable_30_days_credentials,
|
||||
)
|
||||
|
||||
service_client.users[0].password_last_used = password_last_used
|
||||
check = iam_disable_30_days_credentials()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
f"User {user} has logged into the console in the past 30 days.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_iam_user_not_logged_30_days(self):
|
||||
password_last_used = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=40)
|
||||
).strftime("%Y-%m-%d %H:%M:%S+00:00")
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import (
|
||||
iam_disable_30_days_credentials,
|
||||
)
|
||||
|
||||
service_client.users[0].password_last_used = password_last_used
|
||||
check = iam_disable_30_days_credentials()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"User {user} has not logged into the console in the past 30 days.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_iam_user_not_logged(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import (
|
||||
iam_disable_30_days_credentials,
|
||||
)
|
||||
|
||||
service_client.users[0].password_last_used = ""
|
||||
print(service_client.users)
|
||||
# raise Exception
|
||||
check = iam_disable_30_days_credentials()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
f"User {user} has not a console password or is unused.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
@@ -16,7 +16,7 @@ class iam_disable_90_days_credentials(Check):
|
||||
report.region = iam_client.region
|
||||
report.resource_id = user.name
|
||||
report.resource_arn = user.arn
|
||||
if user.password_last_used and user.password_last_used != "":
|
||||
if user.password_last_used:
|
||||
time_since_insertion = (
|
||||
datetime.datetime.now()
|
||||
- datetime.datetime.strptime(
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import datetime
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_disable_90_days_credentials_test:
|
||||
@mock_iam
|
||||
def test_iam_user_logged_90_days(self):
|
||||
password_last_used = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=2)
|
||||
).strftime("%Y-%m-%d %H:%M:%S+00:00")
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials import (
|
||||
iam_disable_90_days_credentials,
|
||||
)
|
||||
|
||||
service_client.users[0].password_last_used = password_last_used
|
||||
check = iam_disable_90_days_credentials()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
f"User {user} has logged into the console in the past 90 days.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_iam_user_not_logged_90_days(self):
|
||||
password_last_used = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=100)
|
||||
).strftime("%Y-%m-%d %H:%M:%S+00:00")
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials import (
|
||||
iam_disable_90_days_credentials,
|
||||
)
|
||||
|
||||
service_client.users[0].password_last_used = password_last_used
|
||||
check = iam_disable_90_days_credentials()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"User {user} has not logged into the console in the past 90 days.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_iam_user_not_logged(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials import (
|
||||
iam_disable_90_days_credentials,
|
||||
)
|
||||
|
||||
service_client.users[0].password_last_used = ""
|
||||
print(service_client.users)
|
||||
# raise Exception
|
||||
check = iam_disable_90_days_credentials()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
f"User {user} has not a console password or is unused.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
@@ -0,0 +1,159 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_no_root_access_key_test:
|
||||
@mock_iam
|
||||
def test_iam_root_no_access_keys(self):
|
||||
iam_client = client("iam")
|
||||
user = "test"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key import (
|
||||
iam_no_root_access_key,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
print(service_client.credential_report)
|
||||
# raise Exception
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
f"User <root_account> has not access keys.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:iam::123456789012:user/<root_account>"
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_iam_root_access_key_1(self):
|
||||
iam_client = client("iam")
|
||||
user = "test"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key import (
|
||||
iam_no_root_access_key,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "true"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
print(service_client.credential_report)
|
||||
# raise Exception
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"User <root_account> has one active access key.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:iam::123456789012:user/<root_account>"
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_iam_root_access_key_2(self):
|
||||
iam_client = client("iam")
|
||||
user = "test"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key import (
|
||||
iam_no_root_access_key,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "true"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
print(service_client.credential_report)
|
||||
# raise Exception
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"User <root_account> has one active access key.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:iam::123456789012:user/<root_account>"
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_iam_root_both_access_keys(self):
|
||||
iam_client = client("iam")
|
||||
user = "test"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key import (
|
||||
iam_no_root_access_key,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "true"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "true"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
print(service_client.credential_report)
|
||||
# raise Exception
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"User <root_account> has two active access key.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:iam::123456789012:user/<root_account>"
|
||||
)
|
||||
@@ -0,0 +1,74 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_password_policy_expires_passwords_within_90_days_or_less:
|
||||
@mock_iam
|
||||
def test_password_expiration_lower_90(self):
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM, PasswordPolicy
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_expires_passwords_within_90_days_or_less.iam_password_policy_expires_passwords_within_90_days_or_less.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_password_policy_expires_passwords_within_90_days_or_less.iam_password_policy_expires_passwords_within_90_days_or_less import (
|
||||
iam_password_policy_expires_passwords_within_90_days_or_less,
|
||||
)
|
||||
|
||||
service_client.password_policy = PasswordPolicy(
|
||||
length=10,
|
||||
symbols=True,
|
||||
numbers=True,
|
||||
uppercase=True,
|
||||
lowercase=True,
|
||||
allow_change=True,
|
||||
expiration=True,
|
||||
max_age=40,
|
||||
reuse_prevention=2,
|
||||
hard_expiry=True,
|
||||
)
|
||||
check = iam_password_policy_expires_passwords_within_90_days_or_less()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == "password_policy"
|
||||
assert search(
|
||||
"Password expiration is set lower than 90 days",
|
||||
result[0].status_extended,
|
||||
)
|
||||
|
||||
@mock_iam
|
||||
def test_password_expiration_greater_90(self):
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM, PasswordPolicy
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_password_policy_expires_passwords_within_90_days_or_less.iam_password_policy_expires_passwords_within_90_days_or_less.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_password_policy_expires_passwords_within_90_days_or_less.iam_password_policy_expires_passwords_within_90_days_or_less import (
|
||||
iam_password_policy_expires_passwords_within_90_days_or_less,
|
||||
)
|
||||
|
||||
service_client.password_policy = PasswordPolicy(
|
||||
length=10,
|
||||
symbols=True,
|
||||
numbers=True,
|
||||
uppercase=True,
|
||||
lowercase=True,
|
||||
allow_change=True,
|
||||
expiration=True,
|
||||
max_age=100,
|
||||
reuse_prevention=2,
|
||||
hard_expiry=True,
|
||||
)
|
||||
check = iam_password_policy_expires_passwords_within_90_days_or_less()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_id == "password_policy"
|
||||
assert search(
|
||||
"Password expiration is set greater than 90 days",
|
||||
result[0].status_extended,
|
||||
)
|
||||
@@ -14,6 +14,9 @@ from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
class iam_policy_allows_privilege_escalation(Check):
|
||||
def execute(self) -> Check_Report:
|
||||
# Is necessary to include the "Action:*" for
|
||||
# each service that has a policy that could
|
||||
# allow for privilege escalation
|
||||
privilege_escalation_iam_actions = {
|
||||
"iam:AttachGroupPolicy",
|
||||
"iam:SetDefaultPolicyVersion2",
|
||||
@@ -30,23 +33,31 @@ class iam_policy_allows_privilege_escalation(Check):
|
||||
"iam:SetDefaultPolicyVersion",
|
||||
"iam:UpdateAssumeRolePolicy",
|
||||
"iam:UpdateLoginProfile",
|
||||
"iam:*",
|
||||
"sts:AssumeRole",
|
||||
"sts:*",
|
||||
"ec2:RunInstances",
|
||||
"ec2:*",
|
||||
"lambda:CreateEventSourceMapping",
|
||||
"lambda:CreateFunction",
|
||||
"lambda:InvokeFunction",
|
||||
"lambda:UpdateFunctionCode",
|
||||
"lambda:*",
|
||||
"dynamodb:CreateTable",
|
||||
"dynamodb:PutItem",
|
||||
"dynamodb:*",
|
||||
"glue:CreateDevEndpoint",
|
||||
"glue:GetDevEndpoint",
|
||||
"glue:GetDevEndpoints",
|
||||
"glue:UpdateDevEndpoint",
|
||||
"glue:*",
|
||||
"cloudformation:CreateStack",
|
||||
"cloudformation:DescribeStacks",
|
||||
"cloudformation:*",
|
||||
"datapipeline:CreatePipeline",
|
||||
"datapipeline:PutPipelineDefinition",
|
||||
"datapipeline:ActivatePipeline",
|
||||
"datapipeline:*",
|
||||
}
|
||||
findings = []
|
||||
for policy in iam_client.customer_managed_policies:
|
||||
@@ -86,7 +97,11 @@ class iam_policy_allows_privilege_escalation(Check):
|
||||
# First, we need to perform a left join with ALLOWED_ACTIONS and DENIED_ACTIONS
|
||||
left_actions = allowed_actions.difference(denied_actions)
|
||||
# Then, we need to find the DENIED_NOT_ACTIONS in LEFT_ACTIONS
|
||||
privileged_actions = left_actions.intersection(denied_not_actions)
|
||||
if denied_not_actions:
|
||||
privileged_actions = left_actions.intersection(denied_not_actions)
|
||||
# If there is no Denied Not Actions
|
||||
else:
|
||||
privileged_actions = left_actions
|
||||
# Finally, check if there is a privilege escalation action within this policy
|
||||
policy_privilege_escalation_actions = privileged_actions.intersection(
|
||||
privilege_escalation_iam_actions
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
from json import dumps
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_iam_policy_allows_privilege_escalation:
|
||||
@mock_iam
|
||||
def test_iam_policy_allows_privilege_escalation_sts(self):
|
||||
iam_client = client("iam", region_name=AWS_REGION)
|
||||
policy_name = "policy1"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "sts:*", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
policy_arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation import (
|
||||
iam_policy_allows_privilege_escalation,
|
||||
)
|
||||
|
||||
check = iam_policy_allows_privilege_escalation()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Customer Managed IAM Policy {policy_arn} allows for privilege escalation using the following actions: {{'sts:*'}}"
|
||||
)
|
||||
assert result[0].resource_id == policy_name
|
||||
assert result[0].resource_arn == policy_arn
|
||||
|
||||
@mock_iam
|
||||
def test_iam_policy_not_allows_privilege_escalation(self):
|
||||
|
||||
iam_client = client("iam", region_name=AWS_REGION)
|
||||
policy_name = "policy1"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "sts:*", "Resource": "*"},
|
||||
{"Effect": "Deny", "Action": "sts:*", "Resource": "*"},
|
||||
{"Effect": "Deny", "NotAction": "sts:*", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
policy_arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation import (
|
||||
iam_policy_allows_privilege_escalation,
|
||||
)
|
||||
|
||||
check = iam_policy_allows_privilege_escalation()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Customer Managed IAM Policy {policy_arn} not allows for privilege escalation"
|
||||
)
|
||||
assert result[0].resource_id == policy_name
|
||||
assert result[0].resource_arn == policy_arn
|
||||
|
||||
@mock_iam
|
||||
def test_iam_policy_not_allows_privilege_escalation_glue_GetDevEndpoints(self):
|
||||
|
||||
iam_client = client("iam", region_name=AWS_REGION)
|
||||
policy_name = "policy1"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "lambda:*", "Resource": "*"},
|
||||
{"Effect": "Deny", "Action": "lambda:InvokeFunction", "Resource": "*"},
|
||||
{
|
||||
"Effect": "Deny",
|
||||
"NotAction": "glue:GetDevEndpoints",
|
||||
"Resource": "*",
|
||||
},
|
||||
],
|
||||
}
|
||||
policy_arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation import (
|
||||
iam_policy_allows_privilege_escalation,
|
||||
)
|
||||
|
||||
check = iam_policy_allows_privilege_escalation()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Customer Managed IAM Policy {policy_arn} not allows for privilege escalation"
|
||||
)
|
||||
assert result[0].resource_id == policy_name
|
||||
assert result[0].resource_arn == policy_arn
|
||||
|
||||
@mock_iam
|
||||
def test_iam_policy_not_allows_privilege_escalation_dynamodb_PutItem(self):
|
||||
|
||||
iam_client = client("iam", region_name=AWS_REGION)
|
||||
policy_name = "policy1"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"lambda:*",
|
||||
"iam:PassRole",
|
||||
"dynamodb:PutItem",
|
||||
"cloudformation:CreateStack",
|
||||
"cloudformation:DescribeStacks",
|
||||
"ec2:RunInstances",
|
||||
],
|
||||
"Resource": "*",
|
||||
},
|
||||
{
|
||||
"Effect": "Deny",
|
||||
"Action": ["lambda:InvokeFunction", "cloudformation:CreateStack"],
|
||||
"Resource": "*",
|
||||
},
|
||||
{"Effect": "Deny", "NotAction": "dynamodb:PutItem", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
policy_arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation import (
|
||||
iam_policy_allows_privilege_escalation,
|
||||
)
|
||||
|
||||
check = iam_policy_allows_privilege_escalation()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Customer Managed IAM Policy {policy_arn} allows for privilege escalation using the following actions: {{'dynamodb:PutItem'}}"
|
||||
)
|
||||
assert result[0].resource_id == policy_name
|
||||
assert result[0].resource_arn == policy_arn
|
||||
@@ -0,0 +1,65 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_root_hardware_mfa_enabled_test:
|
||||
@mock_iam
|
||||
def test_root_hardware_virtual_mfa_enabled(self):
|
||||
iam = client("iam")
|
||||
mfa_device_name = "mfa-test"
|
||||
iam.create_virtual_mfa_device(VirtualMFADeviceName=mfa_device_name)
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
service_client.account_summary["SummaryMap"]["AccountMFAEnabled"] = 1
|
||||
service_client.virtual_mfa_devices[0]["SerialNumber"] = "sddfaf-root-sfsfds"
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"Root account has a virtual MFA instead of a hardware MFA enabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "root"
|
||||
|
||||
@mock_iam
|
||||
def test_root_hardware_virtual_hardware_mfa_enabled(self):
|
||||
iam = client("iam")
|
||||
mfa_device_name = "mfa-test"
|
||||
iam.create_virtual_mfa_device(VirtualMFADeviceName=mfa_device_name)
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
service_client.account_summary["SummaryMap"]["AccountMFAEnabled"] = 1
|
||||
service_client.virtual_mfa_devices[0]["SerialNumber"] = ""
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"Root account has hardware MFA enabled.", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == "root"
|
||||
assert (
|
||||
result[0].resource_arn == f"arn:aws:iam::{service_client.account}:root"
|
||||
)
|
||||
@@ -0,0 +1,67 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_root_mfa_enabled_test:
|
||||
@mock_iam
|
||||
def test_root_mfa_not_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled import (
|
||||
iam_root_mfa_enabled,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["mfa_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:<root_account>:root"
|
||||
|
||||
check = iam_root_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"MFA is not enabled for root account.", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == service_client.credential_report[0]["arn"]
|
||||
|
||||
@mock_iam
|
||||
def test_root_mfa_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled import (
|
||||
iam_root_mfa_enabled,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["mfa_active"] = "true"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:<root_account>:root"
|
||||
|
||||
check = iam_root_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert search("MFA is enabled for root account.", result[0].status_extended)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == service_client.credential_report[0]["arn"]
|
||||
@@ -0,0 +1,102 @@
|
||||
import datetime
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_rotate_access_key_90_days_test:
|
||||
@mock_iam
|
||||
def test_user_no_access_keys(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_rotate_access_key_90_days.iam_rotate_access_key_90_days.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_rotate_access_key_90_days.iam_rotate_access_key_90_days import (
|
||||
iam_rotate_access_key_90_days,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["access_key_1_last_rotated"] == "N/A"
|
||||
service_client.credential_report[0]["access_key_2_last_rotated"] == "N/A"
|
||||
|
||||
check = iam_rotate_access_key_90_days()
|
||||
result = check.execute()
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == f"User {user} has not access keys."
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_user_access_key_1_not_rotated(self):
|
||||
credentials_last_rotated = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_rotate_access_key_90_days.iam_rotate_access_key_90_days.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_rotate_access_key_90_days.iam_rotate_access_key_90_days import (
|
||||
iam_rotate_access_key_90_days,
|
||||
)
|
||||
|
||||
service_client.credential_report[0][
|
||||
"access_key_1_last_rotated"
|
||||
] = credentials_last_rotated
|
||||
|
||||
check = iam_rotate_access_key_90_days()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"User {user} has not rotated access key 1 in over 90 days (100 days)."
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_user_access_key_2_not_rotated(self):
|
||||
credentials_last_rotated = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_rotate_access_key_90_days.iam_rotate_access_key_90_days.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_rotate_access_key_90_days.iam_rotate_access_key_90_days import (
|
||||
iam_rotate_access_key_90_days,
|
||||
)
|
||||
|
||||
service_client.credential_report[0][
|
||||
"access_key_2_last_rotated"
|
||||
] = credentials_last_rotated
|
||||
|
||||
check = iam_rotate_access_key_90_days()
|
||||
result = check.execute()
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"User {user} has not rotated access key 2 in over 90 days (100 days)."
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
@@ -13,17 +13,15 @@ class iam_user_hardware_mfa_enabled(Check):
|
||||
report.resource_arn = user.arn
|
||||
report.region = iam_client.region
|
||||
if user.mfa_devices:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"User {user.name} has hardware MFA enabled."
|
||||
for mfa_device in user.mfa_devices:
|
||||
if mfa_device.type == "mfa" or mfa_device.type == "sms-mfa":
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"User {user.name} has a virtual MFA instead of a hardware MFA enabled."
|
||||
findings.append(report)
|
||||
else:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"User {user.name} has hardware MFA enabled."
|
||||
)
|
||||
findings.append(report)
|
||||
break
|
||||
|
||||
findings.append(report)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_user_hardware_mfa_enabled_test:
|
||||
@mock_iam
|
||||
def test_user_no_mfa_devices(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_user_hardware_mfa_enabled.iam_user_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_user_hardware_mfa_enabled.iam_user_hardware_mfa_enabled import (
|
||||
iam_user_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
service_client.users[0].mfa_devices = []
|
||||
check = iam_user_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"User {user} has not any type of MFA enabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_user_virtual_mfa_devices(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM, MFADevice
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_user_hardware_mfa_enabled.iam_user_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_user_hardware_mfa_enabled.iam_user_hardware_mfa_enabled import (
|
||||
iam_user_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
mfa_devices = [
|
||||
MFADevice(serial_number="123454", type="mfa"),
|
||||
MFADevice(serial_number="1234547", type="sms-mfa"),
|
||||
]
|
||||
|
||||
service_client.users[0].mfa_devices = mfa_devices
|
||||
check = iam_user_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"User {user} has a virtual MFA instead of a hardware MFA enabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_user_virtual_sms_mfa_devices(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM, MFADevice
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_user_hardware_mfa_enabled.iam_user_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_user_hardware_mfa_enabled.iam_user_hardware_mfa_enabled import (
|
||||
iam_user_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
mfa_devices = [
|
||||
MFADevice(serial_number="123454", type="test-mfa"),
|
||||
MFADevice(serial_number="1234547", type="sms-mfa"),
|
||||
]
|
||||
|
||||
service_client.users[0].mfa_devices = mfa_devices
|
||||
check = iam_user_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"User {user} has a virtual MFA instead of a hardware MFA enabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
@@ -0,0 +1,98 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
class Test_iam_user_mfa_enabled_console_access_test:
|
||||
@mock_iam
|
||||
def test_user_not_password_console_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_user_mfa_enabled_console_access.iam_user_mfa_enabled_console_access.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_user_mfa_enabled_console_access.iam_user_mfa_enabled_console_access import (
|
||||
iam_user_mfa_enabled_console_access,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["password_enabled"] = "not_supported"
|
||||
|
||||
check = iam_user_mfa_enabled_console_access()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"User {user} has not Console Password enabled."
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_user_password_console_and_mfa_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_user_mfa_enabled_console_access.iam_user_mfa_enabled_console_access.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_user_mfa_enabled_console_access.iam_user_mfa_enabled_console_access import (
|
||||
iam_user_mfa_enabled_console_access,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["mfa_active"] = "true"
|
||||
|
||||
check = iam_user_mfa_enabled_console_access()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"User {user} has Console Password enabled and MFA enabled."
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_iam
|
||||
def test_user_password_console_enabled_and_mfa_not_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
arn = iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.iam.iam_user_mfa_enabled_console_access.iam_user_mfa_enabled_console_access.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
) as service_client:
|
||||
from providers.aws.services.iam.iam_user_mfa_enabled_console_access.iam_user_mfa_enabled_console_access import (
|
||||
iam_user_mfa_enabled_console_access,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["mfa_active"] = "false"
|
||||
|
||||
check = iam_user_mfa_enabled_console_access()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"User {user} has Console Password enabled but MFA disabled."
|
||||
)
|
||||
assert result[0].resource_id == user
|
||||
assert result[0].resource_arn == arn
|
||||
@@ -9,7 +9,7 @@ class Test_iam_user_no_setup_initial_access_key_test:
|
||||
@mock_iam
|
||||
def test_setup_access_key_1_fail(self):
|
||||
raw_credential_report = r"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated
|
||||
test_false_access_key_1,arn:aws:iam::106908755756:test_false_access_key_1,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,true,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
test_false_access_key_1,arn:aws:iam::123456789012:test_false_access_key_1,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,true,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
credential_lines = raw_credential_report.split("\n")
|
||||
csv_reader = DictReader(credential_lines, delimiter=",")
|
||||
credential_list = list(csv_reader)
|
||||
@@ -35,7 +35,7 @@ test_false_access_key_1,arn:aws:iam::106908755756:test_false_access_key_1,2022-0
|
||||
@mock_iam
|
||||
def test_setup_access_key_2_fail(self):
|
||||
raw_credential_report = r"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated
|
||||
test_false_access_key_2,arn:aws:iam::106908755756:test_false_access_key_2,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,false,N/A,N/A,N/A,N/A,true,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
test_false_access_key_2,arn:aws:iam::123456789012:test_false_access_key_2,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,false,N/A,N/A,N/A,N/A,true,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
credential_lines = raw_credential_report.split("\n")
|
||||
csv_reader = DictReader(credential_lines, delimiter=",")
|
||||
credential_list = list(csv_reader)
|
||||
@@ -61,7 +61,7 @@ test_false_access_key_2,arn:aws:iam::106908755756:test_false_access_key_2,2022-0
|
||||
@mock_iam
|
||||
def test_setup_access_key_pass(self):
|
||||
raw_credential_report = r"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated
|
||||
test_pass,arn:aws:iam::106908755756:test_pass,2022-02-17T14:59:38+00:00,not_supported,no_information,not_supported,not_supported,false,false,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
test_pass,arn:aws:iam::123456789012:test_pass,2022-02-17T14:59:38+00:00,not_supported,no_information,not_supported,not_supported,false,false,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A"""
|
||||
credential_lines = raw_credential_report.split("\n")
|
||||
csv_reader = DictReader(credential_lines, delimiter=",")
|
||||
credential_list = list(csv_reader)
|
||||
|
||||
Reference in New Issue
Block a user