mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
feat(iam): improve disable credentials checks (#2909)
This commit is contained in:
@@ -367,7 +367,8 @@
|
|||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"iam_root_hardware_mfa_enabled",
|
"iam_root_hardware_mfa_enabled",
|
||||||
"iam_password_policy_minimum_length_14",
|
"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_aws_attached_policy_no_administrative_privileges",
|
||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges"
|
"iam_inline_policy_no_administrative_privileges"
|
||||||
|
|||||||
@@ -71,7 +71,8 @@
|
|||||||
"Id": "1.12",
|
"Id": "1.12",
|
||||||
"Description": "Ensure credentials unused for 45 days or greater are disabled",
|
"Description": "Ensure credentials unused for 45 days or greater are disabled",
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_45_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
],
|
],
|
||||||
"Attributes": [
|
"Attributes": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -71,7 +71,8 @@
|
|||||||
"Id": "1.12",
|
"Id": "1.12",
|
||||||
"Description": "Ensure credentials unused for 45 days or greater are disabled",
|
"Description": "Ensure credentials unused for 45 days or greater are disabled",
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_45_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
],
|
],
|
||||||
"Attributes": [
|
"Attributes": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -71,7 +71,8 @@
|
|||||||
"Id": "1.12",
|
"Id": "1.12",
|
||||||
"Description": "Ensure credentials unused for 45 days or greater are disabled",
|
"Description": "Ensure credentials unused for 45 days or greater are disabled",
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_45_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
],
|
],
|
||||||
"Attributes": [
|
"Attributes": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -97,7 +97,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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",
|
"kms_cmk_rotation_enabled",
|
||||||
"awslambda_function_not_publicly_accessible",
|
"awslambda_function_not_publicly_accessible",
|
||||||
"awslambda_function_not_publicly_accessible",
|
"awslambda_function_not_publicly_accessible",
|
||||||
|
|||||||
@@ -306,7 +306,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused",
|
||||||
"iam_rotate_access_key_90_days"
|
"iam_rotate_access_key_90_days"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -332,7 +333,8 @@
|
|||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_password_policy_expires_passwords_within_90_days_or_less",
|
"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"
|
"iam_rotate_access_key_90_days"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -485,8 +487,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_30_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"iam_user_hardware_mfa_enabled",
|
"iam_user_hardware_mfa_enabled",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused",
|
||||||
"rds_instance_integration_cloudwatch_logs",
|
"rds_instance_integration_cloudwatch_logs",
|
||||||
"redshift_cluster_audit_logging",
|
"redshift_cluster_audit_logging",
|
||||||
"s3_bucket_server_access_logging_enabled",
|
"s3_bucket_server_access_logging_enabled",
|
||||||
@@ -64,7 +65,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"securityhub_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -103,7 +104,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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": [
|
"Checks": [
|
||||||
"iam_password_policy_minimum_length_14",
|
"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_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -259,7 +264,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
|
|||||||
@@ -591,7 +591,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,7 +44,8 @@
|
|||||||
"iam_support_role_created",
|
"iam_support_role_created",
|
||||||
"iam_rotate_access_key_90_days",
|
"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",
|
"kms_cmk_rotation_enabled",
|
||||||
"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes",
|
"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes",
|
||||||
"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled",
|
"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled",
|
||||||
|
|||||||
@@ -92,7 +92,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -177,7 +178,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -323,7 +325,8 @@
|
|||||||
"iam_password_policy_symbol",
|
"iam_password_policy_symbol",
|
||||||
"iam_password_policy_uppercase",
|
"iam_password_policy_uppercase",
|
||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused",
|
||||||
"secretsmanager_automatic_rotation_enabled"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -177,7 +177,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused",
|
||||||
"secretsmanager_automatic_rotation_enabled"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -343,7 +345,8 @@
|
|||||||
"iam_password_policy_uppercase",
|
"iam_password_policy_uppercase",
|
||||||
"iam_password_policy_reuse_24",
|
"iam_password_policy_reuse_24",
|
||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -866,7 +866,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1042,7 +1043,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1250,7 +1252,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -167,7 +167,8 @@
|
|||||||
"iam_customer_unattached_policy_no_administrative_privileges",
|
"iam_customer_unattached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_expired_server_certificates_stored",
|
"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_root_access_key",
|
||||||
"iam_no_custom_policy_permissive_role_assumption",
|
"iam_no_custom_policy_permissive_role_assumption",
|
||||||
"iam_password_policy_expires_passwords_within_90_days_or_less",
|
"iam_password_policy_expires_passwords_within_90_days_or_less",
|
||||||
@@ -673,7 +674,8 @@
|
|||||||
"iam_policy_allows_privilege_escalation",
|
"iam_policy_allows_privilege_escalation",
|
||||||
"iam_policy_no_full_access_to_cloudtrail",
|
"iam_policy_no_full_access_to_cloudtrail",
|
||||||
"iam_policy_no_full_access_to_kms",
|
"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_no_root_access_key",
|
||||||
"iam_root_hardware_mfa_enabled",
|
"iam_root_hardware_mfa_enabled",
|
||||||
"iam_root_mfa_enabled",
|
"iam_root_mfa_enabled",
|
||||||
@@ -720,7 +722,8 @@
|
|||||||
"Checks": [
|
"Checks": [
|
||||||
"guardduty_is_enabled",
|
"guardduty_is_enabled",
|
||||||
"config_recorder_all_regions_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_expires_passwords_within_90_days_or_less",
|
||||||
"iam_password_policy_lowercase",
|
"iam_password_policy_lowercase",
|
||||||
"iam_password_policy_minimum_length_14",
|
"iam_password_policy_minimum_length_14",
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -70,7 +71,8 @@
|
|||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -133,7 +135,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -574,7 +578,8 @@
|
|||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_password_policy_reuse_24",
|
"iam_password_policy_reuse_24",
|
||||||
"iam_password_policy_expires_passwords_within_90_days_or_less",
|
"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_uppercase",
|
||||||
"iam_password_policy_reuse_24",
|
"iam_password_policy_reuse_24",
|
||||||
"iam_password_policy_expires_passwords_within_90_days_or_less",
|
"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": [
|
"Checks": [
|
||||||
"iam_password_policy_reuse_24",
|
"iam_password_policy_reuse_24",
|
||||||
"iam_password_policy_expires_passwords_within_90_days_or_less",
|
"iam_password_policy_expires_passwords_within_90_days_or_less",
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
"guardduty_is_enabled",
|
"guardduty_is_enabled",
|
||||||
"iam_password_policy_reuse_24",
|
"iam_password_policy_reuse_24",
|
||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused",
|
||||||
"securityhub_enabled"
|
"securityhub_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -37,7 +38,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -107,7 +109,8 @@
|
|||||||
"iam_root_mfa_enabled",
|
"iam_root_mfa_enabled",
|
||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_rotate_access_key_90_days",
|
"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",
|
"rds_instance_integration_cloudwatch_logs",
|
||||||
"redshift_cluster_audit_logging",
|
"redshift_cluster_audit_logging",
|
||||||
"s3_bucket_server_access_logging_enabled",
|
"s3_bucket_server_access_logging_enabled",
|
||||||
@@ -131,7 +134,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_snapshots_public_access",
|
"rds_snapshots_public_access",
|
||||||
"redshift_cluster_public_access",
|
"redshift_cluster_public_access",
|
||||||
@@ -225,7 +229,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
"rds_snapshots_public_access",
|
"rds_snapshots_public_access",
|
||||||
|
|||||||
@@ -28,7 +28,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -47,7 +48,8 @@
|
|||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_password_policy_minimum_length_14",
|
"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": [
|
"Checks": [
|
||||||
"iam_password_policy_minimum_length_14",
|
"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": [
|
"Checks": [
|
||||||
"iam_password_policy_minimum_length_14",
|
"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": [
|
"Checks": [
|
||||||
"iam_password_policy_minimum_length_14",
|
"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": [
|
"Checks": [
|
||||||
"iam_password_policy_minimum_length_14",
|
"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_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -225,7 +232,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -260,7 +268,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Checks": [
|
"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_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_policy_attached_only_to_group_or_roles",
|
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -364,7 +374,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -394,7 +405,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -424,7 +436,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -454,7 +467,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -484,7 +498,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -514,7 +529,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -544,7 +560,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -574,7 +591,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -603,7 +621,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -633,7 +652,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -652,7 +672,8 @@
|
|||||||
],
|
],
|
||||||
"Checks": [
|
"Checks": [
|
||||||
"secretsmanager_automatic_rotation_enabled",
|
"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_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
@@ -693,7 +714,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -723,7 +745,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -753,7 +776,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -780,7 +804,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -817,7 +842,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -870,7 +896,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -916,7 +943,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -946,7 +974,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -976,7 +1005,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -1102,7 +1132,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -1145,7 +1176,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -1497,7 +1529,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -2673,7 +2706,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -2753,7 +2787,8 @@
|
|||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_rotate_access_key_90_days",
|
"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",
|
"kms_cmk_rotation_enabled",
|
||||||
"s3_bucket_default_encryption",
|
"s3_bucket_default_encryption",
|
||||||
"s3_bucket_secure_transport_policy",
|
"s3_bucket_secure_transport_policy",
|
||||||
@@ -3010,7 +3045,8 @@
|
|||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_rotate_access_key_90_days",
|
"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",
|
"kms_cmk_rotation_enabled",
|
||||||
"s3_bucket_default_encryption",
|
"s3_bucket_default_encryption",
|
||||||
"s3_bucket_secure_transport_policy",
|
"s3_bucket_secure_transport_policy",
|
||||||
@@ -3979,7 +4015,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"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_not_publicly_accessible",
|
||||||
"awslambda_function_url_public",
|
"awslambda_function_url_public",
|
||||||
"rds_instance_no_public_access",
|
"rds_instance_no_public_access",
|
||||||
@@ -5457,7 +5494,8 @@
|
|||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_user_mfa_enabled_console_access",
|
"iam_user_mfa_enabled_console_access",
|
||||||
"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"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -574,7 +574,8 @@
|
|||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_rotate_access_key_90_days",
|
"iam_rotate_access_key_90_days",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused",
|
||||||
"secretsmanager_automatic_rotation_enabled"
|
"secretsmanager_automatic_rotation_enabled"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -630,7 +631,8 @@
|
|||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_no_root_access_key",
|
"iam_no_root_access_key",
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -162,7 +162,8 @@
|
|||||||
"iam_root_hardware_mfa_enabled",
|
"iam_root_hardware_mfa_enabled",
|
||||||
"iam_root_mfa_enabled",
|
"iam_root_mfa_enabled",
|
||||||
"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",
|
||||||
"iam_password_policy_minimum_length_14",
|
"iam_password_policy_minimum_length_14",
|
||||||
"iam_password_policy_lowercase",
|
"iam_password_policy_lowercase",
|
||||||
"iam_password_policy_number",
|
"iam_password_policy_number",
|
||||||
|
|||||||
@@ -49,7 +49,8 @@
|
|||||||
"iam_aws_attached_policy_no_administrative_privileges",
|
"iam_aws_attached_policy_no_administrative_privileges",
|
||||||
"iam_customer_attached_policy_no_administrative_privileges",
|
"iam_customer_attached_policy_no_administrative_privileges",
|
||||||
"iam_inline_policy_no_administrative_privileges",
|
"iam_inline_policy_no_administrative_privileges",
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_accesskey_unused",
|
||||||
|
"iam_user_console_access_unused"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# AWS Configuration
|
# AWS Configuration
|
||||||
aws:
|
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 Configuration
|
||||||
# aws.ec2_elastic_ip_shodan
|
# aws.ec2_elastic_ip_shodan
|
||||||
shodan_api_key: null
|
shodan_api_key: null
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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": ""
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Provider": "aws",
|
"Provider": "aws",
|
||||||
"CheckID": "iam_disable_30_days_credentials",
|
"CheckID": "iam_user_accesskey_unused",
|
||||||
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
|
"CheckTitle": "Ensure User Access Keys unused are disabled",
|
||||||
"CheckType": [
|
"CheckType": [
|
||||||
"Software and Configuration Checks"
|
"Software and Configuration Checks"
|
||||||
],
|
],
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||||
"Severity": "medium",
|
"Severity": "medium",
|
||||||
"ResourceType": "AwsIamUser",
|
"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.",
|
"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": "",
|
"RelatedUrl": "",
|
||||||
"Remediation": {
|
"Remediation": {
|
||||||
@@ -3,40 +3,13 @@ import datetime
|
|||||||
from prowler.lib.check.models import Check, Check_Report_AWS
|
from prowler.lib.check.models import Check, Check_Report_AWS
|
||||||
from prowler.providers.aws.services.iam.iam_client import iam_client
|
from prowler.providers.aws.services.iam.iam_client import iam_client
|
||||||
|
|
||||||
maximum_expiration_days = 45
|
|
||||||
|
|
||||||
|
class iam_user_accesskey_unused(Check):
|
||||||
class iam_disable_45_days_credentials(Check):
|
|
||||||
def execute(self) -> Check_Report_AWS:
|
def execute(self) -> Check_Report_AWS:
|
||||||
|
maximum_expiration_days = iam_client.audit_config.get(
|
||||||
|
"max_unused_access_keys_days", 45
|
||||||
|
)
|
||||||
findings = []
|
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:
|
for user in iam_client.credential_report:
|
||||||
if (
|
if (
|
||||||
user["access_key_1_active"] != "true"
|
user["access_key_1_active"] != "true"
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Provider": "aws",
|
"Provider": "aws",
|
||||||
"CheckID": "iam_disable_45_days_credentials",
|
"CheckID": "iam_user_console_access_unused",
|
||||||
"CheckTitle": "Ensure credentials unused for 45 days or greater are disabled",
|
"CheckTitle": "Ensure unused user console access are disabled",
|
||||||
"CheckType": [
|
"CheckType": [
|
||||||
"Software and Configuration Checks"
|
"Software and Configuration Checks"
|
||||||
],
|
],
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||||
"Severity": "medium",
|
"Severity": "medium",
|
||||||
"ResourceType": "AwsIamUser",
|
"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.",
|
"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": "",
|
"RelatedUrl": "",
|
||||||
"Remediation": {
|
"Remediation": {
|
||||||
@@ -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
|
||||||
@@ -295,8 +295,8 @@ class Test_Check:
|
|||||||
"metadata_path": f"{os.path.dirname(os.path.realpath(__file__))}/fixtures/metadata.json",
|
"metadata_path": f"{os.path.dirname(os.path.realpath(__file__))}/fixtures/metadata.json",
|
||||||
},
|
},
|
||||||
"expected": {
|
"expected": {
|
||||||
"CheckID": "iam_disable_30_days_credentials",
|
"CheckID": "iam_user_accesskey_unused",
|
||||||
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
|
"CheckTitle": "Ensure Access Keys unused are disabled",
|
||||||
"ServiceName": "iam",
|
"ServiceName": "iam",
|
||||||
"Severity": "low",
|
"Severity": "low",
|
||||||
},
|
},
|
||||||
@@ -398,22 +398,22 @@ class Test_Check:
|
|||||||
{
|
{
|
||||||
"input": {
|
"input": {
|
||||||
"checks_to_run": {
|
"checks_to_run": {
|
||||||
"iam_disable_30_days_credentials",
|
"iam_user_console_access_unused",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
},
|
},
|
||||||
"excluded_services": {"ec2"},
|
"excluded_services": {"ec2"},
|
||||||
"provider": "aws",
|
"provider": "aws",
|
||||||
},
|
},
|
||||||
"expected": {
|
"expected": {
|
||||||
"iam_disable_30_days_credentials",
|
"iam_user_console_access_unused",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": {
|
"input": {
|
||||||
"checks_to_run": {
|
"checks_to_run": {
|
||||||
"iam_disable_30_days_credentials",
|
"iam_user_console_access_unused",
|
||||||
"iam_disable_90_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
},
|
},
|
||||||
"excluded_services": {"iam"},
|
"excluded_services": {"iam"},
|
||||||
"provider": "aws",
|
"provider": "aws",
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
},
|
},
|
||||||
"iam": {
|
"iam": {
|
||||||
"checks": [
|
"checks": [
|
||||||
"iam_disable_30_days_credentials",
|
"iam_user_accesskey_unused",
|
||||||
"iam_disable_90_days_credentials"
|
"iam_user_console_access_unused"
|
||||||
],
|
],
|
||||||
"description": "Identity and Access Management"
|
"description": "Identity and Access Management"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
"cat1",
|
"cat1",
|
||||||
"cat2"
|
"cat2"
|
||||||
],
|
],
|
||||||
"CheckID": "iam_disable_30_days_credentials",
|
"CheckID": "iam_user_accesskey_unused",
|
||||||
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
|
"CheckTitle": "Ensure Access Keys unused are disabled",
|
||||||
"CheckType": [
|
"CheckType": [
|
||||||
"Software and Configuration Checks"
|
"Software and Configuration Checks"
|
||||||
],
|
],
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"othercheck1",
|
"othercheck1",
|
||||||
"othercheck2"
|
"othercheck2"
|
||||||
],
|
],
|
||||||
"Description": "Ensure credentials unused for 30 days or greater are disabled",
|
"Description": "Ensure Access Keys unused are disabled",
|
||||||
"Notes": "additional information",
|
"Notes": "additional information",
|
||||||
"Provider": "aws",
|
"Provider": "aws",
|
||||||
"RelatedTo": [
|
"RelatedTo": [
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
"cat1",
|
"cat1",
|
||||||
"cat2"
|
"cat2"
|
||||||
],
|
],
|
||||||
"CheckID": "iam_disable_30_days_credentials",
|
"CheckID": "iam_user_accesskey_unused",
|
||||||
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
|
"CheckTitle": "Ensure Access Keys unused are disabled",
|
||||||
"CheckType": [
|
"CheckType": [
|
||||||
"Software and Configuration Checks"
|
"Software and Configuration Checks"
|
||||||
],
|
],
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"othercheck1",
|
"othercheck1",
|
||||||
"othercheck2"
|
"othercheck2"
|
||||||
],
|
],
|
||||||
"Description": "Ensure credentials unused for 30 days or greater are disabled",
|
"Description": "Ensure Access Keys unused are disabled",
|
||||||
"Notes": "additional information",
|
"Notes": "additional information",
|
||||||
"Provider": "aws",
|
"Provider": "aws",
|
||||||
"RelatedTo": [
|
"RelatedTo": [
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ from prowler.lib.outputs.file_descriptors import fill_file_descriptors
|
|||||||
from prowler.lib.outputs.json import (
|
from prowler.lib.outputs.json import (
|
||||||
fill_json_asff,
|
fill_json_asff,
|
||||||
fill_json_ocsf,
|
fill_json_ocsf,
|
||||||
generate_json_asff_status,
|
|
||||||
generate_json_asff_resource_tags,
|
generate_json_asff_resource_tags,
|
||||||
|
generate_json_asff_status,
|
||||||
generate_json_ocsf_severity_id,
|
generate_json_ocsf_severity_id,
|
||||||
generate_json_ocsf_status,
|
generate_json_ocsf_status,
|
||||||
generate_json_ocsf_status_id,
|
generate_json_ocsf_status_id,
|
||||||
@@ -989,8 +989,8 @@ class Test_Outputs:
|
|||||||
|
|
||||||
expected = Check_Output_JSON_OCSF(
|
expected = Check_Output_JSON_OCSF(
|
||||||
finding=Finding(
|
finding=Finding(
|
||||||
title="Ensure credentials unused for 30 days or greater are disabled",
|
title="Ensure Access Keys unused are disabled",
|
||||||
desc="Ensure credentials unused for 30 days or greater are disabled",
|
desc="Ensure Access Keys unused are disabled",
|
||||||
supporting_data={
|
supporting_data={
|
||||||
"Risk": "Risk associated.",
|
"Risk": "Risk associated.",
|
||||||
"Notes": "additional information",
|
"Notes": "additional information",
|
||||||
@@ -1007,7 +1007,7 @@ class Test_Outputs:
|
|||||||
),
|
),
|
||||||
types=["Software and Configuration Checks"],
|
types=["Software and Configuration Checks"],
|
||||||
src_url="https://serviceofficialsiteorpageforthissubject",
|
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=[
|
related_events=[
|
||||||
"othercheck1",
|
"othercheck1",
|
||||||
"othercheck2",
|
"othercheck2",
|
||||||
@@ -1050,8 +1050,8 @@ class Test_Outputs:
|
|||||||
version=prowler_version,
|
version=prowler_version,
|
||||||
vendor_name="Prowler/ProwlerPro",
|
vendor_name="Prowler/ProwlerPro",
|
||||||
feature=Feature(
|
feature=Feature(
|
||||||
name="iam_disable_30_days_credentials",
|
name="iam_user_accesskey_unused",
|
||||||
uid="iam_disable_30_days_credentials",
|
uid="iam_user_accesskey_unused",
|
||||||
version=prowler_version,
|
version=prowler_version,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1117,8 +1117,8 @@ class Test_Outputs:
|
|||||||
|
|
||||||
expected = Check_Output_JSON_OCSF(
|
expected = Check_Output_JSON_OCSF(
|
||||||
finding=Finding(
|
finding=Finding(
|
||||||
title="Ensure credentials unused for 30 days or greater are disabled",
|
title="Ensure Access Keys unused are disabled",
|
||||||
desc="Ensure credentials unused for 30 days or greater are disabled",
|
desc="Ensure Access Keys unused are disabled",
|
||||||
supporting_data={
|
supporting_data={
|
||||||
"Risk": "Risk associated.",
|
"Risk": "Risk associated.",
|
||||||
"Notes": "additional information",
|
"Notes": "additional information",
|
||||||
@@ -1135,7 +1135,7 @@ class Test_Outputs:
|
|||||||
),
|
),
|
||||||
types=["Software and Configuration Checks"],
|
types=["Software and Configuration Checks"],
|
||||||
src_url="https://serviceofficialsiteorpageforthissubject",
|
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=[
|
related_events=[
|
||||||
"othercheck1",
|
"othercheck1",
|
||||||
"othercheck2",
|
"othercheck2",
|
||||||
@@ -1178,8 +1178,8 @@ class Test_Outputs:
|
|||||||
version=prowler_version,
|
version=prowler_version,
|
||||||
vendor_name="Prowler/ProwlerPro",
|
vendor_name="Prowler/ProwlerPro",
|
||||||
feature=Feature(
|
feature=Feature(
|
||||||
name="iam_disable_30_days_credentials",
|
name="iam_user_accesskey_unused",
|
||||||
uid="iam_disable_30_days_credentials",
|
uid="iam_user_accesskey_unused",
|
||||||
version=prowler_version,
|
version=prowler_version,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1333,10 +1333,10 @@ class Test_Outputs:
|
|||||||
output_options = mock.MagicMock()
|
output_options = mock.MagicMock()
|
||||||
output_options.bulk_checks_metadata = {}
|
output_options.bulk_checks_metadata = {}
|
||||||
output_options.bulk_checks_metadata[
|
output_options.bulk_checks_metadata[
|
||||||
"iam_disable_30_days_credentials"
|
"iam_user_accesskey_unused"
|
||||||
] = mock.MagicMock()
|
] = mock.MagicMock()
|
||||||
output_options.bulk_checks_metadata[
|
output_options.bulk_checks_metadata[
|
||||||
"iam_disable_30_days_credentials"
|
"iam_user_accesskey_unused"
|
||||||
].Compliance = bulk_check_metadata
|
].Compliance = bulk_check_metadata
|
||||||
|
|
||||||
assert get_check_compliance(finding, "aws", output_options) == {
|
assert get_check_compliance(finding, "aws", output_options) == {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
"cat1",
|
"cat1",
|
||||||
"cat2"
|
"cat2"
|
||||||
],
|
],
|
||||||
"CheckID": "iam_disable_30_days_credentials",
|
"CheckID": "iam_user_accesskey_unused",
|
||||||
"CheckTitle": "Ensure credentials unused for 30 days or greater are disabled",
|
"CheckTitle": "Ensure Access Keys unused are disabled",
|
||||||
"CheckType": [
|
"CheckType": [
|
||||||
"Software and Configuration Checks"
|
"Software and Configuration Checks"
|
||||||
],
|
],
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"othercheck1",
|
"othercheck1",
|
||||||
"othercheck2"
|
"othercheck2"
|
||||||
],
|
],
|
||||||
"Description": "Ensure credentials unused for 30 days or greater are disabled",
|
"Description": "Ensure Access Keys unused are disabled",
|
||||||
"Notes": "additional information",
|
"Notes": "additional information",
|
||||||
"Provider": "aws",
|
"Provider": "aws",
|
||||||
"RelatedTo": [
|
"RelatedTo": [
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class Test_SecurityHub:
|
|||||||
AWS_REGION_1: [
|
AWS_REGION_1: [
|
||||||
{
|
{
|
||||||
"SchemaVersion": "2018-10-08",
|
"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",
|
"ProductArn": f"arn:aws:securityhub:{AWS_REGION_1}::product/prowler/prowler",
|
||||||
"RecordState": "ACTIVE",
|
"RecordState": "ACTIVE",
|
||||||
"ProductFields": {
|
"ProductFields": {
|
||||||
@@ -130,14 +130,14 @@ class Test_SecurityHub:
|
|||||||
"ProviderVersion": "3.9.0",
|
"ProviderVersion": "3.9.0",
|
||||||
"ProwlerResourceName": "test",
|
"ProwlerResourceName": "test",
|
||||||
},
|
},
|
||||||
"GeneratorId": "prowler-iam_disable_30_days_credentials",
|
"GeneratorId": "prowler-iam_user_accesskey_unused",
|
||||||
"AwsAccountId": f"{AWS_ACCOUNT_ID}",
|
"AwsAccountId": f"{AWS_ACCOUNT_ID}",
|
||||||
"Types": ["Software and Configuration Checks"],
|
"Types": ["Software and Configuration Checks"],
|
||||||
"FirstObservedAt": timestamp_utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
"FirstObservedAt": timestamp_utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||||
"UpdatedAt": 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"),
|
"CreatedAt": timestamp_utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||||
"Severity": {"Label": "LOW"},
|
"Severity": {"Label": "LOW"},
|
||||||
"Title": "Ensure credentials unused for 30 days or greater are disabled",
|
"Title": "Ensure Access Keys unused are disabled",
|
||||||
"Description": "test",
|
"Description": "test",
|
||||||
"Resources": [
|
"Resources": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user