fix(iam_policy_no_administrative_privileges): check attached policies and AWS-Managed (#2200)

Co-authored-by: Pepe Fagoaga <pepe@verica.io>
This commit is contained in:
Sergio Garcia
2023-04-19 14:34:53 +02:00
committed by GitHub
parent 10d744704a
commit 7a00f79a56
40 changed files with 1025 additions and 361 deletions

View File

@@ -362,14 +362,14 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_rotate_access_key_90_days",
"iam_no_root_access_key",
"iam_user_mfa_enabled_console_access",
"iam_root_hardware_mfa_enabled",
"iam_password_policy_minimum_length_14",
"iam_disable_90_days_credentials",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{

View File

@@ -155,7 +155,8 @@
"Id": "1.16",
"Description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached",
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
],
"Attributes": [
{

View File

@@ -155,7 +155,8 @@
"Id": "1.16",
"Description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached",
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
],
"Attributes": [
{

View File

@@ -88,7 +88,8 @@
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_no_custom_policy_permissive_role_assumption",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -181,7 +182,8 @@
"Checks": [
"elbv2_ssl_listeners",
"iam_no_custom_policy_permissive_role_assumption",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key"
]
},

View File

@@ -103,7 +103,8 @@
"awslambda_function_url_public",
"awslambda_function_url_cors_policy",
"iam_policy_allows_privilege_escalation",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -129,7 +130,8 @@
"Checks": [
"iam_policy_allows_privilege_escalation",
"iam_no_custom_policy_permissive_role_assumption",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -202,7 +204,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -1065,7 +1068,8 @@
],
"Checks": [
"iam_policy_allows_privilege_escalation",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_custom_policy_permissive_role_assumption",
"iam_policy_attached_only_to_group_or_roles",
"iam_role_cross_service_confused_deputy_prevention"

View File

@@ -26,9 +26,9 @@
"opensearch_service_domains_cloudwatch_logging_enabled",
"guardduty_is_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -58,9 +58,9 @@
"ec2_instance_public_ip",
"ec2_instance_imdsv2_enabled",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_not_publicly_accessible",

View File

@@ -20,7 +20,8 @@
"guardduty_is_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -91,9 +92,9 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -144,9 +145,9 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
@@ -188,9 +189,9 @@
"ec2_instance_public_ip",
"ec2_instance_imdsv2_enabled",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_not_publicly_accessible",
@@ -249,9 +250,9 @@
],
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
]
@@ -269,8 +270,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key"
]
},
@@ -290,7 +291,8 @@
"ec2_instance_public_ip",
"ec2_instance_imdsv2_enabled",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_not_publicly_accessible",
@@ -974,7 +976,8 @@
],
"Checks": [
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{

View File

@@ -418,9 +418,9 @@
],
"Checks": [
"ec2_instance_profile_attached",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key"
]
},
@@ -519,8 +519,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -536,8 +536,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -553,8 +553,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key"
@@ -579,8 +579,8 @@
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_policy_no_administrative_privileges",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_rotate_access_key_90_days",
@@ -755,9 +755,9 @@
"Checks": [
"cloudtrail_multi_region_enabled",
"cloudtrail_cloudwatch_logging_enabled",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{

View File

@@ -35,7 +35,8 @@
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",

View File

@@ -82,9 +82,9 @@
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -166,9 +166,9 @@
"iam_password_policy_number",
"iam_password_policy_symbol",
"iam_password_policy_uppercase",
"iam_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",

View File

@@ -45,7 +45,8 @@
"elb_ssl_listeners",
"emr_cluster_master_nodes_no_public_ip",
"opensearch_service_domains_encryption_at_rest_enabled",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
@@ -114,7 +115,8 @@
"Checks": [
"ec2_ebs_public_snapshot",
"ec2_instance_public_ip",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
@@ -169,7 +171,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
]
@@ -201,7 +204,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -255,7 +259,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -271,7 +276,8 @@
],
"Checks": [
"iam_password_policy_reuse_24",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_disable_90_days_credentials",
@@ -512,7 +518,8 @@
"ec2_ebs_public_snapshot",
"ec2_instance_public_ip",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_user_mfa_enabled_console_access",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",

View File

@@ -21,7 +21,8 @@
"ec2_instance_public_ip",
"eks_endpoints_not_publicly_accessible",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -60,7 +61,8 @@
"ec2_instance_public_ip",
"eks_endpoints_not_publicly_accessible",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -125,7 +127,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
]
@@ -142,7 +145,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
]
@@ -159,7 +163,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key"
]
},
@@ -175,7 +180,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key"
]
},
@@ -449,7 +455,8 @@
"ec2_ebs_public_snapshot",
"ec2_instance_managed_by_ssm",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"awslambda_function_url_public",
"rds_snapshots_public_access",
@@ -821,7 +828,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{

View File

@@ -101,7 +101,8 @@
"cloudtrail_cloudwatch_logging_enabled",
"guardduty_is_enabled",
"iam_password_policy_reuse_24",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
@@ -125,7 +126,8 @@
],
"Checks": [
"ec2_ebs_public_snapshot",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_url_public",
@@ -180,7 +182,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -215,7 +218,8 @@
"ec2_instance_public_ip",
"ec2_instance_imdsv2_enabled",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_url_public",
@@ -846,7 +850,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{

View File

@@ -19,7 +19,8 @@
"Checks": [
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -160,7 +161,8 @@
"ec2_instance_imdsv2_enabled",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_not_publicly_accessible",
@@ -238,7 +240,8 @@
],
"Checks": [
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -274,9 +277,9 @@
"ec2_instance_public_ip",
"ec2_instance_imdsv2_enabled",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_disable_90_days_credentials",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",
@@ -348,7 +351,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -376,7 +380,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -404,7 +409,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -432,7 +438,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -460,7 +467,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -488,7 +496,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -516,7 +525,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -544,7 +554,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -571,7 +582,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -599,7 +611,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -632,7 +645,8 @@
"iam_no_root_access_key",
"iam_root_mfa_enabled",
"iam_root_hardware_mfa_enabled",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_password_policy_minimum_length_14",
"ec2_instance_imdsv2_enabled"
@@ -655,7 +669,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -683,7 +698,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -711,7 +727,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -741,7 +758,8 @@
"ec2_instance_imdsv2_enabled",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_not_publicly_accessible",
@@ -771,7 +789,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -822,7 +841,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -866,7 +886,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -894,7 +915,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -922,7 +944,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -1046,7 +1069,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -1070,8 +1094,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -1091,7 +1115,8 @@
"ec2_instance_imdsv2_enabled",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_not_publicly_accessible",
@@ -1119,8 +1144,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key"
]
},
@@ -1138,7 +1163,8 @@
],
"Checks": [
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{
@@ -1177,8 +1203,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key"
]
},
@@ -1432,7 +1458,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -2606,9 +2633,9 @@
"ec2_instance_profile_attached",
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
@@ -2686,7 +2713,8 @@
"ec2_instance_profile_attached",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -2941,7 +2969,8 @@
"ec2_ebs_default_encryption",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -3912,7 +3941,8 @@
"ec2_instance_imdsv2_enabled",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials",
"awslambda_function_not_publicly_accessible",
@@ -5383,7 +5413,8 @@
"ec2_instance_imdsv2_enabled",
"iam_password_policy_minimum_length_14",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_no_root_access_key",
@@ -5426,7 +5457,8 @@
"ec2_ebs_public_snapshot",
"ec2_instance_public_ip",
"emr_cluster_master_nodes_no_public_ip",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"awslambda_function_not_publicly_accessible",
"awslambda_function_url_public",

View File

@@ -569,7 +569,8 @@
],
"Checks": [
"iam_password_policy_reuse_24",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_rotate_access_key_90_days",
"iam_disable_90_days_credentials",
@@ -624,7 +625,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"iam_disable_90_days_credentials"
]
@@ -1076,7 +1078,8 @@
],
"Checks": [
"ec2_ebs_public_snapshot",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key",
"awslambda_function_url_public",
"rds_snapshots_public_access",

View File

@@ -156,7 +156,8 @@
],
"Checks": [
"iam_no_root_access_key",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_root_hardware_mfa_enabled",
"iam_root_mfa_enabled",
"iam_user_mfa_enabled_console_access",

View File

@@ -113,9 +113,11 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_no_root_access_key"
]
},

View File

@@ -46,7 +46,8 @@
],
"Checks": [
"iam_policy_attached_only_to_group_or_roles",
"iam_policy_no_administrative_privileges",
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges",
"iam_disable_90_days_credentials"
]
},
@@ -311,7 +312,8 @@
}
],
"Checks": [
"iam_policy_no_administrative_privileges"
"iam_aws_attached_policy_no_administrative_privileges",
"iam_customer_attached_policy_no_administrative_privileges"
]
},
{

View File

@@ -0,0 +1,34 @@
{
"Provider": "aws",
"CheckID": "iam_aws_attached_policy_no_administrative_privileges",
"CheckTitle": "Ensure IAM AWS-Managed policies that allow full \"*:*\" administrative privileges are not attached",
"CheckType": [
"Software and Configuration Checks",
"Industry and Regulatory Standards",
"CIS AWS Foundations Benchmark"
],
"ServiceName": "iam",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "high",
"ResourceType": "AwsIamPolicy",
"Description": "Ensure IAM AWS-Managed policies that allow full \"*:*\" administrative privileges are not attached",
"Risk": "IAM policies are the means by which privileges are granted to users; groups; or roles. It is recommended and considered a standard security advice to grant least privilege—that is; granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform only those tasks instead of allowing full administrative privileges. Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "https://docs.bridgecrew.io/docs/iam_47#cli-command",
"NativeIaC": "",
"Other": "https://docs.bridgecrew.io/docs/iam_47#aws-console",
"Terraform": "https://docs.bridgecrew.io/docs/iam_47#terraform"
},
"Recommendation": {
"Text": "It is more secure to start with a minimum set of permissions and grant additional permissions as necessary; rather than starting with permissions that are too lenient and then trying to tighten them later. List policies an analyze if permissions are the least possible to conduct business activities.",
"Url": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": "CAF Security Epic: IAM"
}

View File

@@ -0,0 +1,42 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
class iam_aws_attached_policy_no_administrative_privileges(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
# Check only for attached AWS policies
if policy.attached and policy.type == "AWS":
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.arn
report.resource_id = policy.name
report.resource_tags = policy.tags
report.status = "PASS"
report.status_extended = f"{policy.type} policy {policy.name} is attached but does not allow '*:*' administrative privileges"
if policy.document:
# Check the statements, if one includes *:* stop iterating over the rest
if type(policy.document["Statement"]) != list:
policy_statements = [policy.document["Statement"]]
else:
policy_statements = policy.document["Statement"]
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement["Effect"] == "Allow"
and "Action" in statement
and (
statement["Action"] == "*"
or statement["Action"] == ["*"]
)
and (
statement["Resource"] == "*"
or statement["Resource"] == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"{policy.type} policy {policy.name} is attached and allows '*:*' administrative privileges"
break
findings.append(report)
return findings

View File

@@ -0,0 +1,34 @@
{
"Provider": "aws",
"CheckID": "iam_customer_attached_policy_no_administrative_privileges",
"CheckTitle": "Ensure IAM Customer-Managed policies that allow full \"*:*\" administrative privileges are not attached",
"CheckType": [
"Software and Configuration Checks",
"Industry and Regulatory Standards",
"CIS AWS Foundations Benchmark"
],
"ServiceName": "iam",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "high",
"ResourceType": "AwsIamPolicy",
"Description": "Ensure IAM Customer-Managed policies that allow full \"*:*\" administrative privileges are not attached",
"Risk": "IAM policies are the means by which privileges are granted to users; groups; or roles. It is recommended and considered a standard security advice to grant least privilege—that is; granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform only those tasks instead of allowing full administrative privileges. Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "https://docs.bridgecrew.io/docs/iam_47#cli-command",
"NativeIaC": "",
"Other": "https://docs.bridgecrew.io/docs/iam_47#aws-console",
"Terraform": "https://docs.bridgecrew.io/docs/iam_47#terraform"
},
"Recommendation": {
"Text": "It is more secure to start with a minimum set of permissions and grant additional permissions as necessary; rather than starting with permissions that are too lenient and then trying to tighten them later. List policies an analyze if permissions are the least possible to conduct business activities.",
"Url": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": "CAF Security Epic: IAM"
}

View File

@@ -0,0 +1,42 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
class iam_customer_attached_policy_no_administrative_privileges(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
# Check only for attached custom policies
if policy.attached and policy.type == "Custom":
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.arn
report.resource_id = policy.name
report.resource_tags = policy.tags
report.status = "PASS"
report.status_extended = f"{policy.type} policy {policy.name} is attached but does not allow '*:*' administrative privileges"
if policy.document:
# Check the statements, if one includes *:* stop iterating over the rest
if type(policy.document["Statement"]) != list:
policy_statements = [policy.document["Statement"]]
else:
policy_statements = policy.document["Statement"]
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement["Effect"] == "Allow"
and "Action" in statement
and (
statement["Action"] == "*"
or statement["Action"] == ["*"]
)
and (
statement["Resource"] == "*"
or statement["Resource"] == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"{policy.type} policy {policy.name} is attached and allows '*:*' administrative privileges"
break
findings.append(report)
return findings

View File

@@ -1,6 +1,6 @@
{
"Provider": "aws",
"CheckID": "iam_policy_no_administrative_privileges",
"CheckID": "iam_customer_unattached_policy_no_administrative_privileges",
"CheckTitle": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not created",
"CheckType": [
"Software and Configuration Checks",
@@ -10,9 +10,9 @@
"ServiceName": "iam",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"Severity": "low",
"ResourceType": "AwsIamPolicy",
"Description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not created",
"Description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not created, may be eventual consistent if an ephemeral resource is using it",
"Risk": "IAM policies are the means by which privileges are granted to users; groups; or roles. It is recommended and considered a standard security advice to grant least privilege—that is; granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform only those tasks instead of allowing full administrative privileges. Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.",
"RelatedUrl": "",
"Remediation": {

View File

@@ -0,0 +1,42 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
class iam_customer_unattached_policy_no_administrative_privileges(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
# Check only for cutomer unattached policies
if not policy.attached and policy.type == "Custom":
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.arn
report.resource_id = policy.name
report.resource_tags = policy.tags
report.status = "PASS"
report.status_extended = f"{policy.type} policy {policy.name} is unattached and does not allow '*:*' administrative privileges"
if policy.document:
# Check the statements, if one includes *:* stop iterating over the rest
if type(policy.document["Statement"]) != list:
policy_statements = [policy.document["Statement"]]
else:
policy_statements = policy.document["Statement"]
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement["Effect"] == "Allow"
and "Action" in statement
and (
statement["Action"] == "*"
or statement["Action"] == ["*"]
)
and (
statement["Resource"] == "*"
or statement["Resource"] == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"{policy.type} policy {policy.name} is unattached and allows '*:*' administrative privileges"
break
findings.append(report)
return findings

View File

@@ -6,44 +6,47 @@ class iam_no_custom_policy_permissive_role_assumption(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy["Arn"]
report.resource_id = policy["PolicyName"]
report.status = "PASS"
report.status_extended = f"Custom Policy {policy['PolicyName']} does not allow permissive STS Role assumption"
if policy.get("PolicyDocument"):
if type(policy["PolicyDocument"]["Statement"]) != list:
policy_statements = [policy["PolicyDocument"]["Statement"]]
else:
policy_statements = policy["PolicyDocument"]["Statement"]
for statement in policy_statements:
if (
statement["Effect"] == "Allow"
and "Action" in statement
and "Resource" in statement
and "*" in statement["Resource"]
):
if type(statement["Action"]) == list:
for action in statement["Action"]:
# Check only custom policies
if policy.type == "Custom":
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.arn
report.resource_id = policy.name
report.resource_tags = policy.tags
report.status = "PASS"
report.status_extended = f"Custom Policy {policy.name} does not allow permissive STS Role assumption"
if policy.document:
if type(policy.document["Statement"]) != list:
policy_statements = [policy.document["Statement"]]
else:
policy_statements = policy.document["Statement"]
for statement in policy_statements:
if (
statement["Effect"] == "Allow"
and "Action" in statement
and "Resource" in statement
and "*" in statement["Resource"]
):
if type(statement["Action"]) == list:
for action in statement["Action"]:
if (
action == "sts:AssumeRole"
or action == "sts:*"
or action == "*"
):
report.status = "FAIL"
report.status_extended = f"Custom Policy {policy.name} allows permissive STS Role assumption"
break
else:
if (
action == "sts:AssumeRole"
or action == "sts:*"
or action == "*"
statement["Action"] == "sts:AssumeRole"
or statement["Action"] == "sts:*"
or statement["Action"] == "*"
):
report.status = "FAIL"
report.status_extended = f"Custom Policy {policy['PolicyName']} allows permissive STS Role assumption"
break
else:
if (
statement["Action"] == "sts:AssumeRole"
or statement["Action"] == "sts:*"
or statement["Action"] == "*"
):
report.status = "FAIL"
report.status_extended = f"Custom Policy {policy['PolicyName']} allows permissive STS Role assumption"
break
report.status_extended = f"Custom Policy {policy.name} allows permissive STS Role assumption"
break
findings.append(report)
findings.append(report)
return findings

View File

@@ -61,63 +61,66 @@ class iam_policy_allows_privilege_escalation(Check):
}
findings = []
for policy in iam_client.policies:
report = Check_Report_AWS(self.metadata())
report.resource_id = policy["PolicyName"]
report.resource_arn = policy["Arn"]
report.region = iam_client.region
# Check only custom policies
if policy.type == "Custom":
report = Check_Report_AWS(self.metadata())
report.resource_id = policy.name
report.resource_arn = policy.arn
report.region = iam_client.region
report.resource_tags = policy.tags
# List of policy actions
allowed_actions = set()
denied_actions = set()
denied_not_actions = set()
# List of policy actions
allowed_actions = set()
denied_actions = set()
denied_not_actions = set()
# Recover all policy actions
if policy.get("PolicyDocument"):
if type(policy["PolicyDocument"]["Statement"]) != list:
policy_statements = [policy["PolicyDocument"]["Statement"]]
# Recover all policy actions
if policy.document:
if type(policy.document["Statement"]) != list:
policy_statements = [policy.document["Statement"]]
else:
policy_statements = policy.document["Statement"]
for statements in policy_statements:
# Recover allowed actions
if statements["Effect"] == "Allow":
if "Action" in statements:
if type(statements["Action"]) is str:
allowed_actions = {statements["Action"]}
if type(statements["Action"]) is list:
allowed_actions = set(statements["Action"])
# Recover denied actions
if statements["Effect"] == "Deny":
if "Action" in statements:
if type(statements["Action"]) is str:
denied_actions = {statements["Action"]}
if type(statements["Action"]) is list:
denied_actions = set(statements["Action"])
if "NotAction" in statements:
if type(statements["NotAction"]) is str:
denied_not_actions = {statements["NotAction"]}
if type(statements["NotAction"]) is list:
denied_not_actions = set(statements["NotAction"])
# First, we need to perform a left join with ALLOWED_ACTIONS and DENIED_ACTIONS
left_actions = allowed_actions.difference(denied_actions)
# Then, we need to find the DENIED_NOT_ACTIONS in LEFT_ACTIONS
if denied_not_actions:
privileged_actions = left_actions.intersection(denied_not_actions)
# If there is no Denied Not Actions
else:
policy_statements = policy["PolicyDocument"]["Statement"]
for statements in policy_statements:
# Recover allowed actions
if statements["Effect"] == "Allow":
if "Action" in statements:
if type(statements["Action"]) is str:
allowed_actions = {statements["Action"]}
if type(statements["Action"]) is list:
allowed_actions = set(statements["Action"])
privileged_actions = left_actions
# Finally, check if there is a privilege escalation action within this policy
policy_privilege_escalation_actions = privileged_actions.intersection(
privilege_escalation_iam_actions
)
# Recover denied actions
if statements["Effect"] == "Deny":
if "Action" in statements:
if type(statements["Action"]) is str:
denied_actions = {statements["Action"]}
if type(statements["Action"]) is list:
denied_actions = set(statements["Action"])
if "NotAction" in statements:
if type(statements["NotAction"]) is str:
denied_not_actions = {statements["NotAction"]}
if type(statements["NotAction"]) is list:
denied_not_actions = set(statements["NotAction"])
# First, we need to perform a left join with ALLOWED_ACTIONS and DENIED_ACTIONS
left_actions = allowed_actions.difference(denied_actions)
# Then, we need to find the DENIED_NOT_ACTIONS in LEFT_ACTIONS
if denied_not_actions:
privileged_actions = left_actions.intersection(denied_not_actions)
# If there is no Denied Not Actions
else:
privileged_actions = left_actions
# Finally, check if there is a privilege escalation action within this policy
policy_privilege_escalation_actions = privileged_actions.intersection(
privilege_escalation_iam_actions
)
if len(policy_privilege_escalation_actions) == 0:
report.status = "PASS"
report.status_extended = f"Customer Managed IAM Policy {report.resource_arn} not allows for privilege escalation"
else:
report.status = "FAIL"
report.status_extended = f"Customer Managed IAM Policy {report.resource_arn} allows for privilege escalation using the following actions: {policy_privilege_escalation_actions}"
findings.append(report)
if len(policy_privilege_escalation_actions) == 0:
report.status = "PASS"
report.status_extended = f"Custom Policy {report.resource_arn} does not allow privilege escalation"
else:
report.status = "FAIL"
report.status_extended = f"Custom Policy {report.resource_arn} allows privilege escalation using the following actions: {policy_privilege_escalation_actions}"
findings.append(report)
return findings

View File

@@ -1,36 +0,0 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
class iam_policy_no_administrative_privileges(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy["Arn"]
report.resource_id = policy["PolicyName"]
report.status = "PASS"
report.status_extended = f"Policy {policy['PolicyName']} does not allow '*:*' administrative privileges"
if policy.get("PolicyDocument"):
# Check the statements, if one includes *:* stop iterating over the rest
if type(policy["PolicyDocument"]["Statement"]) != list:
policy_statements = [policy["PolicyDocument"]["Statement"]]
else:
policy_statements = policy["PolicyDocument"]["Statement"]
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement["Effect"] == "Allow"
and "Action" in statement
and (statement["Action"] == "*" or statement["Action"] == ["*"])
and (
statement["Resource"] == "*"
or statement["Resource"] == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"Policy {policy['PolicyName']} allows '*:*' administrative privileges"
break
findings.append(report)
return findings

View File

@@ -8,30 +8,33 @@ class iam_policy_no_full_access_to_cloudtrail(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.get("Arn")
report.resource_id = policy.get("PolicyName")
report.status = "PASS"
report.status_extended = f"Policy {policy.get('PolicyName')} does not allow '{critical_service}:*' privileges"
if policy.get("PolicyDocument"):
# Check the statements, if one includes critical_service:* stop iterating over the rest
if type(policy.get("PolicyDocument").get("Statement")) != list:
policy_statements = [policy.get("PolicyDocument").get("Statement")]
else:
policy_statements = policy.get("PolicyDocument").get("Statement")
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement.get("Effect") == "Allow"
and critical_service + ":*" in statement.get("Action")
and (
statement.get("Resource") == "*"
or statement.get("Resource") == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"Policy {policy.get('PolicyName')} allows '{critical_service}:*' privileges"
break
findings.append(report)
# Check only custom policies
if policy.type == "Custom":
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.arn
report.resource_id = policy.name
report.resource_tags = policy.tags
report.status = "PASS"
report.status_extended = f"Custom Policy {policy.name} does not allow '{critical_service}:*' privileges"
if policy.document:
# Check the statements, if one includes critical_service:* stop iterating over the rest
if type(policy.document.get("Statement")) != list:
policy_statements = [policy.document.get("Statement")]
else:
policy_statements = policy.document.get("Statement")
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement.get("Effect") == "Allow"
and critical_service + ":*" in statement.get("Action")
and (
statement.get("Resource") == "*"
or statement.get("Resource") == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"Custom Policy {policy.name} allows '{critical_service}:*' privileges"
break
findings.append(report)
return findings

View File

@@ -8,30 +8,33 @@ class iam_policy_no_full_access_to_kms(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.get("Arn")
report.resource_id = policy.get("PolicyName")
report.status = "PASS"
report.status_extended = f"Policy {policy.get('PolicyName')} does not allow '{critical_service}:*' privileges"
if policy.get("PolicyDocument"):
# Check the statements, if one includes critical_service:* stop iterating over the rest
if type(policy.get("PolicyDocument").get("Statement")) != list:
policy_statements = [policy.get("PolicyDocument").get("Statement")]
else:
policy_statements = policy.get("PolicyDocument").get("Statement")
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement.get("Effect") == "Allow"
and critical_service + ":*" in statement.get("Action")
and (
statement.get("Resource") == "*"
or statement.get("Resource") == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"Policy {policy.get('PolicyName')} allows '{critical_service}:*' privileges"
break
findings.append(report)
# Check only custom policies
if policy.type == "Custom":
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.arn
report.resource_id = policy.name
report.resource_tags = policy.tags
report.status = "PASS"
report.status_extended = f"Custom Policy {policy.name} does not allow '{critical_service}:*' privileges"
if policy.document:
# Check the statements, if one includes critical_service:* stop iterating over the rest
if type(policy.document.get("Statement")) != list:
policy_statements = [policy.document.get("Statement")]
else:
policy_statements = policy.document.get("Statement")
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement.get("Effect") == "Allow"
and critical_service + ":*" in statement.get("Action")
and (
statement.get("Resource") == "*"
or statement.get("Resource") == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"Custom Policy {policy.name} allows '{critical_service}:*' privileges"
break
findings.append(report)
return findings

View File

@@ -63,7 +63,10 @@ class IAM:
self.entities_role_attached_to_securityaudit_policy = (
self.__list_entities_role_for_policy__(securityaudit_policy_arn)
)
self.policies = self.__list_policies__()
# List both Customer (attached and unattached) and AWS Managed (only attached) policies
self.policies = []
self.policies.extend(self.__list_policies__("AWS"))
self.policies.extend(self.__list_policies__("Local"))
self.__list_policies_version__(self.policies)
self.saml_providers = self.__list_saml_providers__()
self.server_certificates = self.__list_server_certificates__()
@@ -76,6 +79,7 @@ class IAM:
return self.session
def __get_roles__(self):
logger.info("IAM - List Roles...")
try:
roles = []
get_roles_paginator = self.client.get_paginator("list_roles")
@@ -100,6 +104,7 @@ class IAM:
return roles
def __get_credential_report__(self):
logger.info("IAM - Get Credential Report...")
report_is_completed = False
credential_list = []
try:
@@ -127,6 +132,7 @@ class IAM:
return credential_list
def __get_groups__(self):
logger.info("IAM - Get Groups...")
try:
groups = []
get_groups_paginator = self.client.get_paginator("list_groups")
@@ -145,6 +151,7 @@ class IAM:
return groups
def __get_account_summary__(self):
logger.info("IAM - Get Account Summary...")
try:
account_summary = self.client.get_account_summary()
except Exception as error:
@@ -156,6 +163,7 @@ class IAM:
return account_summary
def __get_password_policy__(self):
logger.info("IAM - Get Password Policy...")
try:
stored_password_policy = None
password_policy = self.client.get_account_password_policy()[
@@ -196,6 +204,7 @@ class IAM:
return stored_password_policy
def __get_users__(self):
logger.info("IAM - List Users...")
try:
get_users_paginator = self.client.get_paginator("list_users")
users = []
@@ -222,6 +231,7 @@ class IAM:
return users
def __list_virtual_mfa_devices__(self):
logger.info("IAM - List Virtual MFA Devices...")
try:
mfa_devices = []
list_virtual_mfa_devices_paginator = self.client.get_paginator(
@@ -239,6 +249,7 @@ class IAM:
return mfa_devices
def __list_attached_group_policies__(self):
logger.info("IAM - List Attached Group Policies...")
try:
for group in self.groups:
list_attached_group_policies_paginator = self.client.get_paginator(
@@ -258,6 +269,7 @@ class IAM:
)
def __get_group_users__(self):
logger.info("IAM - Get Group Users...")
try:
for group in self.groups:
get_group_paginator = self.client.get_paginator("get_group")
@@ -283,6 +295,7 @@ class IAM:
)
def __list_mfa_devices__(self):
logger.info("IAM - List MFA Devices...")
try:
for user in self.users:
list_mfa_devices_paginator = self.client.get_paginator(
@@ -305,6 +318,7 @@ class IAM:
)
def __list_attached_user_policies__(self):
logger.info("IAM - List Attached User Policies...")
try:
for user in self.users:
attached_user_policies = []
@@ -325,6 +339,7 @@ class IAM:
)
def __list_inline_user_policies__(self):
logger.info("IAM - List Inline User Policies...")
try:
for user in self.users:
inline_user_policies = []
@@ -345,6 +360,7 @@ class IAM:
)
def __list_entities_role_for_policy__(self, policy_arn):
logger.info("IAM - List Entities Role For Policy...")
try:
roles = []
roles = self.client.list_entities_for_policy(
@@ -357,16 +373,29 @@ class IAM:
finally:
return roles
def __list_policies__(self):
def __list_policies__(self, scope):
logger.info("IAM - List Policies...")
try:
policies = []
list_policies_paginator = self.client.get_paginator("list_policies")
for page in list_policies_paginator.paginate(Scope="Local"):
for page in list_policies_paginator.paginate(
Scope=scope, OnlyAttached=False if scope == "Local" else True
): # Look for only Attached policies when AWS Managed
for policy in page["Policies"]:
if not self.audit_resources or (
is_resource_filtered(policy["Arn"], self.audit_resources)
):
policies.append(policy)
policies.append(
Policy(
name=policy["PolicyName"],
arn=policy["Arn"],
version_id=policy["DefaultVersionId"],
type="Custom" if scope == "Local" else "AWS",
attached=True
if policy["AttachmentCount"] > 0
else False,
)
)
except Exception as error:
logger.error(
f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
@@ -375,18 +404,20 @@ class IAM:
return policies
def __list_policies_version__(self, policies):
logger.info("IAM - List Policies Version...")
try:
for policy in policies:
policy_version = self.client.get_policy_version(
PolicyArn=policy["Arn"], VersionId=policy["DefaultVersionId"]
PolicyArn=policy.arn, VersionId=policy.version_id
)
policy["PolicyDocument"] = policy_version["PolicyVersion"]["Document"]
policy.document = policy_version["PolicyVersion"]["Document"]
except Exception as error:
logger.error(
f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __list_saml_providers__(self):
logger.info("IAM - List SAML Providers...")
try:
saml_providers = self.client.list_saml_providers()["SAMLProviderList"]
except Exception as error:
@@ -398,6 +429,7 @@ class IAM:
return saml_providers
def __list_server_certificates__(self):
logger.info("IAM - List Server Certificates...")
try:
server_certificates = []
for certificate in self.client.list_server_certificates()[
@@ -439,6 +471,14 @@ class IAM:
logger.error(
f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
try:
for policy in self.policies:
response = self.client.list_policy_tags(PolicyArn=policy.arn)["Tags"]
policy.tags = response
except Exception as error:
logger.error(
f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
class MFADevice(BaseModel):
@@ -489,3 +529,13 @@ class Certificate(BaseModel):
id: str
arn: str
expiration: datetime
class Policy(BaseModel):
name: str
arn: str
version_id: str
type: str
attached: bool
document: Optional[dict]
tags: Optional[list] = []

View File

@@ -0,0 +1,165 @@
from re import search
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
AWS_ACCOUNT_NUMBER = "123456789012"
class Test_iam_aws_attached_policy_no_administrative_privileges_test:
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
session_config=None,
original_session=None,
audit_session=session.Session(
profile_name=None,
botocore_session=None,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,
profile=None,
profile_region=None,
credentials=None,
assumed_role_info=None,
audited_regions=["us-east-1", "eu-west-1"],
organizations_metadata=None,
audit_resources=None,
)
return audit_info
@mock_iam
def test_policy_with_administrative_privileges(self):
iam_client = client("iam")
iam_client.create_role(
RoleName="my-role", AssumeRolePolicyDocument="{}", Path="/my-path/"
)
iam_client.attach_role_policy(
PolicyArn="arn:aws:iam::aws:policy/AdministratorAccess", RoleName="my-role"
)
current_audit_info = self.set_mocked_audit_info()
from prowler.providers.aws.services.iam.iam_service import IAM
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_aws_attached_policy_no_administrative_privileges.iam_aws_attached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_aws_attached_policy_no_administrative_privileges.iam_aws_attached_policy_no_administrative_privileges import (
iam_aws_attached_policy_no_administrative_privileges,
)
check = iam_aws_attached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "AdministratorAccess":
assert result.status == "FAIL"
assert (
result.resource_arn
== "arn:aws:iam::aws:policy/AdministratorAccess"
)
assert search(
"AWS policy AdministratorAccess is attached and allows ",
result.status_extended,
)
@mock_iam
def test_policy_non_administrative(self):
iam_client = client("iam")
iam_client.create_role(
RoleName="my-role", AssumeRolePolicyDocument="{}", Path="/my-path/"
)
iam_client.attach_role_policy(
PolicyArn="arn:aws:iam::aws:policy/IAMUserChangePassword",
RoleName="my-role",
)
current_audit_info = self.set_mocked_audit_info()
from prowler.providers.aws.services.iam.iam_service import IAM
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_aws_attached_policy_no_administrative_privileges.iam_aws_attached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_aws_attached_policy_no_administrative_privileges.iam_aws_attached_policy_no_administrative_privileges import (
iam_aws_attached_policy_no_administrative_privileges,
)
check = iam_aws_attached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "IAMUserChangePassword":
assert result.status == "PASS"
assert (
result.resource_arn
== "arn:aws:iam::aws:policy/IAMUserChangePassword"
)
assert search(
"AWS policy IAMUserChangePassword is attached but does not allow",
result.status_extended,
)
@mock_iam
def test_policy_administrative_and_non_administrative(self):
iam_client = client("iam")
iam_client.create_role(
RoleName="my-role", AssumeRolePolicyDocument="{}", Path="/my-path/"
)
iam_client.attach_role_policy(
PolicyArn="arn:aws:iam::aws:policy/AdministratorAccess", RoleName="my-role"
)
iam_client.attach_role_policy(
PolicyArn="arn:aws:iam::aws:policy/IAMUserChangePassword",
RoleName="my-role",
)
current_audit_info = self.set_mocked_audit_info()
from prowler.providers.aws.services.iam.iam_service import IAM
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_aws_attached_policy_no_administrative_privileges.iam_aws_attached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_aws_attached_policy_no_administrative_privileges.iam_aws_attached_policy_no_administrative_privileges import (
iam_aws_attached_policy_no_administrative_privileges,
)
check = iam_aws_attached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "IAMUserChangePassword":
assert result.status == "PASS"
assert (
result.resource_arn
== "arn:aws:iam::aws:policy/IAMUserChangePassword"
)
assert search(
"AWS policy IAMUserChangePassword is attached but does not allow ",
result.status_extended,
)
assert result.resource_id == "IAMUserChangePassword"
if result.resource_id == "AdministratorAccess":
assert result.status == "FAIL"
assert (
result.resource_arn
== "arn:aws:iam::aws:policy/AdministratorAccess"
)
assert search(
"AWS policy AdministratorAccess is attached and allows ",
result.status_extended,
)
assert result.resource_id == "AdministratorAccess"

View File

@@ -0,0 +1,185 @@
from json import dumps
from re import search
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
AWS_ACCOUNT_NUMBER = "123456789012"
class Test_iam_customer_attached_policy_no_administrative_privileges_test:
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
session_config=None,
original_session=None,
audit_session=session.Session(
profile_name=None,
botocore_session=None,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,
profile=None,
profile_region=None,
credentials=None,
assumed_role_info=None,
audited_regions=["us-east-1", "eu-west-1"],
organizations_metadata=None,
audit_resources=None,
)
return audit_info
@mock_iam
def test_policy_administrative(self):
iam_client = client("iam")
policy_name = "policy1"
policy_document = {
"Version": "2012-10-17",
"Statement": [
{"Effect": "Allow", "Action": "*", "Resource": "*"},
],
}
iam_client.create_role(
RoleName="my-role", AssumeRolePolicyDocument="{}", Path="/my-path/"
)
arn = iam_client.create_policy(
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
)["Policy"]["Arn"]
iam_client.attach_role_policy(PolicyArn=arn, RoleName="my-role")
current_audit_info = self.set_mocked_audit_info()
from prowler.providers.aws.services.iam.iam_service import IAM
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_customer_attached_policy_no_administrative_privileges.iam_customer_attached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_customer_attached_policy_no_administrative_privileges.iam_customer_attached_policy_no_administrative_privileges import (
iam_customer_attached_policy_no_administrative_privileges,
)
check = iam_customer_attached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "policy1":
assert result.status == "FAIL"
assert result.resource_arn == arn
assert search(
f"Custom policy {policy_name} is attached and allows ",
result.status_extended,
)
@mock_iam
def test_policy_non_administrative(self):
iam_client = client("iam")
policy_name = "policy1"
policy_document = {
"Version": "2012-10-17",
"Statement": [
{"Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "*"},
],
}
iam_client.create_role(
RoleName="my-role", AssumeRolePolicyDocument="{}", Path="/my-path/"
)
arn = iam_client.create_policy(
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
)["Policy"]["Arn"]
iam_client.attach_role_policy(PolicyArn=arn, RoleName="my-role")
current_audit_info = self.set_mocked_audit_info()
from prowler.providers.aws.services.iam.iam_service import IAM
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_customer_attached_policy_no_administrative_privileges.iam_customer_attached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_customer_attached_policy_no_administrative_privileges.iam_customer_attached_policy_no_administrative_privileges import (
iam_customer_attached_policy_no_administrative_privileges,
)
check = iam_customer_attached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "policy1":
assert result.status == "PASS"
assert result.resource_arn == arn
assert search(
f"Custom policy {policy_name} is attached but does not allow",
result.status_extended,
)
@mock_iam
def test_policy_administrative_and_non_administrative(self):
iam_client = client("iam")
policy_name_non_administrative = "policy1"
policy_document_non_administrative = {
"Version": "2012-10-17",
"Statement": [
{"Effect": "Allow", "Action": "logs:*", "Resource": "*"},
],
}
policy_name_administrative = "policy2"
policy_document_administrative = {
"Version": "2012-10-17",
"Statement": [
{"Effect": "Allow", "Action": "*", "Resource": "*"},
],
}
arn_non_administrative = iam_client.create_policy(
PolicyName=policy_name_non_administrative,
PolicyDocument=dumps(policy_document_non_administrative),
)["Policy"]["Arn"]
arn_administrative = iam_client.create_policy(
PolicyName=policy_name_administrative,
PolicyDocument=dumps(policy_document_administrative),
)["Policy"]["Arn"]
iam_client.create_role(
RoleName="my-role", AssumeRolePolicyDocument="{}", Path="/my-path/"
)
iam_client.attach_role_policy(
PolicyArn=arn_non_administrative, RoleName="my-role"
)
iam_client.attach_role_policy(PolicyArn=arn_administrative, RoleName="my-role")
current_audit_info = self.set_mocked_audit_info()
from prowler.providers.aws.services.iam.iam_service import IAM
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_customer_attached_policy_no_administrative_privileges.iam_customer_attached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_customer_attached_policy_no_administrative_privileges.iam_customer_attached_policy_no_administrative_privileges import (
iam_customer_attached_policy_no_administrative_privileges,
)
check = iam_customer_attached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "policy1":
assert result.status == "PASS"
assert result.resource_arn == arn_non_administrative
assert search(
f"Custom policy {policy_name_non_administrative} is attached but does not allow ",
result.status_extended,
)
assert result.resource_id == policy_name_non_administrative
if result.resource_id == "policy2":
assert result.status == "FAIL"
assert result.resource_arn == arn_administrative
assert search(
f"Custom policy {policy_name_administrative} is attached and allows ",
result.status_extended,
)
assert result.resource_id == policy_name_administrative

View File

@@ -10,7 +10,7 @@ from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
class Test_iam_policy_no_administrative_privileges_test:
class Test_iam_customer_unattached_policy_no_administrative_privileges_test:
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
session_config=None,
@@ -55,19 +55,23 @@ class Test_iam_policy_no_administrative_privileges_test:
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_policy_no_administrative_privileges.iam_policy_no_administrative_privileges.iam_client",
"prowler.providers.aws.services.iam.iam_customer_unattached_policy_no_administrative_privileges.iam_customer_unattached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_policy_no_administrative_privileges.iam_policy_no_administrative_privileges import (
iam_policy_no_administrative_privileges,
from prowler.providers.aws.services.iam.iam_customer_unattached_policy_no_administrative_privileges.iam_customer_unattached_policy_no_administrative_privileges import (
iam_customer_unattached_policy_no_administrative_privileges,
)
check = iam_policy_no_administrative_privileges()
result = check.execute()
assert result[0].status == "FAIL"
assert result[0].resource_arn == arn
assert search(f"Policy {policy_name} allows ", result[0].status_extended)
assert result[0].resource_id == policy_name
check = iam_customer_unattached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "policy1":
assert result.status == "FAIL"
assert result.resource_arn == arn
assert search(
f"Custom policy {policy_name} is unattached and allows ",
result.status_extended,
)
@mock_iam
def test_policy_non_administrative(self):
@@ -90,21 +94,23 @@ class Test_iam_policy_no_administrative_privileges_test:
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_policy_no_administrative_privileges.iam_policy_no_administrative_privileges.iam_client",
"prowler.providers.aws.services.iam.iam_customer_unattached_policy_no_administrative_privileges.iam_customer_unattached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_policy_no_administrative_privileges.iam_policy_no_administrative_privileges import (
iam_policy_no_administrative_privileges,
from prowler.providers.aws.services.iam.iam_customer_unattached_policy_no_administrative_privileges.iam_customer_unattached_policy_no_administrative_privileges import (
iam_customer_unattached_policy_no_administrative_privileges,
)
check = iam_policy_no_administrative_privileges()
result = check.execute()
assert result[0].status == "PASS"
assert result[0].resource_arn == arn
assert search(
f"Policy {policy_name} does not allow", result[0].status_extended
)
assert result[0].resource_id == policy_name
check = iam_customer_unattached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "policy1":
assert result.status == "PASS"
assert result.resource_arn == arn
assert search(
f"Custom policy {policy_name} is unattached and does not allow",
result.status_extended,
)
@mock_iam
def test_policy_administrative_and_non_administrative(self):
@@ -139,27 +145,29 @@ class Test_iam_policy_no_administrative_privileges_test:
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_policy_no_administrative_privileges.iam_policy_no_administrative_privileges.iam_client",
"prowler.providers.aws.services.iam.iam_customer_unattached_policy_no_administrative_privileges.iam_customer_unattached_policy_no_administrative_privileges.iam_client",
new=IAM(current_audit_info),
):
from prowler.providers.aws.services.iam.iam_policy_no_administrative_privileges.iam_policy_no_administrative_privileges import (
iam_policy_no_administrative_privileges,
from prowler.providers.aws.services.iam.iam_customer_unattached_policy_no_administrative_privileges.iam_customer_unattached_policy_no_administrative_privileges import (
iam_customer_unattached_policy_no_administrative_privileges,
)
check = iam_policy_no_administrative_privileges()
result = check.execute()
assert len(result) == 2
assert result[0].status == "PASS"
assert result[0].resource_arn == arn_non_administrative
assert search(
f"Policy {policy_name_non_administrative} does not allow ",
result[0].status_extended,
)
assert result[0].resource_id == policy_name_non_administrative
assert result[1].status == "FAIL"
assert result[1].resource_arn == arn_administrative
assert search(
f"Policy {policy_name_administrative} allows ",
result[1].status_extended,
)
assert result[1].resource_id == policy_name_administrative
check = iam_customer_unattached_policy_no_administrative_privileges()
results = check.execute()
for result in results:
if result.resource_id == "policy1":
assert result.status == "PASS"
assert result.resource_arn == arn_non_administrative
assert search(
f"Custom policy {policy_name_non_administrative} is unattached and does not allow ",
result.status_extended,
)
assert result.resource_id == policy_name_non_administrative
if result.resource_id == "policy2":
assert result.status == "FAIL"
assert result.resource_arn == arn_administrative
assert search(
f"Custom policy {policy_name_administrative} is unattached and allows ",
result.status_extended,
)
assert result.resource_id == policy_name_administrative

View File

@@ -69,7 +69,7 @@ class Test_iam_policy_allows_privilege_escalation:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Customer Managed IAM Policy {policy_arn} allows for privilege escalation using the following actions: {{'sts:*'}}"
== f"Custom Policy {policy_arn} allows privilege escalation using the following actions: {{'sts:*'}}"
)
assert result[0].resource_id == policy_name
assert result[0].resource_arn == policy_arn
@@ -111,7 +111,7 @@ class Test_iam_policy_allows_privilege_escalation:
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Customer Managed IAM Policy {policy_arn} not allows for privilege escalation"
== f"Custom Policy {policy_arn} does not allow privilege escalation"
)
assert result[0].resource_id == policy_name
assert result[0].resource_arn == policy_arn
@@ -157,7 +157,7 @@ class Test_iam_policy_allows_privilege_escalation:
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Customer Managed IAM Policy {policy_arn} not allows for privilege escalation"
== f"Custom Policy {policy_arn} does not allow privilege escalation"
)
assert result[0].resource_id == policy_name
assert result[0].resource_arn == policy_arn
@@ -214,7 +214,7 @@ class Test_iam_policy_allows_privilege_escalation:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Customer Managed IAM Policy {policy_arn} allows for privilege escalation using the following actions: {{'dynamodb:PutItem'}}"
== f"Custom Policy {policy_arn} allows privilege escalation using the following actions: {{'dynamodb:PutItem'}}"
)
assert result[0].resource_id == policy_name
assert result[0].resource_arn == policy_arn

View File

@@ -9,7 +9,6 @@ from prowler.providers.aws.services.iam.iam_service import IAM
class Test_iam_policy_no_full_access_to_cloudtrail:
# Mocked Audit Info
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
@@ -66,7 +65,7 @@ class Test_iam_policy_no_full_access_to_cloudtrail:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Policy {policy_name} allows 'cloudtrail:*' privileges"
== f"Custom Policy {policy_name} allows 'cloudtrail:*' privileges"
)
assert result[0].resource_id == "policy_cloudtrail_full"
assert result[0].resource_arn == arn
@@ -105,7 +104,7 @@ class Test_iam_policy_no_full_access_to_cloudtrail:
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Policy {policy_name} does not allow 'cloudtrail:*' privileges"
== f"Custom Policy {policy_name} does not allow 'cloudtrail:*' privileges"
)
assert result[0].resource_id == "policy_no_cloudtrail_full"
assert result[0].resource_arn == arn
@@ -148,7 +147,7 @@ class Test_iam_policy_no_full_access_to_cloudtrail:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Policy {policy_name} allows 'cloudtrail:*' privileges"
== f"Custom Policy {policy_name} allows 'cloudtrail:*' privileges"
)
assert result[0].resource_id == "policy_mixed"
assert result[0].resource_arn == arn

View File

@@ -9,7 +9,6 @@ from prowler.providers.aws.services.iam.iam_service import IAM
class Test_iam_policy_no_full_access_to_kms:
# Mocked Audit Info
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
@@ -66,7 +65,7 @@ class Test_iam_policy_no_full_access_to_kms:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Policy {policy_name} allows 'kms:*' privileges"
== f"Custom Policy {policy_name} allows 'kms:*' privileges"
)
assert result[0].resource_id == "policy_kms_full"
assert result[0].resource_arn == arn
@@ -105,7 +104,7 @@ class Test_iam_policy_no_full_access_to_kms:
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Policy {policy_name} does not allow 'kms:*' privileges"
== f"Custom Policy {policy_name} does not allow 'kms:*' privileges"
)
assert result[0].resource_id == "policy_no_kms_full"
assert result[0].resource_arn == arn
@@ -144,7 +143,7 @@ class Test_iam_policy_no_full_access_to_kms:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Policy {policy_name} allows 'kms:*' privileges"
== f"Custom Policy {policy_name} allows 'kms:*' privileges"
)
assert result[0].resource_id == "policy_mixed"
assert result[0].resource_arn == arn

View File

@@ -620,12 +620,23 @@ class Test_IAM_Service:
],
}
iam_client.create_policy(
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
PolicyName=policy_name,
PolicyDocument=dumps(policy_document),
Tags=[
{"Key": "string", "Value": "string"},
],
)
audit_info = self.set_mocked_audit_info()
iam = IAM(audit_info)
assert len(iam.policies) == 1
assert iam.policies[0]["PolicyName"] == "policy1"
custom_policies = 0
for policy in iam.policies:
if policy.type == "Custom":
custom_policies += 1
assert policy.name == "policy1"
assert policy.tags == [
{"Key": "string", "Value": "string"},
]
assert custom_policies == 1
@mock_iam
def test__list_policies_version__(self):
@@ -643,10 +654,15 @@ class Test_IAM_Service:
audit_info = self.set_mocked_audit_info()
iam = IAM(audit_info)
assert len(iam.policies) == 1
assert iam.policies[0]["PolicyDocument"]["Statement"][0]["Effect"] == "Allow"
assert iam.policies[0]["PolicyDocument"]["Statement"][0]["Action"] == "*"
assert iam.policies[0]["PolicyDocument"]["Statement"][0]["Resource"] == "*"
custom_policies = 0
for policy in iam.policies:
if policy.type == "Custom":
custom_policies += 1
assert policy.name == "policy2"
assert policy.document["Statement"][0]["Effect"] == "Allow"
assert policy.document["Statement"][0]["Action"] == "*"
assert policy.document["Statement"][0]["Resource"] == "*"
assert custom_policies == 1
# Test IAM List SAML Providers
@mock_iam