From 75571e4266f5f79a613c8f5592eb96e2bd922a9e Mon Sep 17 00:00:00 2001 From: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Date: Mon, 30 Jan 2023 16:47:24 +0100 Subject: [PATCH] fix(iam_avoid_root_usage): correct date logic (#1801) --- .../iam_avoid_root_usage.py | 2 +- .../iam_avoid_root_usage_test.py | 129 ++++++++++++++++-- 2 files changed, 118 insertions(+), 13 deletions(-) diff --git a/prowler/providers/aws/services/iam/iam_avoid_root_usage/iam_avoid_root_usage.py b/prowler/providers/aws/services/iam/iam_avoid_root_usage/iam_avoid_root_usage.py index f5e93457..59f1ecbe 100644 --- a/prowler/providers/aws/services/iam/iam_avoid_root_usage/iam_avoid_root_usage.py +++ b/prowler/providers/aws/services/iam/iam_avoid_root_usage/iam_avoid_root_usage.py @@ -46,7 +46,7 @@ class iam_avoid_root_usage(Check): "%Y-%m-%dT%H:%M:%S+00:00", ) ).days - if days_since_accessed > maximum_access_days: + if maximum_access_days >= days_since_accessed: report.status = "FAIL" report.status_extended = f"Root user in the account was last accessed {days_since_accessed} days ago." else: diff --git a/tests/providers/aws/services/iam/iam_avoid_root_usage/iam_avoid_root_usage_test.py b/tests/providers/aws/services/iam/iam_avoid_root_usage/iam_avoid_root_usage_test.py index d4caae56..ad9f788a 100644 --- a/tests/providers/aws/services/iam/iam_avoid_root_usage/iam_avoid_root_usage_test.py +++ b/tests/providers/aws/services/iam/iam_avoid_root_usage/iam_avoid_root_usage_test.py @@ -40,10 +40,10 @@ class Test_iam_avoid_root_usage: assert result[0].resource_arn == "arn:aws:iam::123456789012:" @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") + def test_root_password_recently_used(self): + password_last_used = (datetime.datetime.now()).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 ,arn:aws:iam::123456789012:,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") @@ -74,10 +74,10 @@ class Test_iam_avoid_root_usage: assert result[0].resource_arn == "arn:aws:iam::123456789012:" @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") + def test_root_access_key_1_recently_used(self): + access_key_1_last_used = (datetime.datetime.now()).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 ,arn:aws:iam::123456789012:,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") @@ -108,10 +108,10 @@ class Test_iam_avoid_root_usage: assert result[0].resource_arn == "arn:aws:iam::123456789012:" @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") + def test_root_access_key_2_recently_used(self): + access_key_2_last_used = (datetime.datetime.now()).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 ,arn:aws:iam::123456789012:,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") @@ -140,3 +140,108 @@ class Test_iam_avoid_root_usage: ) assert result[0].resource_id == "" assert result[0].resource_arn == "arn:aws:iam::123456789012:" + + @mock_iam + def test_root_password_used(self): + password_last_used = ( + datetime.datetime.now() - datetime.timedelta(days=100) + ).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 +,arn:aws:iam::123456789012:,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 prowler.providers.aws.lib.audit_info.audit_info import current_audit_info + from prowler.providers.aws.services.iam.iam_service import IAM + + current_audit_info.audited_partition = "aws" + + with mock.patch( + "prowler.providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage.iam_client", + new=IAM(current_audit_info), + ) as service_client: + from prowler.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 1 days", + result[0].status_extended, + ) + assert result[0].resource_id == "" + assert result[0].resource_arn == "arn:aws:iam::123456789012:" + + @mock_iam + def test_root_access_key_1_used(self): + access_key_1_last_used = ( + datetime.datetime.now() - datetime.timedelta(days=100) + ).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 +,arn:aws:iam::123456789012:,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 prowler.providers.aws.lib.audit_info.audit_info import current_audit_info + from prowler.providers.aws.services.iam.iam_service import IAM + + current_audit_info.audited_partition = "aws" + + with mock.patch( + "prowler.providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage.iam_client", + new=IAM(current_audit_info), + ) as service_client: + from prowler.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 1 days", + result[0].status_extended, + ) + assert result[0].resource_id == "" + assert result[0].resource_arn == "arn:aws:iam::123456789012:" + + @mock_iam + def test_root_access_key_2_used(self): + access_key_2_last_used = ( + datetime.datetime.now() - datetime.timedelta(days=100) + ).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 +,arn:aws:iam::123456789012:,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 prowler.providers.aws.lib.audit_info.audit_info import current_audit_info + from prowler.providers.aws.services.iam.iam_service import IAM + + current_audit_info.audited_partition = "aws" + + with mock.patch( + "prowler.providers.aws.services.iam.iam_avoid_root_usage.iam_avoid_root_usage.iam_client", + new=IAM(current_audit_info), + ) as service_client: + from prowler.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 1 days", + result[0].status_extended, + ) + assert result[0].resource_id == "" + assert result[0].resource_arn == "arn:aws:iam::123456789012:"