feat(iam): improve disable credentials checks (#2909)

This commit is contained in:
Sergio Garcia
2023-10-06 11:41:04 +02:00
committed by GitHub
parent 3955450245
commit e610c2514d
43 changed files with 693 additions and 1741 deletions

View File

@@ -367,7 +367,8 @@
"iam_user_mfa_enabled_console_access",
"iam_root_hardware_mfa_enabled",
"iam_password_policy_minimum_length_14",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges"

View File

@@ -71,7 +71,8 @@
"Id": "1.12",
"Description": "Ensure credentials unused for 45 days or greater are disabled",
"Checks": [
"iam_disable_45_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
],
"Attributes": [
{

View File

@@ -71,7 +71,8 @@
"Id": "1.12",
"Description": "Ensure credentials unused for 45 days or greater are disabled",
"Checks": [
"iam_disable_45_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
],
"Attributes": [
{

View File

@@ -71,7 +71,8 @@
"Id": "1.12",
"Description": "Ensure credentials unused for 45 days or greater are disabled",
"Checks": [
"iam_disable_45_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
],
"Attributes": [
{

View File

@@ -97,7 +97,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"kms_cmk_rotation_enabled",
"awslambda_function_not_publicly_accessible",
"awslambda_function_not_publicly_accessible",

View File

@@ -306,7 +306,8 @@
}
],
"Checks": [
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_rotate_access_key_90_days"
]
},
@@ -332,7 +333,8 @@
],
"Checks": [
"iam_password_policy_expires_passwords_within_90_days_or_less",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_rotate_access_key_90_days"
]
},
@@ -485,8 +487,8 @@
}
],
"Checks": [
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{

View File

@@ -36,7 +36,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_hardware_mfa_enabled",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
"s3_bucket_server_access_logging_enabled",
@@ -64,7 +65,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",

View File

@@ -29,7 +29,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"securityhub_enabled"
]
},
@@ -103,7 +104,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -156,7 +158,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -173,7 +176,8 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -197,7 +201,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -259,7 +264,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -301,7 +307,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",

View File

@@ -591,7 +591,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{

View File

@@ -44,7 +44,8 @@
"iam_support_role_created",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"kms_cmk_rotation_enabled",
"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes",
"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled",

View File

@@ -92,7 +92,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -177,7 +178,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -323,7 +325,8 @@
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_rotate_access_key_90_days",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},

View File

@@ -177,7 +177,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -286,7 +287,8 @@
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -343,7 +345,8 @@
"iam_password_policy_uppercase",
"iam_password_policy_reuse_24",
"iam_rotate_access_key_90_days",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{

View File

@@ -866,7 +866,8 @@
}
],
"Checks": [
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -1042,7 +1043,8 @@
}
],
"Checks": [
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -1250,7 +1252,8 @@
}
],
"Checks": [
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{

View File

@@ -167,7 +167,8 @@
"iam_customer_unattached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_expired_server_certificates_stored",
"iam_disable_30_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_no_root_access_key",
"iam_no_custom_policy_permissive_role_assumption",
"iam_password_policy_expires_passwords_within_90_days_or_less",
@@ -673,7 +674,8 @@
"iam_policy_allows_privilege_escalation",
"iam_policy_no_full_access_to_cloudtrail",
"iam_policy_no_full_access_to_kms",
"iam_disable_30_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_no_root_access_key",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
@@ -720,7 +722,8 @@
"Checks": [
"guardduty_is_enabled",
"config_recorder_all_regions_enabled",
"iam_disable_30_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_password_policy_expires_passwords_within_90_days_or_less",
"iam_password_policy_lowercase",
"iam_password_policy_minimum_length_14",

View File

@@ -29,7 +29,8 @@
"iam_no_root_access_key",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -70,7 +71,8 @@
"iam_no_root_access_key",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -133,7 +135,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -152,7 +155,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -574,7 +578,8 @@
"Checks": [
"iam_password_policy_reuse_24",
"iam_password_policy_expires_passwords_within_90_days_or_less",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -596,7 +601,8 @@
"iam_password_policy_uppercase",
"iam_password_policy_reuse_24",
"iam_password_policy_expires_passwords_within_90_days_or_less",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -613,7 +619,8 @@
"Checks": [
"iam_password_policy_reuse_24",
"iam_password_policy_expires_passwords_within_90_days_or_less",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{

View File

@@ -20,7 +20,8 @@
"guardduty_is_enabled",
"iam_password_policy_reuse_24",
"iam_rotate_access_key_90_days",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"securityhub_enabled"
]
},
@@ -37,7 +38,8 @@
}
],
"Checks": [
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -107,7 +109,8 @@
"iam_root_mfa_enabled",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"rds_instance_integration_cloudwatch_logs",
"redshift_cluster_audit_logging",
"s3_bucket_server_access_logging_enabled",
@@ -131,7 +134,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_url_public",
"rds_snapshots_public_access",
"redshift_cluster_public_access",
@@ -225,7 +229,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_url_public",
"rds_instance_no_public_access",
"rds_snapshots_public_access",

View File

@@ -28,7 +28,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -47,7 +48,8 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -65,7 +67,8 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -83,7 +86,8 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -101,7 +105,8 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -118,7 +123,8 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -166,7 +172,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -225,7 +232,8 @@
}
],
"Checks": [
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -260,7 +268,8 @@
}
],
"Checks": [
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{
@@ -284,7 +293,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -364,7 +374,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -394,7 +405,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -424,7 +436,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -454,7 +467,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -484,7 +498,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -514,7 +529,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -544,7 +560,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -574,7 +591,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -603,7 +621,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -633,7 +652,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -652,7 +672,8 @@
],
"Checks": [
"secretsmanager_automatic_rotation_enabled",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_rotate_access_key_90_days",
@@ -693,7 +714,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -723,7 +745,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -753,7 +776,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -780,7 +804,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -817,7 +842,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -870,7 +896,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -916,7 +943,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -946,7 +974,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -976,7 +1005,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -1102,7 +1132,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -1145,7 +1176,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -1497,7 +1529,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -2673,7 +2706,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -2753,7 +2787,8 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"kms_cmk_rotation_enabled",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
@@ -3010,7 +3045,8 @@
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"kms_cmk_rotation_enabled",
"s3_bucket_default_encryption",
"s3_bucket_secure_transport_policy",
@@ -3979,7 +4015,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
"rds_instance_no_public_access",
@@ -5457,7 +5494,8 @@
"iam_rotate_access_key_90_days",
"iam_user_mfa_enabled_console_access",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},

View File

@@ -574,7 +574,8 @@
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"secretsmanager_automatic_rotation_enabled"
]
},
@@ -630,7 +631,8 @@
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{

View File

@@ -162,7 +162,8 @@
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",
"iam_disable_90_days_credentials",
"iam_user_accesskey_unused",
"iam_user_console_access_unused",
"iam_password_policy_minimum_length_14",
"iam_password_policy_lowercase",
"iam_password_policy_number",

View File

@@ -49,7 +49,8 @@
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_inline_policy_no_administrative_privileges",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
]
},
{

View File

@@ -1,5 +1,11 @@
# AWS Configuration
aws:
# AWS IAM Configuration
# aws.iam_user_accesskey_unused --> CIS recommends 45 days
max_unused_access_keys_days: 45
# aws.iam_user_console_access_unused --> CIS recommends 45 days
max_console_access_days: 45
# AWS EC2 Configuration
# aws.ec2_elastic_ip_shodan
shodan_api_key: null

View File

@@ -1,104 +0,0 @@
import datetime
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
maximum_expiration_days = 30
class iam_disable_30_days_credentials(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for user in iam_client.users:
report = Check_Report_AWS(self.metadata())
report.resource_id = user.name
report.resource_arn = user.arn
report.resource_tags = user.tags
report.region = iam_client.region
if user.password_last_used:
time_since_insertion = (
datetime.datetime.now()
- datetime.datetime.strptime(
str(user.password_last_used), "%Y-%m-%d %H:%M:%S+00:00"
)
)
if time_since_insertion.days > maximum_expiration_days:
report.status = "FAIL"
report.status_extended = f"User {user.name} has not logged in to the console in the past {maximum_expiration_days} days."
else:
report.status = "PASS"
report.status_extended = f"User {user.name} has logged in to the console in the past {maximum_expiration_days} days."
else:
report.status = "PASS"
report.status_extended = (
f"User {user.name} does not have a console password or is unused."
)
# Append report
findings.append(report)
for user in iam_client.credential_report:
if (
user["access_key_1_active"] != "true"
and user["access_key_2_active"] != "true"
):
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_id = user["user"]
report.resource_arn = user["arn"]
report.status = "PASS"
report.status_extended = (
f"User {user['user']} does not have access keys."
)
findings.append(report)
else:
old_access_keys = False
if user["access_key_1_active"] == "true":
if user["access_key_1_last_used_date"] != "N/A":
access_key_1_last_used_date = (
datetime.datetime.now()
- datetime.datetime.strptime(
user["access_key_1_last_used_date"],
"%Y-%m-%dT%H:%M:%S+00:00",
)
)
if access_key_1_last_used_date.days > maximum_expiration_days:
old_access_keys = True
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_id = user["user"] + "/AccessKey1"
report.resource_arn = user["arn"]
report.status = "FAIL"
report.status_extended = f"User {user['user']} has not used access key 1 in the last {maximum_expiration_days} days ({access_key_1_last_used_date.days} days)."
findings.append(report)
if user["access_key_2_active"] == "true":
if user["access_key_2_last_used_date"] != "N/A":
access_key_2_last_used_date = (
datetime.datetime.now()
- datetime.datetime.strptime(
user["access_key_2_last_used_date"],
"%Y-%m-%dT%H:%M:%S+00:00",
)
)
if access_key_2_last_used_date.days > maximum_expiration_days:
old_access_keys = True
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_id = user["user"] + "/AccessKey2"
report.resource_arn = user["arn"]
report.status = "FAIL"
report.status_extended = f"User {user['user']} has not used access key 2 in the last {maximum_expiration_days} days ({access_key_2_last_used_date.days} days)."
findings.append(report)
if not old_access_keys:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_id = user["user"]
report.resource_arn = user["arn"]
report.status = "PASS"
report.status_extended = f"User {user['user']} does not have unused access keys for {maximum_expiration_days} days."
findings.append(report)
return findings

View File

@@ -1,32 +0,0 @@
{
"Categories": [],
"CheckID": "iam_disable_90_days_credentials",
"CheckTitle": "Ensure credentials unused for 90 days or greater are disabled",
"CheckType": [
"Software and Configuration Checks"
],
"DependsOn": [],
"Description": "Ensure credentials unused for 90 days or greater are disabled",
"Notes": "",
"Provider": "aws",
"RelatedTo": [],
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Find the credentials that they were using and ensure that they are no longer operational. Ideally; you delete credentials if they are no longer needed. You can always recreate them at a later date if the need arises. At the very least; you should change the password or deactivate the access keys so that the former users no longer have access.",
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html"
}
},
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceType": "AwsIamUser",
"Risk": "AWS IAM users can access AWS resources using different types of credentials (passwords or access keys). It is recommended that all credentials that have been unused in 90 or greater days be removed or deactivated.",
"ServiceName": "iam",
"Severity": "medium",
"SubServiceName": ""
}

View File

@@ -1,104 +0,0 @@
import datetime
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
maximum_expiration_days = 90
class iam_disable_90_days_credentials(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for user in iam_client.users:
report = Check_Report_AWS(self.metadata())
report.resource_id = user.name
report.resource_arn = user.arn
report.resource_tags = user.tags
report.region = iam_client.region
if user.password_last_used:
time_since_insertion = (
datetime.datetime.now()
- datetime.datetime.strptime(
str(user.password_last_used), "%Y-%m-%d %H:%M:%S+00:00"
)
)
if time_since_insertion.days > maximum_expiration_days:
report.status = "FAIL"
report.status_extended = f"User {user.name} has not logged in to the console in the past {maximum_expiration_days} days."
else:
report.status = "PASS"
report.status_extended = f"User {user.name} has logged in to the console in the past {maximum_expiration_days} days."
else:
report.status = "PASS"
report.status_extended = (
f"User {user.name} does not have a console password or is unused."
)
# Append report
findings.append(report)
for user in iam_client.credential_report:
if (
user["access_key_1_active"] != "true"
and user["access_key_2_active"] != "true"
):
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_id = user["user"]
report.resource_arn = user["arn"]
report.status = "PASS"
report.status_extended = (
f"User {user['user']} does not have access keys."
)
findings.append(report)
else:
old_access_keys = False
if user["access_key_1_active"] == "true":
if user["access_key_1_last_used_date"] != "N/A":
access_key_1_last_used_date = (
datetime.datetime.now()
- datetime.datetime.strptime(
user["access_key_1_last_used_date"],
"%Y-%m-%dT%H:%M:%S+00:00",
)
)
if access_key_1_last_used_date.days > maximum_expiration_days:
old_access_keys = True
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_id = user["user"] + "/AccessKey1"
report.resource_arn = user["arn"]
report.status = "FAIL"
report.status_extended = f"User {user['user']} has not used access key 1 in the last {maximum_expiration_days} days ({access_key_1_last_used_date.days} days)."
findings.append(report)
if user["access_key_2_active"] == "true":
if user["access_key_2_last_used_date"] != "N/A":
access_key_2_last_used_date = (
datetime.datetime.now()
- datetime.datetime.strptime(
user["access_key_2_last_used_date"],
"%Y-%m-%dT%H:%M:%S+00:00",
)
)
if access_key_2_last_used_date.days > maximum_expiration_days:
old_access_keys = True
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_id = user["user"] + "/AccessKey2"
report.resource_arn = user["arn"]
report.status = "FAIL"
report.status_extended = f"User {user['user']} has not used access key 2 in the last {maximum_expiration_days} days ({access_key_2_last_used_date.days} days)."
findings.append(report)
if not old_access_keys:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_id = user["user"]
report.resource_arn = user["arn"]
report.status = "PASS"
report.status_extended = f"User {user['user']} does not have unused access keys for {maximum_expiration_days} days."
findings.append(report)
return findings

View File

@@ -1,7 +1,7 @@
{
"Provider": "aws",
"CheckID": "iam_disable_30_days_credentials",
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
"CheckID": "iam_user_accesskey_unused",
"CheckTitle": "Ensure User Access Keys unused are disabled",
"CheckType": [
"Software and Configuration Checks"
],
@@ -10,7 +10,7 @@
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"ResourceType": "AwsIamUser",
"Description": "Ensure credentials unused for 30 days or greater are disabled",
"Description": "Ensure User Access Keys unused are disabled",
"Risk": "To increase the security of your AWS account; remove IAM user credentials (that is; passwords and access keys) that are not needed. For example; when users leave your organization or no longer need AWS access.",
"RelatedUrl": "",
"Remediation": {

View File

@@ -3,40 +3,13 @@ import datetime
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
maximum_expiration_days = 45
class iam_disable_45_days_credentials(Check):
class iam_user_accesskey_unused(Check):
def execute(self) -> Check_Report_AWS:
maximum_expiration_days = iam_client.audit_config.get(
"max_unused_access_keys_days", 45
)
findings = []
for user in iam_client.users:
report = Check_Report_AWS(self.metadata())
report.resource_id = user.name
report.resource_arn = user.arn
report.resource_tags = user.tags
report.region = iam_client.region
if user.password_last_used:
time_since_insertion = (
datetime.datetime.now()
- datetime.datetime.strptime(
str(user.password_last_used), "%Y-%m-%d %H:%M:%S+00:00"
)
)
if time_since_insertion.days > maximum_expiration_days:
report.status = "FAIL"
report.status_extended = f"User {user.name} has not logged in to the console in the past 45 days."
else:
report.status = "PASS"
report.status_extended = f"User {user.name} has logged in to the console in the past 45 days."
else:
report.status = "PASS"
report.status_extended = (
f"User {user.name} does not have a console password or is unused."
)
# Append report
findings.append(report)
for user in iam_client.credential_report:
if (
user["access_key_1_active"] != "true"

View File

@@ -1,7 +1,7 @@
{
"Provider": "aws",
"CheckID": "iam_disable_45_days_credentials",
"CheckTitle": "Ensure credentials unused for 45 days or greater are disabled",
"CheckID": "iam_user_console_access_unused",
"CheckTitle": "Ensure unused user console access are disabled",
"CheckType": [
"Software and Configuration Checks"
],
@@ -10,7 +10,7 @@
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"ResourceType": "AwsIamUser",
"Description": "Ensure credentials unused for 45 days or greater are disabled",
"Description": "Ensure unused user console access are disabled",
"Risk": "To increase the security of your AWS account; remove IAM user credentials (that is; passwords and access keys) that are not needed. For example; when users leave your organization or no longer need AWS access.",
"RelatedUrl": "",
"Remediation": {

View File

@@ -0,0 +1,40 @@
import datetime
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
class iam_user_console_access_unused(Check):
def execute(self) -> Check_Report_AWS:
maximum_expiration_days = iam_client.audit_config.get(
"max_console_access_days", 45
)
findings = []
for user in iam_client.users:
report = Check_Report_AWS(self.metadata())
report.resource_id = user.name
report.resource_arn = user.arn
report.resource_tags = user.tags
report.region = iam_client.region
if user.password_last_used:
time_since_insertion = (
datetime.datetime.now()
- datetime.datetime.strptime(
str(user.password_last_used), "%Y-%m-%d %H:%M:%S+00:00"
)
)
if time_since_insertion.days > maximum_expiration_days:
report.status = "FAIL"
report.status_extended = f"User {user.name} has not logged in to the console in the past {maximum_expiration_days} days ({time_since_insertion.days} days)."
else:
report.status = "PASS"
report.status_extended = f"User {user.name} has logged in to the console in the past {maximum_expiration_days} days ({time_since_insertion.days} days)."
else:
report.status = "PASS"
report.status_extended = (
f"User {user.name} does not have a console password or is unused."
)
# Append report
findings.append(report)
return findings

View File

@@ -295,8 +295,8 @@ class Test_Check:
"metadata_path": f"{os.path.dirname(os.path.realpath(__file__))}/fixtures/metadata.json",
},
"expected": {
"CheckID": "iam_disable_30_days_credentials",
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
"CheckID": "iam_user_accesskey_unused",
"CheckTitle": "Ensure Access Keys unused are disabled",
"ServiceName": "iam",
"Severity": "low",
},
@@ -398,22 +398,22 @@ class Test_Check:
{
"input": {
"checks_to_run": {
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials",
"iam_user_console_access_unused",
"iam_user_accesskey_unused",
},
"excluded_services": {"ec2"},
"provider": "aws",
},
"expected": {
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials",
"iam_user_console_access_unused",
"iam_user_accesskey_unused",
},
},
{
"input": {
"checks_to_run": {
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials",
"iam_user_console_access_unused",
"iam_user_accesskey_unused",
},
"excluded_services": {"iam"},
"provider": "aws",

View File

@@ -9,8 +9,8 @@
},
"iam": {
"checks": [
"iam_disable_30_days_credentials",
"iam_disable_90_days_credentials"
"iam_user_accesskey_unused",
"iam_user_console_access_unused"
],
"description": "Identity and Access Management"
}

View File

@@ -3,8 +3,8 @@
"cat1",
"cat2"
],
"CheckID": "iam_disable_30_days_credentials",
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
"CheckID": "iam_user_accesskey_unused",
"CheckTitle": "Ensure Access Keys unused are disabled",
"CheckType": [
"Software and Configuration Checks"
],
@@ -25,7 +25,7 @@
"othercheck1",
"othercheck2"
],
"Description": "Ensure credentials unused for 30 days or greater are disabled",
"Description": "Ensure Access Keys unused are disabled",
"Notes": "additional information",
"Provider": "aws",
"RelatedTo": [

View File

@@ -3,8 +3,8 @@
"cat1",
"cat2"
],
"CheckID": "iam_disable_30_days_credentials",
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
"CheckID": "iam_user_accesskey_unused",
"CheckTitle": "Ensure Access Keys unused are disabled",
"CheckType": [
"Software and Configuration Checks"
],
@@ -25,7 +25,7 @@
"othercheck1",
"othercheck2"
],
"Description": "Ensure credentials unused for 30 days or greater are disabled",
"Description": "Ensure Access Keys unused are disabled",
"Notes": "additional information",
"Provider": "aws",
"RelatedTo": [

View File

@@ -27,8 +27,8 @@ from prowler.lib.outputs.file_descriptors import fill_file_descriptors
from prowler.lib.outputs.json import (
fill_json_asff,
fill_json_ocsf,
generate_json_asff_status,
generate_json_asff_resource_tags,
generate_json_asff_status,
generate_json_ocsf_severity_id,
generate_json_ocsf_status,
generate_json_ocsf_status_id,
@@ -989,8 +989,8 @@ class Test_Outputs:
expected = Check_Output_JSON_OCSF(
finding=Finding(
title="Ensure credentials unused for 30 days or greater are disabled",
desc="Ensure credentials unused for 30 days or greater are disabled",
title="Ensure Access Keys unused are disabled",
desc="Ensure Access Keys unused are disabled",
supporting_data={
"Risk": "Risk associated.",
"Notes": "additional information",
@@ -1007,7 +1007,7 @@ class Test_Outputs:
),
types=["Software and Configuration Checks"],
src_url="https://serviceofficialsiteorpageforthissubject",
uid="prowler-aws-iam_disable_30_days_credentials-123456789012-eu-west-1-test-resource",
uid="prowler-aws-iam_user_accesskey_unused-123456789012-eu-west-1-test-resource",
related_events=[
"othercheck1",
"othercheck2",
@@ -1050,8 +1050,8 @@ class Test_Outputs:
version=prowler_version,
vendor_name="Prowler/ProwlerPro",
feature=Feature(
name="iam_disable_30_days_credentials",
uid="iam_disable_30_days_credentials",
name="iam_user_accesskey_unused",
uid="iam_user_accesskey_unused",
version=prowler_version,
),
),
@@ -1117,8 +1117,8 @@ class Test_Outputs:
expected = Check_Output_JSON_OCSF(
finding=Finding(
title="Ensure credentials unused for 30 days or greater are disabled",
desc="Ensure credentials unused for 30 days or greater are disabled",
title="Ensure Access Keys unused are disabled",
desc="Ensure Access Keys unused are disabled",
supporting_data={
"Risk": "Risk associated.",
"Notes": "additional information",
@@ -1135,7 +1135,7 @@ class Test_Outputs:
),
types=["Software and Configuration Checks"],
src_url="https://serviceofficialsiteorpageforthissubject",
uid="prowler-aws-iam_disable_30_days_credentials-123456789012-eu-west-1-test-resource",
uid="prowler-aws-iam_user_accesskey_unused-123456789012-eu-west-1-test-resource",
related_events=[
"othercheck1",
"othercheck2",
@@ -1178,8 +1178,8 @@ class Test_Outputs:
version=prowler_version,
vendor_name="Prowler/ProwlerPro",
feature=Feature(
name="iam_disable_30_days_credentials",
uid="iam_disable_30_days_credentials",
name="iam_user_accesskey_unused",
uid="iam_user_accesskey_unused",
version=prowler_version,
),
),
@@ -1333,10 +1333,10 @@ class Test_Outputs:
output_options = mock.MagicMock()
output_options.bulk_checks_metadata = {}
output_options.bulk_checks_metadata[
"iam_disable_30_days_credentials"
"iam_user_accesskey_unused"
] = mock.MagicMock()
output_options.bulk_checks_metadata[
"iam_disable_30_days_credentials"
"iam_user_accesskey_unused"
].Compliance = bulk_check_metadata
assert get_check_compliance(finding, "aws", output_options) == {

View File

@@ -3,8 +3,8 @@
"cat1",
"cat2"
],
"CheckID": "iam_disable_30_days_credentials",
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
"CheckID": "iam_user_accesskey_unused",
"CheckTitle": "Ensure Access Keys unused are disabled",
"CheckType": [
"Software and Configuration Checks"
],
@@ -25,7 +25,7 @@
"othercheck1",
"othercheck2"
],
"Description": "Ensure credentials unused for 30 days or greater are disabled",
"Description": "Ensure Access Keys unused are disabled",
"Notes": "additional information",
"Provider": "aws",
"RelatedTo": [

View File

@@ -122,7 +122,7 @@ class Test_SecurityHub:
AWS_REGION_1: [
{
"SchemaVersion": "2018-10-08",
"Id": f"prowler-iam_disable_30_days_credentials-{AWS_ACCOUNT_ID}-{AWS_REGION_1}-ee26b0dd4",
"Id": f"prowler-iam_user_accesskey_unused-{AWS_ACCOUNT_ID}-{AWS_REGION_1}-ee26b0dd4",
"ProductArn": f"arn:aws:securityhub:{AWS_REGION_1}::product/prowler/prowler",
"RecordState": "ACTIVE",
"ProductFields": {
@@ -130,14 +130,14 @@ class Test_SecurityHub:
"ProviderVersion": "3.9.0",
"ProwlerResourceName": "test",
},
"GeneratorId": "prowler-iam_disable_30_days_credentials",
"GeneratorId": "prowler-iam_user_accesskey_unused",
"AwsAccountId": f"{AWS_ACCOUNT_ID}",
"Types": ["Software and Configuration Checks"],
"FirstObservedAt": timestamp_utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
"UpdatedAt": timestamp_utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
"CreatedAt": timestamp_utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
"Severity": {"Label": "LOW"},
"Title": "Ensure credentials unused for 30 days or greater are disabled",
"Title": "Ensure Access Keys unused are disabled",
"Description": "test",
"Resources": [
{

View File

@@ -1,449 +0,0 @@
import datetime
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"
class Test_iam_disable_30_days_credentials_test:
# Mocked Audit Info
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,
region_name=AWS_REGION,
),
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=AWS_REGION,
credentials=None,
assumed_role_info=None,
audited_regions=None,
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
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.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 len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} has logged in to the console in the past 30 days."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_iam_user_not_logged_30_days(self):
password_last_used = (
datetime.datetime.now() - datetime.timedelta(days=60)
).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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.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 len(result) == 2
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"User {user} has not logged in to the console in the past 30 days."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.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 = ""
# raise Exception
check = iam_disable_30_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import (
iam_disable_30_days_credentials,
)
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_disable_30_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_access_key_1_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import (
iam_disable_30_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
check = iam_disable_30_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 1 in the last 30 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey1"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_access_key_2_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import (
iam_disable_30_days_credentials,
)
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_30_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 2 in the last 30 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey2"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_both_access_keys_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import (
iam_disable_30_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_30_days_credentials()
result = check.execute()
assert len(result) == 3
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 1 in the last 30 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey1"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
assert result[2].status == "FAIL"
assert (
result[2].status_extended
== f"User {user} has not used access key 2 in the last 30 days (100 days)."
)
assert result[2].resource_id == user + "/AccessKey2"
assert result[2].resource_arn == arn
assert result[2].region == AWS_REGION
@mock_iam
def test_user_both_access_keys_used(self):
credentials_last_rotated = (
datetime.datetime.now() - datetime.timedelta(days=10)
).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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import (
iam_disable_30_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_30_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have unused access keys for 30 days."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION

View File

@@ -1,448 +0,0 @@
import datetime
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"
class Test_iam_disable_45_days_credentials_test:
# Mocked Audit Info
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,
region_name=AWS_REGION,
),
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=AWS_REGION,
credentials=None,
assumed_role_info=None,
audited_regions=None,
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
@mock_iam
def test_iam_user_logged_45_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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
service_client.users[0].password_last_used = password_last_used
check = iam_disable_45_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} has logged in to the console in the past 45 days."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_iam_user_not_logged_45_days(self):
password_last_used = (
datetime.datetime.now() - datetime.timedelta(days=60)
).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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
service_client.users[0].password_last_used = password_last_used
check = iam_disable_45_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"User {user} has not logged in to the console in the past 45 days."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
service_client.users[0].password_last_used = ""
# raise Exception
check = iam_disable_45_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
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_disable_45_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_access_key_1_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
check = iam_disable_45_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 1 in the last 45 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey1"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_access_key_2_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_45_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 2 in the last 45 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey2"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_both_access_keys_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_45_days_credentials()
result = check.execute()
assert len(result) == 3
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 1 in the last 45 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey1"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
assert result[2].status == "FAIL"
assert (
result[2].status_extended
== f"User {user} has not used access key 2 in the last 45 days (100 days)."
)
assert result[2].resource_id == user + "/AccessKey2"
assert result[2].resource_arn == arn
assert result[2].region == AWS_REGION
@mock_iam
def test_user_both_access_keys_used(self):
credentials_last_rotated = (
datetime.datetime.now() - datetime.timedelta(days=10)
).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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_45_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have unused access keys for 45 days."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION

View File

@@ -1,446 +0,0 @@
import datetime
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"
class Test_iam_disable_90_days_credentials_test:
# Mocked Audit Info
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,
region_name=AWS_REGION,
),
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=AWS_REGION,
credentials=None,
assumed_role_info=None,
audited_regions=None,
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
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.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 (
result[0].status_extended
== f"User {user} has logged in to the console in the past 90 days."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.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 len(result) == 2
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"User {user} has not logged in to the console in the past 90 days."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.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 = ""
# raise Exception
check = iam_disable_90_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials import (
iam_disable_90_days_credentials,
)
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_disable_90_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have access keys."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_access_key_1_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials import (
iam_disable_90_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
check = iam_disable_90_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 1 in the last 90 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey1"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_access_key_2_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials import (
iam_disable_90_days_credentials,
)
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_90_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 2 in the last 90 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey2"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_both_access_keys_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_90_days_credentials.iam_disable_90_days_credentials import (
iam_disable_90_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_90_days_credentials()
result = check.execute()
assert len(result) == 3
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 1 in the last 90 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey1"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
assert result[2].status == "FAIL"
assert (
result[2].status_extended
== f"User {user} has not used access key 2 in the last 90 days (100 days)."
)
assert result[2].resource_id == user + "/AccessKey2"
assert result[2].resource_arn == arn
assert result[2].region == AWS_REGION
@mock_iam
def test_user_both_access_keys_used(self):
credentials_last_rotated = (
datetime.datetime.now() - datetime.timedelta(days=10)
).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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import (
iam_disable_45_days_credentials,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_disable_45_days_credentials()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "PASS"
assert (
result[1].status_extended
== f"User {user} does not have unused access keys for 45 days."
)
assert result[1].resource_id == user
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION

View File

@@ -0,0 +1,274 @@
import datetime
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"
class Test_iam_user_accesskey_unused_test:
# Mocked Audit Info
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,
region_name=AWS_REGION,
),
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=AWS_REGION,
credentials=None,
assumed_role_info=None,
audited_regions=None,
organizations_metadata=None,
audit_resources=None,
mfa_enabled=False,
audit_metadata=Audit_Metadata(
services_scanned=0,
expected_checks=[],
completed_checks=0,
audit_progress=0,
),
audit_config={"max_unused_access_keys_days": 45},
)
return audit_info
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused import (
iam_user_accesskey_unused,
)
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_user_accesskey_unused()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have access keys."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
@mock_iam
def test_user_access_key_1_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused import (
iam_user_accesskey_unused,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
check = iam_user_accesskey_unused()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"User {user} has not used access key 1 in the last 45 days (100 days)."
)
assert result[0].resource_id == user + "/AccessKey1"
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
@mock_iam
def test_user_access_key_2_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused import (
iam_user_accesskey_unused,
)
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_user_accesskey_unused()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"User {user} has not used access key 2 in the last 45 days (100 days)."
)
assert result[0].resource_id == user + "/AccessKey2"
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
@mock_iam
def test_user_both_access_keys_not_used(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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused import (
iam_user_accesskey_unused,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_user_accesskey_unused()
result = check.execute()
assert len(result) == 2
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"User {user} has not used access key 1 in the last 45 days (100 days)."
)
assert result[0].resource_id == user + "/AccessKey1"
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
assert result[1].status == "FAIL"
assert (
result[1].status_extended
== f"User {user} has not used access key 2 in the last 45 days (100 days)."
)
assert result[1].resource_id == user + "/AccessKey2"
assert result[1].resource_arn == arn
assert result[1].region == AWS_REGION
@mock_iam
def test_user_both_access_keys_used(self):
credentials_last_rotated = (
datetime.datetime.now() - datetime.timedelta(days=10)
).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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_user_accesskey_unused.iam_user_accesskey_unused import (
iam_user_accesskey_unused,
)
service_client.credential_report[0]["access_key_1_active"] = "true"
service_client.credential_report[0][
"access_key_1_last_used_date"
] = credentials_last_rotated
service_client.credential_report[0]["access_key_2_active"] = "true"
service_client.credential_report[0][
"access_key_2_last_used_date"
] = credentials_last_rotated
check = iam_user_accesskey_unused()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have unused access keys for 45 days."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION

View File

@@ -0,0 +1,158 @@
import datetime
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"
class Test_iam_user_console_access_unused_test:
# Mocked Audit Info
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,
region_name=AWS_REGION,
),
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=AWS_REGION,
credentials=None,
assumed_role_info=None,
audited_regions=None,
organizations_metadata=None,
audit_resources=None,
mfa_enabled=False,
audit_metadata=Audit_Metadata(
services_scanned=0,
expected_checks=[],
completed_checks=0,
audit_progress=0,
),
audit_config={"max_console_access_days": 45},
)
return audit_info
@mock_iam
def test_iam_user_logged_45_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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_user_console_access_unused.iam_user_console_access_unused.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_user_console_access_unused.iam_user_console_access_unused import (
iam_user_console_access_unused,
)
service_client.users[0].password_last_used = password_last_used
check = iam_user_console_access_unused()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} has logged in to the console in the past 45 days (2 days)."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
@mock_iam
def test_iam_user_not_logged_45_days(self):
password_last_used = (
datetime.datetime.now() - datetime.timedelta(days=60)
).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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_user_console_access_unused.iam_user_console_access_unused.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_user_console_access_unused.iam_user_console_access_unused import (
iam_user_console_access_unused,
)
service_client.users[0].password_last_used = password_last_used
check = iam_user_console_access_unused()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"User {user} has not logged in to the console in the past 45 days (60 days)."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION
@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 prowler.providers.aws.services.iam.iam_service import IAM
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.iam.iam_user_console_access_unused.iam_user_console_access_unused.iam_client",
new=IAM(audit_info),
) as service_client:
from prowler.providers.aws.services.iam.iam_user_console_access_unused.iam_user_console_access_unused import (
iam_user_console_access_unused,
)
service_client.users[0].password_last_used = ""
# raise Exception
check = iam_user_console_access_unused()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"User {user} does not have a console password or is unused."
)
assert result[0].resource_id == user
assert result[0].resource_arn == arn
assert result[0].region == AWS_REGION