diff --git a/prowler/compliance/aws/aws_foundational_security_best_practices_aws.json b/prowler/compliance/aws/aws_foundational_security_best_practices_aws.json index 3c9ac87f..558a4a26 100644 --- a/prowler/compliance/aws/aws_foundational_security_best_practices_aws.json +++ b/prowler/compliance/aws/aws_foundational_security_best_practices_aws.json @@ -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" ] }, { diff --git a/prowler/compliance/aws/cis_1.4_aws.json b/prowler/compliance/aws/cis_1.4_aws.json index 9e3e3ab3..4843610c 100644 --- a/prowler/compliance/aws/cis_1.4_aws.json +++ b/prowler/compliance/aws/cis_1.4_aws.json @@ -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": [ { diff --git a/prowler/compliance/aws/cis_1.5_aws.json b/prowler/compliance/aws/cis_1.5_aws.json index 0888c7e8..ae36ad36 100644 --- a/prowler/compliance/aws/cis_1.5_aws.json +++ b/prowler/compliance/aws/cis_1.5_aws.json @@ -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": [ { diff --git a/prowler/compliance/aws/cisa_aws.json b/prowler/compliance/aws/cisa_aws.json index d5e69124..b6ddd542 100644 --- a/prowler/compliance/aws/cisa_aws.json +++ b/prowler/compliance/aws/cisa_aws.json @@ -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" ] }, diff --git a/prowler/compliance/aws/ens_rd2022_aws.json b/prowler/compliance/aws/ens_rd2022_aws.json index adbea12b..c7aa0b14 100644 --- a/prowler/compliance/aws/ens_rd2022_aws.json +++ b/prowler/compliance/aws/ens_rd2022_aws.json @@ -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" diff --git a/prowler/compliance/aws/fedramp_low_revision_4_aws.json b/prowler/compliance/aws/fedramp_low_revision_4_aws.json index 726556cf..8b43d3cf 100644 --- a/prowler/compliance/aws/fedramp_low_revision_4_aws.json +++ b/prowler/compliance/aws/fedramp_low_revision_4_aws.json @@ -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", diff --git a/prowler/compliance/aws/fedramp_moderate_revision_4_aws.json b/prowler/compliance/aws/fedramp_moderate_revision_4_aws.json index 53635159..5b401be5 100644 --- a/prowler/compliance/aws/fedramp_moderate_revision_4_aws.json +++ b/prowler/compliance/aws/fedramp_moderate_revision_4_aws.json @@ -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" ] }, { diff --git a/prowler/compliance/aws/ffiec_aws.json b/prowler/compliance/aws/ffiec_aws.json index 2c293c2f..00a4bcc7 100644 --- a/prowler/compliance/aws/ffiec_aws.json +++ b/prowler/compliance/aws/ffiec_aws.json @@ -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" ] }, { diff --git a/prowler/compliance/aws/gdpr_aws.json b/prowler/compliance/aws/gdpr_aws.json index eada401e..97f0468d 100644 --- a/prowler/compliance/aws/gdpr_aws.json +++ b/prowler/compliance/aws/gdpr_aws.json @@ -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", diff --git a/prowler/compliance/aws/gxp_21_cfr_part_11_aws.json b/prowler/compliance/aws/gxp_21_cfr_part_11_aws.json index 8d79ac89..20012fac 100644 --- a/prowler/compliance/aws/gxp_21_cfr_part_11_aws.json +++ b/prowler/compliance/aws/gxp_21_cfr_part_11_aws.json @@ -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", diff --git a/prowler/compliance/aws/hipaa_aws.json b/prowler/compliance/aws/hipaa_aws.json index 4cc7d157..c3ba88b6 100644 --- a/prowler/compliance/aws/hipaa_aws.json +++ b/prowler/compliance/aws/hipaa_aws.json @@ -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", diff --git a/prowler/compliance/aws/nist_800_171_revision_2_aws.json b/prowler/compliance/aws/nist_800_171_revision_2_aws.json index 93055f57..2219afae 100644 --- a/prowler/compliance/aws/nist_800_171_revision_2_aws.json +++ b/prowler/compliance/aws/nist_800_171_revision_2_aws.json @@ -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" ] }, { diff --git a/prowler/compliance/aws/nist_800_53_revision_4_aws.json b/prowler/compliance/aws/nist_800_53_revision_4_aws.json index 1f064262..762a9550 100644 --- a/prowler/compliance/aws/nist_800_53_revision_4_aws.json +++ b/prowler/compliance/aws/nist_800_53_revision_4_aws.json @@ -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" ] }, { diff --git a/prowler/compliance/aws/nist_800_53_revision_5_aws.json b/prowler/compliance/aws/nist_800_53_revision_5_aws.json index 57a7a77f..d3f8cb21 100644 --- a/prowler/compliance/aws/nist_800_53_revision_5_aws.json +++ b/prowler/compliance/aws/nist_800_53_revision_5_aws.json @@ -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", diff --git a/prowler/compliance/aws/nist_csf_1.1_aws.json b/prowler/compliance/aws/nist_csf_1.1_aws.json index fcfe93fa..30eb8cd8 100644 --- a/prowler/compliance/aws/nist_csf_1.1_aws.json +++ b/prowler/compliance/aws/nist_csf_1.1_aws.json @@ -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", diff --git a/prowler/compliance/aws/pci_3.2.1_aws.json b/prowler/compliance/aws/pci_3.2.1_aws.json index f05a949c..f54cb33e 100644 --- a/prowler/compliance/aws/pci_3.2.1_aws.json +++ b/prowler/compliance/aws/pci_3.2.1_aws.json @@ -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", diff --git a/prowler/compliance/aws/rbi_cyber_security_framework_aws.json b/prowler/compliance/aws/rbi_cyber_security_framework_aws.json index 6681634d..5120b2cc 100644 --- a/prowler/compliance/aws/rbi_cyber_security_framework_aws.json +++ b/prowler/compliance/aws/rbi_cyber_security_framework_aws.json @@ -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" ] }, diff --git a/prowler/compliance/aws/soc2_aws.json b/prowler/compliance/aws/soc2_aws.json index ae1a46a3..b190e3e6 100644 --- a/prowler/compliance/aws/soc2_aws.json +++ b/prowler/compliance/aws/soc2_aws.json @@ -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" ] }, { diff --git a/prowler/providers/aws/services/iam/iam_policy_no_administrative_privileges/__init__.py b/prowler/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/__init__.py similarity index 100% rename from prowler/providers/aws/services/iam/iam_policy_no_administrative_privileges/__init__.py rename to prowler/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/__init__.py diff --git a/prowler/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges.metadata.json b/prowler/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges.metadata.json new file mode 100644 index 00000000..ff197b57 --- /dev/null +++ b/prowler/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges.metadata.json @@ -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" +} diff --git a/prowler/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges.py b/prowler/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges.py new file mode 100644 index 00000000..dc5afe1e --- /dev/null +++ b/prowler/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges.py @@ -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 diff --git a/prowler/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/__init__.py b/prowler/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges.metadata.json b/prowler/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges.metadata.json new file mode 100644 index 00000000..d2d94546 --- /dev/null +++ b/prowler/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges.metadata.json @@ -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" +} diff --git a/prowler/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges.py b/prowler/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges.py new file mode 100644 index 00000000..f7f850fc --- /dev/null +++ b/prowler/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges.py @@ -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 diff --git a/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/__init__.py b/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges.metadata.json b/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges.metadata.json similarity index 90% rename from prowler/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges.metadata.json rename to prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges.metadata.json index d39dbe87..74e27a29 100644 --- a/prowler/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges.metadata.json +++ b/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges.metadata.json @@ -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": { diff --git a/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges.py b/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges.py new file mode 100644 index 00000000..478c3423 --- /dev/null +++ b/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges.py @@ -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 diff --git a/prowler/providers/aws/services/iam/iam_no_custom_policy_permissive_role_assumption/iam_no_custom_policy_permissive_role_assumption.py b/prowler/providers/aws/services/iam/iam_no_custom_policy_permissive_role_assumption/iam_no_custom_policy_permissive_role_assumption.py index cf15c8c4..b030f139 100644 --- a/prowler/providers/aws/services/iam/iam_no_custom_policy_permissive_role_assumption/iam_no_custom_policy_permissive_role_assumption.py +++ b/prowler/providers/aws/services/iam/iam_no_custom_policy_permissive_role_assumption/iam_no_custom_policy_permissive_role_assumption.py @@ -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 diff --git a/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py b/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py index 6a5d9791..f7c616cc 100644 --- a/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py +++ b/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py @@ -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 diff --git a/prowler/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges.py b/prowler/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges.py deleted file mode 100644 index 8450884d..00000000 --- a/prowler/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges.py +++ /dev/null @@ -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 diff --git a/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail.py b/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail.py index b7e7bbb7..dc820d51 100644 --- a/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail.py +++ b/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail.py @@ -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 diff --git a/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms.py b/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms.py index ee12f177..c93da053 100644 --- a/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms.py +++ b/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms.py @@ -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 diff --git a/prowler/providers/aws/services/iam/iam_service.py b/prowler/providers/aws/services/iam/iam_service.py index 53b6214e..426a4b7b 100644 --- a/prowler/providers/aws/services/iam/iam_service.py +++ b/prowler/providers/aws/services/iam/iam_service.py @@ -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] = [] diff --git a/tests/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges_test.py b/tests/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges_test.py new file mode 100644 index 00000000..03444a8e --- /dev/null +++ b/tests/providers/aws/services/iam/iam_aws_attached_policy_no_administrative_privileges/iam_aws_attached_policy_no_administrative_privileges_test.py @@ -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" diff --git a/tests/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges_test.py b/tests/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges_test.py new file mode 100644 index 00000000..a3e321a1 --- /dev/null +++ b/tests/providers/aws/services/iam/iam_customer_attached_policy_no_administrative_privileges/iam_customer_attached_policy_no_administrative_privileges_test.py @@ -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 diff --git a/tests/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges_test.py b/tests/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges_test.py similarity index 53% rename from tests/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges_test.py rename to tests/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges_test.py index 292b1f5a..ab915e78 100644 --- a/tests/providers/aws/services/iam/iam_policy_no_administrative_privileges/iam_policy_no_administrative_privileges_test.py +++ b/tests/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_policy_no_administrative_privileges_test.py @@ -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 diff --git a/tests/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation_test.py b/tests/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation_test.py index 9498ab57..cb4d00f5 100644 --- a/tests/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation_test.py +++ b/tests/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation_test.py @@ -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 diff --git a/tests/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail_test.py b/tests/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail_test.py index b4a66422..54196bd6 100644 --- a/tests/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail_test.py +++ b/tests/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail_test.py @@ -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 diff --git a/tests/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms_test.py b/tests/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms_test.py index 4df5acef..c40051df 100644 --- a/tests/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms_test.py +++ b/tests/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms_test.py @@ -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 diff --git a/tests/providers/aws/services/iam/iam_service_test.py b/tests/providers/aws/services/iam/iam_service_test.py index 20e0b6f1..9ecec3d2 100644 --- a/tests/providers/aws/services/iam/iam_service_test.py +++ b/tests/providers/aws/services/iam/iam_service_test.py @@ -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