From 7954e61944bc4088f04495228c55f5e2744f17c3 Mon Sep 17 00:00:00 2001 From: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Date: Mon, 6 May 2024 17:22:48 +0200 Subject: [PATCH] chore(v3): backport latest v4 changes (#3916) --- docs/developer-guide/checks.md | 4 +- docs/developer-guide/services.md | 2 + docs/developer-guide/unit-testing.md | 108 +- prowler/lib/outputs/summary_table.py | 5 +- .../providers/aws/aws_regions_by_service.json | 51 +- ...tain_current_contact_details.metadata.json | 4 +- ...urity_billing_and_operations.metadata.json | 4 +- ...ails_to_security_billing_and_operations.py | 40 +- ...ct_information_is_registered.metadata.json | 2 +- ...egistered_in_the_aws_account.metadata.json | 2 +- .../aws/services/account/account_service.py | 55 +- ...ertificates_expiration_check.metadata.json | 2 +- ..._restapi_authorizers_enabled.metadata.json | 4 +- ...eway_restapi_logging_enabled.metadata.json | 2 +- ...2_api_access_logging_enabled.metadata.json | 4 +- .../athena_workgroup_encryption.metadata.json | 2 +- ...kgroup_enforce_configuration.metadata.json | 6 +- ...s_cloudtrail_logging_enabled.metadata.json | 2 +- ..._function_no_secrets_in_code.metadata.json | 2 +- ...tion_no_secrets_in_variables.metadata.json | 8 +- ...ion_using_supported_runtimes.metadata.json | 2 +- .../aws/services/backup/backup_service.py | 11 +- .../backup_vaults_encrypted.py | 34 +- .../backup_vaults_exist.py | 27 +- ...n_stack_outputs_find_secrets.metadata.json | 2 +- ...rmination_protection_enabled.metadata.json | 2 +- ...ons_geo_restrictions_enabled.metadata.json | 4 +- ..._distributions_https_enabled.metadata.json | 4 +- ...istributions_logging_enabled.metadata.json | 6 +- ...ing_deprecated_ssl_protocols.metadata.json | 4 +- ...ront_distributions_using_waf.metadata.json | 10 +- .../cloudtrail_bucket_requires_mfa_delete.py | 45 +- ...l_cloudwatch_logging_enabled.metadata.json | 4 +- .../cloudtrail_cloudwatch_logging_enabled.py | 59 +- .../cloudtrail_insights_exist.py | 29 +- ...trail_kms_encryption_enabled.metadata.json | 4 +- .../cloudtrail_kms_encryption_enabled.py | 39 +- ..._log_file_validation_enabled.metadata.json | 4 +- .../cloudtrail_log_file_validation_enabled.py | 37 +- ...ucket_access_logging_enabled.metadata.json | 6 +- ...l_logs_s3_bucket_access_logging_enabled.py | 59 +- ...t_is_not_publicly_accessible.metadata.json | 2 +- ...gs_s3_bucket_is_not_publicly_accessible.py | 73 +- ...udtrail_multi_region_enabled.metadata.json | 8 +- .../cloudtrail_multi_region_enabled.py | 61 +- ...ed_logging_management_events.metadata.json | 8 +- ...egion_enabled_logging_management_events.py | 85 +- .../cloudtrail_s3_dataevents_read_enabled.py | 90 +- .../cloudtrail_s3_dataevents_write_enabled.py | 90 +- .../services/cloudtrail/cloudtrail_service.py | 25 +- ...etwork_acls_alarm_configured.metadata.json | 4 +- ...hanges_to_network_acls_alarm_configured.py | 35 +- ...rk_gateways_alarm_configured.metadata.json | 4 +- ...es_to_network_gateways_alarm_configured.py | 35 +- ...oute_tables_alarm_configured.metadata.json | 4 +- ...o_network_route_tables_alarm_configured.py | 35 +- ...ges_to_vpcs_alarm_configured.metadata.json | 4 +- ...dwatch_changes_to_vpcs_alarm_configured.py | 35 +- ...oudwatch_cross_account_sharing_disabled.py | 29 +- ...group_kms_encryption_enabled.metadata.json | 2 +- ...dwatch_log_group_kms_encryption_enabled.py | 29 +- ...cloudwatch_log_group_no_secrets_in_logs.py | 146 +-- ...policy_specific_days_enabled.metadata.json | 6 +- ..._retention_policy_specific_days_enabled.py | 37 +- ...onfiguration_changes_enabled.metadata.json | 4 +- ...ws_config_configuration_changes_enabled.py | 35 +- ...onfiguration_changes_enabled.metadata.json | 4 +- ...loudtrail_configuration_changes_enabled.py | 35 +- ...lter_authentication_failures.metadata.json | 4 +- ...g_metric_filter_authentication_failures.py | 35 +- ...metric_filter_aws_organizations_changes.py | 35 +- ...cheduled_deletion_of_kms_cmk.metadata.json | 4 +- ...isable_or_scheduled_deletion_of_kms_cmk.py | 35 +- ...for_s3_bucket_policy_changes.metadata.json | 4 +- ...ric_filter_for_s3_bucket_policy_changes.py | 35 +- ...metric_filter_policy_changes.metadata.json | 4 +- ...dwatch_log_metric_filter_policy_changes.py | 35 +- ...log_metric_filter_root_usage.metadata.json | 4 +- ...cloudwatch_log_metric_filter_root_usage.py | 35 +- ...ilter_security_group_changes.metadata.json | 4 +- ...og_metric_filter_security_group_changes.py | 35 +- ...c_filter_sign_in_without_mfa.metadata.json | 4 +- ...h_log_metric_filter_sign_in_without_mfa.py | 35 +- ...ilter_unauthorized_api_calls.metadata.json | 4 +- ...og_metric_filter_unauthorized_api_calls.py | 35 +- .../services/cloudwatch/cloudwatch_service.py | 61 +- .../services/cloudwatch/lib/metric_filters.py | 7 +- ...recorder_all_regions_enabled.metadata.json | 6 +- ...b_instance_storage_encrypted.metadata.json | 2 +- ...r_cluster_encryption_enabled.metadata.json | 4 +- ...s_kms_cmk_encryption_enabled.metadata.json | 2 +- ...dynamodb_tables_pitr_enabled.metadata.json | 4 +- .../ec2_ami_public.metadata.json | 4 +- .../ec2_ebs_default_encryption.metadata.json | 4 +- .../ec2_ebs_public_snapshot.metadata.json | 4 +- .../ec2_ebs_snapshots_encrypted.metadata.json | 8 +- .../ec2_ebs_volume_encryption.metadata.json | 2 +- .../ec2_elastic_ip_shodan.metadata.json | 2 +- .../ec2_elastic_ip_unassigned.metadata.json | 6 +- ..._detailed_monitoring_enabled.metadata.json | 4 +- .../ec2_instance_imdsv2_enabled.metadata.json | 4 +- .../ec2_instance_public_ip.metadata.json | 6 +- ...2_instance_secrets_user_data.metadata.json | 6 +- ...cl_allow_ingress_tcp_port_22.metadata.json | 4 +- ..._allow_ingress_tcp_port_3389.metadata.json | 4 +- ...from_internet_to_tcp_port_22.metadata.json | 8 +- ...om_internet_to_tcp_port_3389.metadata.json | 8 +- ...oup_default_restrict_traffic.metadata.json | 4 +- .../providers/aws/services/ec2/ec2_service.py | 4 +- ...ries_not_publicly_accessible.metadata.json | 4 +- ..._scan_images_on_push_enabled.metadata.json | 4 +- ...tions_no_environment_secrets.metadata.json | 2 +- ...s_encryption_at_rest_enabled.metadata.json | 4 +- .../efs_not_publicly_accessible.metadata.json | 8 +- .../efs_not_publicly_accessible.py | 32 +- .../aws/services/efs/lib/__init__.py | 0 prowler/providers/aws/services/efs/lib/lib.py | 45 + ...ncryption_in_secrets_enabled.metadata.json | 2 +- ...uster_network_policy_enabled.metadata.json | 2 +- ...e_endpoint_access_restricted.metadata.json | 4 +- ...ne_logging_all_types_enabled.metadata.json | 6 +- .../elasticache/elasticache_service.py | 25 +- .../elb_insecure_ssl_ciphers.metadata.json | 2 +- .../elb_logging_enabled.metadata.json | 4 +- .../elbv2_deletion_protection.metadata.json | 2 +- ...elbv2_desync_mitigation_mode.metadata.json | 2 +- .../elbv2_insecure_ssl_ciphers.metadata.json | 2 +- .../elbv2_logging_enabled.metadata.json | 4 +- .../elbv2_ssl_listeners.metadata.json | 2 +- ...r_cluster_publicly_accesible.metadata.json | 2 +- .../providers/aws/services/fms/fms_service.py | 5 + ..._vaults_policy_public_access.metadata.json | 2 +- ...passwords_encryption_enabled.metadata.json | 6 +- ..._metadata_encryption_enabled.metadata.json | 4 +- ...atch_logs_encryption_enabled.metadata.json | 4 +- ..._bookmark_encryption_enabled.metadata.json | 4 +- ...points_s3_encryption_enabled.metadata.json | 4 +- ...amazon_s3_encryption_enabled.metadata.json | 4 +- ...atch_logs_encryption_enabled.metadata.json | 4 +- ..._bookmark_encryption_enabled.metadata.json | 4 +- .../guardduty_is_enabled.metadata.json | 2 +- ...no_administrative_privileges.metadata.json | 10 +- ...no_administrative_privileges.metadata.json | 10 +- ...no_administrative_privileges.metadata.json | 10 +- ...no_administrative_privileges.metadata.json | 10 +- ...xpires_passwords_within_90_days_or_less.py | 14 +- .../iam_password_policy_lowercase.py | 14 +- .../iam_password_policy_minimum_length_14.py | 14 +- .../iam_password_policy_number.py | 14 +- .../iam_password_policy_reuse_24.py | 14 +- .../iam_password_policy_symbol.py | 14 +- .../iam_password_policy_uppercase.py | 14 +- ...ached_only_to_group_or_roles.metadata.json | 2 +- ...no_full_access_to_cloudtrail.metadata.json | 2 +- ...policy_no_full_access_to_kms.metadata.json | 2 +- .../iam_role_administratoraccess_policy.py | 35 +- ...ole_cross_account_readonlyaccess_policy.py | 122 +-- ...ross_service_confused_deputy_prevention.py | 61 +- .../iam_securityaudit_role_created.py | 25 +- .../providers/aws/services/iam/iam_service.py | 213 ++-- .../iam_support_role_created.metadata.json | 2 +- .../iam_support_role_created.py | 27 +- .../iam_user_accesskey_unused.metadata.json | 4 +- ...m_user_console_access_unused.metadata.json | 4 +- ...am_user_hardware_mfa_enabled.metadata.json | 2 +- ..._no_setup_initial_access_key.metadata.json | 2 +- .../kms_cmk_rotation_enabled.metadata.json | 2 +- ...omains_audit_logging_enabled.metadata.json | 2 +- ...s_cloudwatch_logging_enabled.metadata.json | 10 +- ...s_encryption_at_rest_enabled.metadata.json | 2 +- ...ttps_communications_enforced.metadata.json | 6 +- ...ternal_user_database_enabled.metadata.json | 2 +- ...e_to_node_encryption_enabled.metadata.json | 4 +- ...ains_not_publicly_accessible.metadata.json | 2 +- ...est_service_software_version.metadata.json | 2 +- ...to_authentication_for_kibana.metadata.json | 2 +- .../rds_instance_backup_enabled.metadata.json | 2 +- ...instance_deletion_protection.metadata.json | 2 +- ..._enhanced_monitoring_enabled.metadata.json | 4 +- ..._integration_cloudwatch_logs.metadata.json | 2 +- ...inor_version_upgrade_enabled.metadata.json | 4 +- .../rds_instance_multi_az.metadata.json | 4 +- ...ds_instance_no_public_access.metadata.json | 4 +- ...s_instance_storage_encrypted.metadata.json | 4 +- ...dshift_cluster_audit_logging.metadata.json | 8 +- ...t_cluster_automatic_upgrades.metadata.json | 6 +- ...dshift_cluster_public_access.metadata.json | 6 +- .../resourceexplorer2_indexes_found.py | 27 +- .../resourceexplorer2_service.py | 14 + ...domains_transferlock_enabled.metadata.json | 2 +- ...s_cloudwatch_logging_enabled.metadata.json | 2 +- ...t_level_public_access_blocks.metadata.json | 4 +- ...s3_bucket_default_encryption.metadata.json | 4 +- .../s3_bucket_kms_encryption.metadata.json | 2 +- ...et_level_public_access_block.metadata.json | 2 +- .../s3_bucket_no_mfa_delete.metadata.json | 2 +- .../s3_bucket_object_lock.metadata.json | 4 +- .../s3_bucket_object_versioning.metadata.json | 6 +- ...t_policy_public_write_access.metadata.json | 2 +- .../s3_bucket_public_access.metadata.json | 4 +- .../s3_bucket_public_list_acl.metadata.json | 2 +- .../s3_bucket_public_write_acl.metadata.json | 2 +- ...cket_secure_transport_policy.metadata.json | 4 +- ...erver_access_logging_enabled.metadata.json | 10 +- ..._instance_encryption_enabled.metadata.json | 2 +- ...nstance_root_access_disabled.metadata.json | 2 +- ...t_internet_access_configured.metadata.json | 2 +- ...s_encryption_at_rest_enabled.metadata.json | 4 +- ...pics_not_publicly_accessible.metadata.json | 2 +- ...eues_not_publicly_accessible.metadata.json | 2 +- ...rver_side_encryption_enabled.metadata.json | 4 +- .../ssmincidents_enabled_with_plans.py | 33 +- .../ssmincidents/ssmincidents_service.py | 11 + .../trustedadvisor_errors_and_warnings.py | 47 +- ...advisor_premium_support_plan_subscribed.py | 7 +- .../trustedadvisor/trustedadvisor_service.py | 13 + ...connections_trust_boundaries.metadata.json | 2 +- ...c_endpoint_connections_trust_boundaries.py | 10 +- ..._principals_trust_boundaries.metadata.json | 2 +- .../vpc_flow_logs_enabled.metadata.json | 4 +- ..._tables_with_least_privilege.metadata.json | 2 +- .../providers/aws/services/vpc/vpc_service.py | 3 +- ...bnet_no_public_ip_by_default.metadata.json | 2 +- ...wafv2_webacl_logging_enabled.metadata.json | 2 +- ...es_volume_encryption_enabled.metadata.json | 6 +- .../aks_cluster_rbac_enabled.metadata.json | 2 +- .../aks_network_policy_enabled.metadata.json | 2 +- .../app_client_certificates_on.metadata.json | 2 +- .../app_ensure_auth_is_set_up.metadata.json | 2 +- ..._http_is_redirected_to_https.metadata.json | 2 +- ...nsure_java_version_is_latest.metadata.json | 2 +- ...ensure_php_version_is_latest.metadata.json | 2 +- ...ure_python_version_is_latest.metadata.json | 2 +- .../app_ftp_deployment_disabled.metadata.json | 2 +- .../app_http_logs_enabled.metadata.json | 2 +- .../app_minimum_tls_version_12.metadata.json | 2 +- .../app_register_with_identity.metadata.json | 2 +- ...ured_with_a_security_contact.metadata.json | 2 +- ...ender_for_app_services_is_on.metadata.json | 2 +- ...or_azure_sql_databases_is_on.metadata.json | 2 +- ...efender_for_containers_is_on.metadata.json | 2 +- ..._defender_for_keyvault_is_on.metadata.json | 2 +- ...re_defender_for_server_is_on.metadata.json | 2 +- ...fender_for_sql_servers_is_on.metadata.json | 2 +- ...e_defender_for_storage_is_on.metadata.json | 2 +- ...tify_alerts_severity_is_high.metadata.json | 2 +- ...dmin_in_less_than_five_users.metadata.json | 2 +- ...ntra_privileged_user_has_mfa.metadata.json | 2 +- ...y_expiration_set_in_non_rbac.metadata.json | 2 +- ...n_rbac_secret_expiration_set.metadata.json | 2 +- .../keyvault_private_endpoints.metadata.json | 2 +- ...ault_rbac_key_expiration_set.metadata.json | 2 +- ...t_rbac_secret_expiration_set.metadata.json | 2 +- .../keyvault_recoverable.metadata.json | 2 +- ..._activity_logs_cmk_encrypted.metadata.json | 2 +- ...ith_activity_logs_is_private.metadata.json | 2 +- ...erver_minimum_tls_version_12.metadata.json | 2 +- ...k_flow_log_more_than_90_days.metadata.json | 2 +- .../network_public_ip_shodan.metadata.json | 2 +- ...p_internet_access_restricted.metadata.json | 57 +- ...h_internet_access_restricted.metadata.json | 2 +- ...p_internet_access_restricted.metadata.json | 2 +- ...low_access_services_disabled.metadata.json | 2 +- ...ver_connection_throttling_on.metadata.json | 2 +- ...e_server_enforce_ssl_enabled.metadata.json | 4 +- ...le_server_log_checkpoints_on.metadata.json | 2 +- ...le_server_log_connections_on.metadata.json | 2 +- .../sqlserver_auditing_enabled.metadata.json | 4 +- ...r_auditing_retention_90_days.metadata.json | 2 +- ...zuread_administrator_enabled.metadata.json | 2 +- ..._unrestricted_inbound_access.metadata.json | 2 +- ...notifications_admins_enabled.metadata.json | 2 +- ...odic_recurring_scans_enabled.metadata.json | 2 +- ...r_va_scan_reports_configured.metadata.json | 2 +- ...erability_assessment_enabled.metadata.json | 2 +- ...lic_access_level_is_disabled.metadata.json | 2 +- ...etwork_access_rule_is_denied.metadata.json | 2 +- ...trusted_to_access_is_enabled.metadata.json | 2 +- ...n_with_customer_managed_keys.metadata.json | 2 +- ...nsure_minimum_tls_version_12.metadata.json | 4 +- ...transfer_required_is_enabled.metadata.json | 2 +- ...hed_disks_encrypted_with_cmk.metadata.json | 2 +- ...m_ensure_using_managed_disks.metadata.json | 2 +- prowler/providers/gcp/gcp_provider.py | 21 +- ...query_dataset_cmk_encryption.metadata.json | 4 +- ...gquery_dataset_public_access.metadata.json | 2 +- ...igquery_table_cmk_encryption.metadata.json | 2 +- ...ance_mysql_local_infile_flag.metadata.json | 2 +- ...ostgres_log_connections_flag.metadata.json | 2 +- ...gres_log_disconnections_flag.metadata.json | 2 +- ...stgres_log_min_messages_flag.metadata.json | 2 +- .../cloudsql_instance_public_ip.metadata.json | 4 +- ...database_authentication_flag.metadata.json | 2 +- ..._sqlserver_user_options_flag.metadata.json | 2 +- ...sql_instance_ssl_connections.metadata.json | 2 +- ...et_log_retention_policy_lock.metadata.json | 4 +- ...storage_bucket_public_access.metadata.json | 4 +- ..._uniform_bucket_level_access.metadata.json | 2 +- ...ss_from_the_internet_allowed.metadata.json | 4 +- ...ss_from_the_internet_allowed.metadata.json | 4 +- ...oject_wide_ssh_keys_disabled.metadata.json | 4 +- ...fault_service_account_in_use.metadata.json | 4 +- ..._in_use_with_full_api_access.metadata.json | 4 +- ...encryption_with_csek_enabled.metadata.json | 4 +- ...nce_ip_forwarding_is_enabled.metadata.json | 4 +- .../compute_instance_public_ip.metadata.json | 4 +- ...instance_serial_ports_in_use.metadata.json | 4 +- ...instance_shielded_vm_enabled.metadata.json | 4 +- ...mpute_network_default_in_use.metadata.json | 4 +- .../compute_network_not_legacy.metadata.json | 2 +- ...ute_project_os_login_enabled.metadata.json | 4 +- ...ompute_public_address_shodan.metadata.json | 2 +- ...ute_subnet_flow_logs_enabled.metadata.json | 2 +- ...encrypted_with_cmks_disabled.metadata.json | 2 +- .../dns_dnssec_disabled.metadata.json | 4 +- ...in_use_to_key_sign_in_dnssec.metadata.json | 2 +- ...n_use_to_zone_sign_in_dnssec.metadata.json | 2 +- ...r_container_scanning_enabled.metadata.json | 2 +- ...r_no_default_service_account.metadata.json | 2 +- .../iam_audit_logs_enabled.metadata.json | 2 +- ...rvice_roles_at_project_level.metadata.json | 4 +- ...enforce_separation_of_duties.metadata.json | 2 +- ...no_administrative_privileges.metadata.json | 4 +- .../providers/gcp/services/iam/iam_service.py | 11 +- ..._key_not_publicly_accessible.metadata.json | 2 +- .../kms_key_rotation_enabled.metadata.json | 4 +- tests/lib/check/check_loader_test.py | 2 +- .../lib/check/custom_checks_metadata_test.py | 2 +- .../check/fixtures/bulk_checks_metadata.py | 6 +- ...to_security_billing_and_operations_test.py | 26 + .../backup_vaults_exist_test.py | 25 + ...udtrail_bucket_requires_mfa_delete_test.py | 32 + ...udtrail_cloudwatch_logging_enabled_test.py | 29 + .../cloudtrail_insights_exist_test.py | 23 + .../cloudtrail_kms_encryption_enabled_test.py | 27 + ...dtrail_log_file_validation_enabled_test.py | 26 + ...s_s3_bucket_access_logging_enabled_test.py | 35 + ..._bucket_is_not_publicly_accessible_test.py | 35 + .../cloudtrail_multi_region_enabled_test.py | 28 + ..._enabled_logging_management_events_test.py | 26 + ...udtrail_s3_dataevents_read_enabled_test.py | 30 + ...dtrail_s3_dataevents_write_enabled_test.py | 30 + ...s_to_network_acls_alarm_configured_test.py | 48 + ...tch_cross_account_sharing_disabled_test.py | 36 + ...h_log_group_kms_encryption_enabled_test.py | 36 + ...watch_log_group_no_secrets_in_logs_test.py | 36 + ...ntion_policy_specific_days_enabled_test.py | 44 + ...nfig_configuration_changes_enabled_test.py | 50 + .../efs_not_publicly_accessible_test.py | 135 ++- .../aws/services/efs/lib/lib_test.py | 102 ++ .../fms_policy_compliant_test.py | 18 + ...s_passwords_within_90_days_or_less_test.py | 22 + .../iam_password_policy_lowercase_test.py | 22 + ..._password_policy_minimum_length_14_test.py | 22 + .../iam_password_policy_number_test.py | 22 + .../iam_password_policy_reuse_24_test.py | 22 + .../iam_password_policy_symbol_test.py | 22 + .../iam_password_policy_uppercase_test.py | 22 + ...am_role_administratoraccess_policy_test.py | 23 + .../iam_securityaudit_role_created_test.py | 22 + .../iam_support_role_created_test.py | 22 + .../resourceexplorer2_indexes_found_test.py | 28 + .../ssmincidents_enabled_with_plans_test.py | 27 + ...trustedadvisor_errors_and_warnings_test.py | 27 + ...or_premium_support_plan_subscribed_test.py | 27 + tests/providers/gcp/gcp_fixtures.py | 969 ++++++++++++++++++ .../services/apikeys/apikeys_service_test.py | 39 + .../bigquery/bigquery_service_test.py | 55 + .../cloudresourcemanager_service_test.py | 59 ++ .../cloudsql/cloudsql_service_test.py | 57 ++ .../cloudstorage/cloudstorage_service_test.py | 46 + .../services/compute/compute_service_test.py | 174 ++++ .../dataproc/dataproc_service_test.py | 47 + .../gcp/services/dns/dns_service_test.py | 49 + .../gcp/services/gke/gke_service_test.py | 69 ++ ...tion_essential_contacts_configured_test.py | 31 +- .../gcp/services/iam/iamgcp_service_test.py | 142 +++ .../gcp/services/kms/kmsgcp_service_test.py | 63 ++ .../services/logging/logging_service_test.py | 65 ++ .../monitoring/monitoring_service_test.py | 40 + .../serviceusage/serviceusage_test.py | 54 + 381 files changed, 5170 insertions(+), 1655 deletions(-) create mode 100644 prowler/providers/aws/services/efs/lib/__init__.py create mode 100644 prowler/providers/aws/services/efs/lib/lib.py create mode 100644 tests/providers/aws/services/efs/lib/lib_test.py create mode 100644 tests/providers/gcp/gcp_fixtures.py create mode 100644 tests/providers/gcp/services/apikeys/apikeys_service_test.py create mode 100644 tests/providers/gcp/services/bigquery/bigquery_service_test.py create mode 100644 tests/providers/gcp/services/cloudresourcemanager/cloudresourcemanager_service_test.py create mode 100644 tests/providers/gcp/services/cloudsql/cloudsql_service_test.py create mode 100644 tests/providers/gcp/services/cloudstorage/cloudstorage_service_test.py create mode 100644 tests/providers/gcp/services/compute/compute_service_test.py create mode 100644 tests/providers/gcp/services/dataproc/dataproc_service_test.py create mode 100644 tests/providers/gcp/services/dns/dns_service_test.py create mode 100644 tests/providers/gcp/services/gke/gke_service_test.py create mode 100644 tests/providers/gcp/services/iam/iamgcp_service_test.py create mode 100644 tests/providers/gcp/services/kms/kmsgcp_service_test.py create mode 100644 tests/providers/gcp/services/logging/logging_service_test.py create mode 100644 tests/providers/gcp/services/monitoring/monitoring_service_test.py create mode 100644 tests/providers/gcp/services/serviceusage/serviceusage_test.py diff --git a/docs/developer-guide/checks.md b/docs/developer-guide/checks.md index b9353773b9..46f145b234 100644 --- a/docs/developer-guide/checks.md +++ b/docs/developer-guide/checks.md @@ -243,11 +243,11 @@ Each Prowler check has metadata associated which is stored at the same level of # Code holds different methods to remediate the FAIL finding "Code": { # CLI holds the command in the provider native CLI to remediate it - "CLI": "https://docs.bridgecrew.io/docs/public_8#cli-command", + "CLI": "https://docs.prowler.com/checks/public_8#cli-command", # NativeIaC holds the native IaC code to remediate it, use "https://docs.bridgecrew.io/docs" "NativeIaC": "", # Other holds the other commands, scripts or code to remediate it, use "https://www.trendmicro.com/cloudoneconformity" - "Other": "https://docs.bridgecrew.io/docs/public_8#aws-console", + "Other": "https://docs.prowler.com/checks/public_8#aws-console", # Terraform holds the Terraform code to remediate it, use "https://docs.bridgecrew.io/docs" "Terraform": "" }, diff --git a/docs/developer-guide/services.md b/docs/developer-guide/services.md index 1272f02b4a..0a9c9a3020 100644 --- a/docs/developer-guide/services.md +++ b/docs/developer-guide/services.md @@ -175,6 +175,8 @@ class (ServiceParentClass): f"{.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) ``` +???+note + To avoid fake findings, when Prowler can't retrieve the items, because an Access Denied or similar error, we set that items value as `None`. ### Service Models diff --git a/docs/developer-guide/unit-testing.md b/docs/developer-guide/unit-testing.md index b33f13f5b4..0914e1b3cc 100644 --- a/docs/developer-guide/unit-testing.md +++ b/docs/developer-guide/unit-testing.md @@ -509,7 +509,113 @@ class Test_compute_firewall_rdp_access_from_the_internet_allowed: ### Services -Coming soon ... +For testing Google Cloud Services, we have to follow the same logic as with the Google Cloud checks. We still mocking all API calls, but in this case, every API call to set up an attribute is defined in [fixtures file](https://github.com/prowler-cloud/prowler/blob/master/tests/providers/gcp/gcp_fixtures.py) in `mock_api_client` function. Remember that EVERY method of a service must be tested. + +The following code shows a real example of a testing class, but it has more comments than usual for educational purposes. + +```python title="BigQuery Service Test" +# We need to import the unittest.mock.patch to allow us to patch some objects +# not to use shared ones between test, hence to isolate the test +from unittest.mock import patch +# Import the class needed from the service file +from prowler.providers.gcp.services.bigquery.bigquery_service import BigQuery +# Necessary constans and functions from fixtures file +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestBigQueryService: + # Only method needed to test full service + def test_service(self): + # In this case we are mocking the __is_api_active__ to ensure our mocked project is used + # And all the client to use our mocked API calls + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + # Instantiate an object of class with the mocked provider + bigquery_client = BigQuery( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + # Check all attributes of the tested class is well set up according API calls mocked from GCP fixture file + assert bigquery_client.service == "bigquery" + assert bigquery_client.project_ids == [GCP_PROJECT_ID] + + assert len(bigquery_client.datasets) == 2 + + assert bigquery_client.datasets[0].name == "unique_dataset1_name" + assert bigquery_client.datasets[0].id.__class__.__name__ == "str" + assert bigquery_client.datasets[0].region == "US" + assert bigquery_client.datasets[0].cmk_encryption + assert bigquery_client.datasets[0].public + assert bigquery_client.datasets[0].project_id == GCP_PROJECT_ID + + assert bigquery_client.datasets[1].name == "unique_dataset2_name" + assert bigquery_client.datasets[1].id.__class__.__name__ == "str" + assert bigquery_client.datasets[1].region == "EU" + assert not bigquery_client.datasets[1].cmk_encryption + assert not bigquery_client.datasets[1].public + assert bigquery_client.datasets[1].project_id == GCP_PROJECT_ID + + assert len(bigquery_client.tables) == 2 + + assert bigquery_client.tables[0].name == "unique_table1_name" + assert bigquery_client.tables[0].id.__class__.__name__ == "str" + assert bigquery_client.tables[0].region == "US" + assert bigquery_client.tables[0].cmk_encryption + assert bigquery_client.tables[0].project_id == GCP_PROJECT_ID + + assert bigquery_client.tables[1].name == "unique_table2_name" + assert bigquery_client.tables[1].id.__class__.__name__ == "str" + assert bigquery_client.tables[1].region == "US" + assert not bigquery_client.tables[1].cmk_encryption + assert bigquery_client.tables[1].project_id == GCP_PROJECT_ID +``` +As it can be confusing where all these values come from, I'll give an example to make this clearer. First we need to check +what is the API call used to obtain the datasets. In this case if we check the service the call is +`self.client.datasets().list(projectId=project_id)`. + +Now in the fixture file we have to mock this call in our `MagicMock` client in the function `mock_api_client`. The best way to mock +is following the actual format, add one function where the client is passed to be changed, the format of this function name must be +`mock_api__calls` (*endpoint* refers to the first attribute pointed after *client*). + +In the example of BigQuery the function is called `mock_api_dataset_calls`. And inside of this function we found an assignation to +be used in the `__get_datasets__` method in BigQuery class: + +```python +# Mocking datasets +dataset1_id = str(uuid4()) +dataset2_id = str(uuid4()) + +client.datasets().list().execute.return_value = { + "datasets": [ + { + "datasetReference": { + "datasetId": "unique_dataset1_name", + "projectId": GCP_PROJECT_ID, + }, + "id": dataset1_id, + "location": "US", + }, + { + "datasetReference": { + "datasetId": "unique_dataset2_name", + "projectId": GCP_PROJECT_ID, + }, + "id": dataset2_id, + "location": "EU", + }, + ] +} +``` + ## Azure diff --git a/prowler/lib/outputs/summary_table.py b/prowler/lib/outputs/summary_table.py index 5201d7c3ef..3d5c97a25d 100644 --- a/prowler/lib/outputs/summary_table.py +++ b/prowler/lib/outputs/summary_table.py @@ -45,6 +45,7 @@ def display_summary_table( "Service": "", "Provider": "", "Total": 0, + "Pass": 0, "Critical": 0, "High": 0, "Medium": 0, @@ -78,6 +79,7 @@ def display_summary_table( current["Total"] += 1 if finding.status == "PASS": pass_count += 1 + current["Pass"] += 1 elif finding.status == "FAIL": fail_count += 1 if finding.check_metadata.Severity == "critical": @@ -157,7 +159,8 @@ def add_service_to_table(findings_table, current): ) current["Status"] = f"{Fore.RED}FAIL ({total_fails}){Style.RESET_ALL}" else: - current["Status"] = f"{Fore.GREEN}PASS ({current['Total']}){Style.RESET_ALL}" + current["Status"] = f"{Fore.GREEN}PASS ({current['Pass']}){Style.RESET_ALL}" + findings_table["Provider"].append(current["Provider"]) findings_table["Service"].append(current["Service"]) findings_table["Status"].append(current["Status"]) diff --git a/prowler/providers/aws/aws_regions_by_service.json b/prowler/providers/aws/aws_regions_by_service.json index d8420080ba..b4881ca24e 100644 --- a/prowler/providers/aws/aws_regions_by_service.json +++ b/prowler/providers/aws/aws_regions_by_service.json @@ -1253,9 +1253,11 @@ "regions": { "aws": [ "ap-northeast-1", + "ap-south-1", "ap-southeast-1", "ap-southeast-2", "eu-central-1", + "eu-west-1", "eu-west-3", "us-east-1", "us-west-2" @@ -1278,6 +1280,7 @@ "braket": { "regions": { "aws": [ + "eu-west-2", "us-east-1", "us-west-1", "us-west-2" @@ -1292,6 +1295,7 @@ "ap-northeast-1", "ap-northeast-2", "ap-south-1", + "ap-southeast-1", "ap-southeast-2", "ca-central-1", "eu-central-1", @@ -2619,6 +2623,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -4253,6 +4258,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -4374,6 +4380,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -4416,6 +4423,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -4458,6 +4466,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -4499,6 +4508,7 @@ "ap-southeast-2", "ap-southeast-3", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -4541,6 +4551,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -4651,6 +4662,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -6167,7 +6179,10 @@ "us-west-2" ], "aws-cn": [], - "aws-us-gov": [] + "aws-us-gov": [ + "us-gov-east-1", + "us-gov-west-1" + ] } }, "lightsail": { @@ -7946,6 +7961,16 @@ "aws-us-gov": [] } }, + "qbusiness": { + "regions": { + "aws": [ + "us-east-1", + "us-west-2" + ], + "aws-cn": [], + "aws-us-gov": [] + } + }, "qldb": { "regions": { "aws": [ @@ -8668,16 +8693,21 @@ "ap-northeast-2", "ap-northeast-3", "ap-south-1", + "ap-south-2", "ap-southeast-1", "ap-southeast-2", "ap-southeast-3", + "ap-southeast-4", "ca-central-1", "eu-central-1", + "eu-central-2", "eu-north-1", "eu-south-1", + "eu-south-2", "eu-west-1", "eu-west-2", "eu-west-3", + "me-central-1", "me-south-1", "sa-east-1", "us-east-1", @@ -9614,6 +9644,7 @@ "eu-west-1", "eu-west-2", "eu-west-3", + "il-central-1", "me-central-1", "sa-east-1", "us-east-1", @@ -9654,21 +9685,6 @@ "aws-us-gov": [] } }, - "snowmobile": { - "regions": { - "aws": [ - "us-east-1", - "us-east-2", - "us-west-1", - "us-west-2" - ], - "aws-cn": [], - "aws-us-gov": [ - "us-gov-east-1", - "us-gov-west-1" - ] - } - }, "sns": { "regions": { "aws": [ @@ -10343,6 +10359,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -10720,6 +10737,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", @@ -10804,6 +10822,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", diff --git a/prowler/providers/aws/services/account/account_maintain_current_contact_details/account_maintain_current_contact_details.metadata.json b/prowler/providers/aws/services/account/account_maintain_current_contact_details/account_maintain_current_contact_details.metadata.json index cdf25daecc..372721948d 100644 --- a/prowler/providers/aws/services/account/account_maintain_current_contact_details/account_maintain_current_contact_details.metadata.json +++ b/prowler/providers/aws/services/account/account_maintain_current_contact_details/account_maintain_current_contact_details.metadata.json @@ -11,13 +11,13 @@ "Severity": "medium", "ResourceType": "Other", "Description": "Maintain current contact details.", - "Risk": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization. An AWS account supports a number of contact details; and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy. If an AWS account is observed to be behaving in a prohibited or suspicious manner; AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation; proactive measures may be taken; including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question.", + "Risk": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization. An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy. If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question.", "RelatedUrl": "", "Remediation": { "Code": { "CLI": "No command available.", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/iam_18-maintain-contact-details#aws-console", + "Other": "https://docs.prowler.com/checks/aws/iam-policies/iam_18-maintain-contact-details#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations.metadata.json b/prowler/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations.metadata.json index cb055b1ec5..c5a20a6a23 100644 --- a/prowler/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations.metadata.json +++ b/prowler/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations.metadata.json @@ -11,13 +11,13 @@ "Severity": "medium", "ResourceType": "Other", "Description": "Maintain different contact details to security, billing and operations.", - "Risk": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization. An AWS account supports a number of contact details; and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy. If an AWS account is observed to be behaving in a prohibited or suspicious manner; AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation; proactive measures may be taken; including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question.", + "Risk": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization. An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy. If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question.", "RelatedUrl": "https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-update-contact.html", "Remediation": { "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/iam_18-maintain-contact-details#aws-console", + "Other": "https://docs.prowler.com/checks/aws/iam-policies/iam_18-maintain-contact-details#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations.py b/prowler/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations.py index 6616755413..1a3f799dfb 100644 --- a/prowler/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations.py +++ b/prowler/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations.py @@ -6,22 +6,26 @@ class account_maintain_different_contact_details_to_security_billing_and_operati Check ): def execute(self): - report = Check_Report_AWS(self.metadata()) - report.region = account_client.region - report.resource_id = account_client.audited_account - report.resource_arn = account_client.audited_account_arn + findings = [] + if account_client.contact_base: + report = Check_Report_AWS(self.metadata()) + report.region = account_client.region + report.resource_id = account_client.audited_account + report.resource_arn = account_client.audited_account_arn - if ( - len(account_client.contact_phone_numbers) - == account_client.number_of_contacts - and len(account_client.contact_names) == account_client.number_of_contacts - # This is because the primary contact has no email field - and len(account_client.contact_emails) - == account_client.number_of_contacts - 1 - ): - report.status = "PASS" - report.status_extended = "SECURITY, BILLING and OPERATIONS contacts found and they are different between each other and between ROOT contact." - else: - report.status = "FAIL" - report.status_extended = "SECURITY, BILLING and OPERATIONS contacts not found or they are not different between each other and between ROOT contact." - return [report] + if ( + len(account_client.contact_phone_numbers) + == account_client.number_of_contacts + and len(account_client.contact_names) + == account_client.number_of_contacts + # This is because the primary contact has no email field + and len(account_client.contact_emails) + == account_client.number_of_contacts - 1 + ): + report.status = "PASS" + report.status_extended = "SECURITY, BILLING and OPERATIONS contacts found and they are different between each other and between ROOT contact." + else: + report.status = "FAIL" + report.status_extended = "SECURITY, BILLING and OPERATIONS contacts not found or they are not different between each other and between ROOT contact." + findings.append(report) + return findings diff --git a/prowler/providers/aws/services/account/account_security_contact_information_is_registered/account_security_contact_information_is_registered.metadata.json b/prowler/providers/aws/services/account/account_security_contact_information_is_registered/account_security_contact_information_is_registered.metadata.json index 7f8bd7288d..78bd76c010 100644 --- a/prowler/providers/aws/services/account/account_security_contact_information_is_registered/account_security_contact_information_is_registered.metadata.json +++ b/prowler/providers/aws/services/account/account_security_contact_information_is_registered/account_security_contact_information_is_registered.metadata.json @@ -17,7 +17,7 @@ "Code": { "CLI": "No command available.", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/iam_19#aws-console", + "Other": "https://docs.prowler.com/checks/aws/iam-policies/iam_19#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/account/account_security_questions_are_registered_in_the_aws_account/account_security_questions_are_registered_in_the_aws_account.metadata.json b/prowler/providers/aws/services/account/account_security_questions_are_registered_in_the_aws_account/account_security_questions_are_registered_in_the_aws_account.metadata.json index d8f70e4753..e10bbca9a0 100644 --- a/prowler/providers/aws/services/account/account_security_questions_are_registered_in_the_aws_account/account_security_questions_are_registered_in_the_aws_account.metadata.json +++ b/prowler/providers/aws/services/account/account_security_questions_are_registered_in_the_aws_account/account_security_questions_are_registered_in_the_aws_account.metadata.json @@ -17,7 +17,7 @@ "Code": { "CLI": "No command available.", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/iam_15", + "Other": "https://docs.prowler.com/checks/aws/iam-policies/iam_15", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/account/account_service.py b/prowler/providers/aws/services/account/account_service.py index 16331fbe8a..0048cb76b9 100644 --- a/prowler/providers/aws/services/account/account_service.py +++ b/prowler/providers/aws/services/account/account_service.py @@ -18,28 +18,29 @@ class Account(AWSService): self.contacts_security = self.__get_alternate_contact__("SECURITY") self.contacts_operations = self.__get_alternate_contact__("OPERATIONS") - # Set of contact phone numbers - self.contact_phone_numbers = { - self.contact_base.phone_number, - self.contacts_billing.phone_number, - self.contacts_security.phone_number, - self.contacts_operations.phone_number, - } + if self.contact_base: + # Set of contact phone numbers + self.contact_phone_numbers = { + self.contact_base.phone_number, + self.contacts_billing.phone_number, + self.contacts_security.phone_number, + self.contacts_operations.phone_number, + } - # Set of contact names - self.contact_names = { - self.contact_base.name, - self.contacts_billing.name, - self.contacts_security.name, - self.contacts_operations.name, - } + # Set of contact names + self.contact_names = { + self.contact_base.name, + self.contacts_billing.name, + self.contacts_security.name, + self.contacts_operations.name, + } - # Set of contact emails - self.contact_emails = { - self.contacts_billing.email, - self.contacts_security.email, - self.contacts_operations.email, - } + # Set of contact emails + self.contact_emails = { + self.contacts_billing.email, + self.contacts_security.email, + self.contacts_operations.email, + } def __get_contact_information__(self): try: @@ -53,10 +54,16 @@ class Account(AWSService): phone_number=primary_account_contact.get("PhoneNumber"), ) except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return Contact(type="PRIMARY") + if error.response["Error"]["Code"] == "AccessDeniedException": + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return None + else: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return Contact(type="PRIMARY") def __get_alternate_contact__(self, contact_type: str): try: diff --git a/prowler/providers/aws/services/acm/acm_certificates_expiration_check/acm_certificates_expiration_check.metadata.json b/prowler/providers/aws/services/acm/acm_certificates_expiration_check/acm_certificates_expiration_check.metadata.json index f2349fedc1..fb3fe1e2cd 100644 --- a/prowler/providers/aws/services/acm/acm_certificates_expiration_check/acm_certificates_expiration_check.metadata.json +++ b/prowler/providers/aws/services/acm/acm_certificates_expiration_check/acm_certificates_expiration_check.metadata.json @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Monitor certificate expiration and take automated action to renew; replace or remove. Having shorter TTL for any security artifact is a general recommendation; but requires additional automation in place. If not longer required delete certificate. Use AWS config using the managed rule: acm-certificate-expiration-check.", + "Text": "Monitor certificate expiration and take automated action to renew, replace or remove. Having shorter TTL for any security artifact is a general recommendation, but requires additional automation in place. If not longer required delete certificate. Use AWS config using the managed rule: acm-certificate-expiration-check.", "Url": "https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html" } }, diff --git a/prowler/providers/aws/services/apigateway/apigateway_restapi_authorizers_enabled/apigateway_restapi_authorizers_enabled.metadata.json b/prowler/providers/aws/services/apigateway/apigateway_restapi_authorizers_enabled/apigateway_restapi_authorizers_enabled.metadata.json index ea7cd2aec9..9d009b0dde 100644 --- a/prowler/providers/aws/services/apigateway/apigateway_restapi_authorizers_enabled/apigateway_restapi_authorizers_enabled.metadata.json +++ b/prowler/providers/aws/services/apigateway/apigateway_restapi_authorizers_enabled/apigateway_restapi_authorizers_enabled.metadata.json @@ -19,9 +19,9 @@ "Remediation": { "Code": { "CLI": "", - "NativeIaC": "https://docs.bridgecrew.io/docs/public_6-api-gateway-authorizer-set#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/public-policies/public_6-api-gateway-authorizer-set#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/public_6-api-gateway-authorizer-set#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/public-policies/public_6-api-gateway-authorizer-set#terraform" }, "Recommendation": { "Text": "Implement Amazon Cognito or a Lambda function to control access to your API.", diff --git a/prowler/providers/aws/services/apigateway/apigateway_restapi_logging_enabled/apigateway_restapi_logging_enabled.metadata.json b/prowler/providers/aws/services/apigateway/apigateway_restapi_logging_enabled/apigateway_restapi_logging_enabled.metadata.json index 7ccbf0ec5d..accc6102e0 100644 --- a/prowler/providers/aws/services/apigateway/apigateway_restapi_logging_enabled/apigateway_restapi_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/apigateway/apigateway_restapi_logging_enabled/apigateway_restapi_logging_enabled.metadata.json @@ -21,7 +21,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-api-gateway-stage-have-logging-level-defined-as-appropiate#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/ensure-api-gateway-stage-have-logging-level-defined-as-appropiate#terraform" }, "Recommendation": { "Text": "Monitoring is an important part of maintaining the reliability, availability and performance of API Gateway and your AWS solutions. You should collect monitoring data from all of the parts of your AWS solution. CloudTrail provides a record of actions taken by a user, role, or an AWS service in API Gateway. Using the information collected by CloudTrail, you can determine the request that was made to API Gateway, the IP address from which the request was made, who made the request, etc.", diff --git a/prowler/providers/aws/services/apigatewayv2/apigatewayv2_api_access_logging_enabled/apigatewayv2_api_access_logging_enabled.metadata.json b/prowler/providers/aws/services/apigatewayv2/apigatewayv2_api_access_logging_enabled/apigatewayv2_api_access_logging_enabled.metadata.json index da4337ccff..285e4f149b 100644 --- a/prowler/providers/aws/services/apigatewayv2/apigatewayv2_api_access_logging_enabled/apigatewayv2_api_access_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/apigatewayv2/apigatewayv2_api_access_logging_enabled/apigatewayv2_api_access_logging_enabled.metadata.json @@ -20,8 +20,8 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/bc_aws_logging_30#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_logging_30#cloudformation" + "Other": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_30#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_30#cloudformation" }, "Recommendation": { "Text": "Monitoring is an important part of maintaining the reliability, availability and performance of API Gateway and your AWS solutions. You should collect monitoring data from all of the parts of your AWS solution. CloudTrail provides a record of actions taken by a user, role, or an AWS service in API Gateway. Using the information collected by CloudTrail, you can determine the request that was made to API Gateway, the IP address from which the request was made, who made the request, etc.", diff --git a/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.metadata.json b/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.metadata.json index 2b1f0703c5..197ce59b67 100644 --- a/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.metadata.json +++ b/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws athena update-work-group --region --work-group --configuration-updates ResultConfigurationUpdates={EncryptionConfiguration={EncryptionOption=SSE_S3|SSE_KMS|CSE_KMS}}", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Athena/encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-athena-workgroup-is-encrypted#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-athena-workgroup-is-encrypted#terraform" }, "Recommendation": { "Text": "Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits.", diff --git a/prowler/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration.metadata.json b/prowler/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration.metadata.json index e09e0b5696..46f2e305f2 100644 --- a/prowler/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration.metadata.json +++ b/prowler/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws athena update-work-group --region --work-group --configuration-updates EnforceWorkGroupConfiguration=True", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_33#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_33#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_33#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_33#terraform" }, "Recommendation": { "Text": "Ensure that workgroup configuration is enforced so it cannot be overriden by client-side settings.", @@ -29,4 +29,4 @@ "DependsOn": [], "RelatedTo": [], "Notes": "" -} \ No newline at end of file +} diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.metadata.json b/prowler/providers/aws/services/awslambda/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.metadata.json index 40704e0170..d214d90424 100644 --- a/prowler/providers/aws/services/awslambda/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/awslambda/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.metadata.json @@ -9,7 +9,7 @@ "Severity": "low", "ResourceType": "AwsLambdaFunction", "Description": "Check if Lambda functions invoke API operations are being recorded by CloudTrail.", - "Risk": "If logs are not enabled; monitoring of service use and threat analysis is not possible.", + "Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.", "RelatedUrl": "https://docs.aws.amazon.com/lambda/latest/dg/logging-using-cloudtrail.html", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.metadata.json b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.metadata.json index ca93bfaa4e..4fd1e9dc57 100644 --- a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.metadata.json +++ b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.metadata.json @@ -9,7 +9,7 @@ "Severity": "critical", "ResourceType": "AwsLambdaFunction", "Description": "Find secrets in Lambda functions code.", - "Risk": "The use of a hard-coded password increases the possibility of password guessing. If hard-coded passwords are used; it is possible that malicious users gain access through the account in question.", + "Risk": "The use of a hard-coded password increases the possibility of password guessing. If hard-coded passwords are used, it is possible that malicious users gain access through the account in question.", "RelatedUrl": "https://docs.aws.amazon.com/secretsmanager/latest/userguide/lambda-functions.html", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.metadata.json b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.metadata.json index 8822d7dafa..39365275f1 100644 --- a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.metadata.json +++ b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.metadata.json @@ -9,14 +9,14 @@ "Severity": "critical", "ResourceType": "AwsLambdaFunction", "Description": "Find secrets in Lambda functions variables.", - "Risk": "The use of a hard-coded password increases the possibility of password guessing. If hard-coded passwords are used; it is possible that malicious users gain access through the account in question.", + "Risk": "The use of a hard-coded password increases the possibility of password guessing. If hard-coded passwords are used, it is possible that malicious users gain access through the account in question.", "RelatedUrl": "https://docs.aws.amazon.com/secretsmanager/latest/userguide/lambda-functions.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_aws_secrets_3#cli-command", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_secrets_3#cloudformation", + "CLI": "https://docs.prowler.com/checks/aws/secrets-policies/bc_aws_secrets_3#cli-command", + "NativeIaC": "https://docs.prowler.com/checks/aws/secrets-policies/bc_aws_secrets_3#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_secrets_3#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/secrets-policies/bc_aws_secrets_3#terraform" }, "Recommendation": { "Text": "Use Secrets Manager to securely provide database credentials to Lambda functions and secure the databases as well as use the credentials to connect and query them without hardcoding the secrets in code or passing them through environmental variables.", diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.metadata.json b/prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.metadata.json index cada4948be..b8a1c5a013 100644 --- a/prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.metadata.json +++ b/prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.metadata.json @@ -9,7 +9,7 @@ "Severity": "medium", "ResourceType": "AwsLambdaFunction", "Description": "Find obsolete Lambda runtimes.", - "Risk": "If you have functions running on a runtime that will be deprecated in the next 60 days; Lambda notifies you by email that you should prepare by migrating your function to a supported runtime. In some cases; such as security issues that require a backwards-incompatible update; or software that does not support a long-term support (LTS) schedule; advance notice might not be possible. After a runtime is deprecated; Lambda might retire it completely at any time by disabling invocation. Deprecated runtimes are not eligible for security updates or technical support.", + "Risk": "If you have functions running on a runtime that will be deprecated in the next 60 days, Lambda notifies you by email that you should prepare by migrating your function to a supported runtime. In some cases, such as security issues that require a backwards-incompatible update, or software that does not support a long-term support (LTS) schedule, advance notice might not be possible. After a runtime is deprecated, Lambda might retire it completely at any time by disabling invocation. Deprecated runtimes are not eligible for security updates or technical support.", "RelatedUrl": "https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/backup/backup_service.py b/prowler/providers/aws/services/backup/backup_service.py index 6be3f9ac28..e05d65ddce 100644 --- a/prowler/providers/aws/services/backup/backup_service.py +++ b/prowler/providers/aws/services/backup/backup_service.py @@ -1,6 +1,7 @@ from datetime import datetime from typing import Optional +from botocore.client import ClientError from pydantic import BaseModel from prowler.lib.logger import logger @@ -37,6 +38,8 @@ class Backup(AWSService): self.audit_resources, ) ): + if self.backup_vaults is None: + self.backup_vaults = [] self.backup_vaults.append( BackupVault( arn=configuration.get("BackupVaultArn"), @@ -55,7 +58,13 @@ class Backup(AWSService): ), ) ) - + except ClientError as error: + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + if error.response["Error"]["Code"] == "AccessDeniedException": + if not self.backup_vaults: + self.backup_vaults = None except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" diff --git a/prowler/providers/aws/services/backup/backup_vaults_encrypted/backup_vaults_encrypted.py b/prowler/providers/aws/services/backup/backup_vaults_encrypted/backup_vaults_encrypted.py index 7ccc7162fb..c9f909170d 100644 --- a/prowler/providers/aws/services/backup/backup_vaults_encrypted/backup_vaults_encrypted.py +++ b/prowler/providers/aws/services/backup/backup_vaults_encrypted/backup_vaults_encrypted.py @@ -5,24 +5,24 @@ from prowler.providers.aws.services.backup.backup_client import backup_client class backup_vaults_encrypted(Check): def execute(self): findings = [] - - for backup_vault in backup_client.backup_vaults: - # By default we assume that the result is fail - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - f"Backup Vault {backup_vault.name} is not encrypted." - ) - report.resource_arn = backup_vault.arn - report.resource_id = backup_vault.name - report.region = backup_vault.region - # if it is encrypted we only change the status and the status extended - if backup_vault.encryption: - report.status = "PASS" + if backup_client.backup_vaults: + for backup_vault in backup_client.backup_vaults: + # By default we assume that the result is fail + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" report.status_extended = ( - f"Backup Vault {backup_vault.name} is encrypted." + f"Backup Vault {backup_vault.name} is not encrypted." ) - # then we store the finding - findings.append(report) + report.resource_arn = backup_vault.arn + report.resource_id = backup_vault.name + report.region = backup_vault.region + # if it is encrypted we only change the status and the status extended + if backup_vault.encryption: + report.status = "PASS" + report.status_extended = ( + f"Backup Vault {backup_vault.name} is encrypted." + ) + # then we store the finding + findings.append(report) return findings diff --git a/prowler/providers/aws/services/backup/backup_vaults_exist/backup_vaults_exist.py b/prowler/providers/aws/services/backup/backup_vaults_exist/backup_vaults_exist.py index 0c50e63525..c05e9c5ab1 100644 --- a/prowler/providers/aws/services/backup/backup_vaults_exist/backup_vaults_exist.py +++ b/prowler/providers/aws/services/backup/backup_vaults_exist/backup_vaults_exist.py @@ -5,18 +5,19 @@ from prowler.providers.aws.services.backup.backup_client import backup_client class backup_vaults_exist(Check): def execute(self): findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = "No Backup Vault exist." - report.resource_arn = backup_client.backup_vault_arn_template - report.resource_id = backup_client.audited_account - report.region = backup_client.region - if backup_client.backup_vaults: - report.status = "PASS" - report.status_extended = f"At least one backup vault exists: {backup_client.backup_vaults[0].name}." - report.resource_arn = backup_client.backup_vaults[0].arn - report.resource_id = backup_client.backup_vaults[0].name - report.region = backup_client.backup_vaults[0].region + if backup_client.backup_vaults is not None: + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No Backup Vault exist." + report.resource_arn = backup_client.backup_vault_arn_template + report.resource_id = backup_client.audited_account + report.region = backup_client.region + if backup_client.backup_vaults: + report.status = "PASS" + report.status_extended = f"At least one backup vault exists: {backup_client.backup_vaults[0].name}." + report.resource_arn = backup_client.backup_vaults[0].arn + report.resource_id = backup_client.backup_vaults[0].name + report.region = backup_client.backup_vaults[0].region - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudformation/cloudformation_stack_outputs_find_secrets/cloudformation_stack_outputs_find_secrets.metadata.json b/prowler/providers/aws/services/cloudformation/cloudformation_stack_outputs_find_secrets/cloudformation_stack_outputs_find_secrets.metadata.json index d8cde7d3fd..235b3480d6 100644 --- a/prowler/providers/aws/services/cloudformation/cloudformation_stack_outputs_find_secrets/cloudformation_stack_outputs_find_secrets.metadata.json +++ b/prowler/providers/aws/services/cloudformation/cloudformation_stack_outputs_find_secrets/cloudformation_stack_outputs_find_secrets.metadata.json @@ -13,7 +13,7 @@ "RelatedUrl": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-secretsmanager-secret-generatesecretstring.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_aws_secrets_2#cli-command", + "CLI": "https://docs.prowler.com/checks/aws/secrets-policies/bc_aws_secrets_2#cli-command", "NativeIaC": "", "Other": "", "Terraform": "" diff --git a/prowler/providers/aws/services/cloudformation/cloudformation_stacks_termination_protection_enabled/cloudformation_stacks_termination_protection_enabled.metadata.json b/prowler/providers/aws/services/cloudformation/cloudformation_stacks_termination_protection_enabled/cloudformation_stacks_termination_protection_enabled.metadata.json index 2d59e74801..03011fc315 100644 --- a/prowler/providers/aws/services/cloudformation/cloudformation_stacks_termination_protection_enabled/cloudformation_stacks_termination_protection_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudformation/cloudformation_stacks_termination_protection_enabled/cloudformation_stacks_termination_protection_enabled.metadata.json @@ -9,7 +9,7 @@ "Severity": "medium", "ResourceType": "AwsCloudFormationStack", "Description": "Enable termination protection for Cloudformation Stacks", - "Risk": "Without termination protection enabled; a critical cloudformation stack can be accidently deleted.", + "Risk": "Without termination protection enabled, a critical cloudformation stack can be accidently deleted.", "RelatedUrl": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-protect-stacks.html", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_geo_restrictions_enabled/cloudfront_distributions_geo_restrictions_enabled.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_geo_restrictions_enabled/cloudfront_distributions_geo_restrictions_enabled.metadata.json index 111a7062bb..f04ec3ba3f 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_geo_restrictions_enabled/cloudfront_distributions_geo_restrictions_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_geo_restrictions_enabled/cloudfront_distributions_geo_restrictions_enabled.metadata.json @@ -9,7 +9,7 @@ "Severity": "low", "ResourceType": "AwsCloudFrontDistribution", "Description": "Check if Geo restrictions are enabled in CloudFront distributions.", - "Risk": "Consider countries where service should not be accessed; by legal or compliance requirements. Additionally if not restricted the attack vector is increased.", + "Risk": "Consider countries where service should not be accessed, by legal or compliance requirements. Additionally if not restricted the attack vector is increased.", "RelatedUrl": "https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/georestrictions.html", "Remediation": { "Code": { @@ -19,7 +19,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "If possible; define and enable Geo restrictions for this service.", + "Text": "If possible, define and enable Geo restrictions for this service.", "Url": "https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/georestrictions.html" } }, diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_https_enabled/cloudfront_distributions_https_enabled.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_https_enabled/cloudfront_distributions_https_enabled.metadata.json index 12d9d89855..fe73aa0c95 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_https_enabled/cloudfront_distributions_https_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_https_enabled/cloudfront_distributions_https_enabled.metadata.json @@ -14,9 +14,9 @@ "Remediation": { "Code": { "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudFront/security-policy.html", - "NativeIaC": "https://docs.bridgecrew.io/docs/networking_32#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/networking-policies/networking_32#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/networking_32#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/networking_32#terraform" }, "Recommendation": { "Text": "Use HTTPS everywhere possible. It will enforce privacy and protect against account hijacking and other threats.", diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_logging_enabled/cloudfront_distributions_logging_enabled.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_logging_enabled/cloudfront_distributions_logging_enabled.metadata.json index c5d5ce399c..c8e52e9f47 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_logging_enabled/cloudfront_distributions_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_logging_enabled/cloudfront_distributions_logging_enabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/logging_20#cli-command", - "NativeIaC": "https://docs.bridgecrew.io/docs/logging_20#cloudformation", + "CLI": "https://docs.prowler.com/checks/aws/logging-policies/logging_20#cli-command", + "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_20#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/logging_20#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_20#terraform" }, "Recommendation": { "Text": "Real-time monitoring can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Enable logging for services with defined log rotation. These logs are useful for Incident Response and forensics investigation among other use cases.", diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_deprecated_ssl_protocols/cloudfront_distributions_using_deprecated_ssl_protocols.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_deprecated_ssl_protocols/cloudfront_distributions_using_deprecated_ssl_protocols.metadata.json index 11a4b7d3c9..09e812dffb 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_deprecated_ssl_protocols/cloudfront_distributions_using_deprecated_ssl_protocols.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_deprecated_ssl_protocols/cloudfront_distributions_using_deprecated_ssl_protocols.metadata.json @@ -13,9 +13,9 @@ "RelatedUrl": "https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/secure-connections-supported-viewer-protocols-ciphers.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/networking_33#cli-command", + "CLI": "https://docs.prowler.com/checks/aws/networking-policies/networking_33#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/networking_33#aws-cloudfront-console", + "Other": "https://docs.prowler.com/checks/aws/networking-policies/networking_33#aws-cloudfront-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_waf/cloudfront_distributions_using_waf.metadata.json b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_waf/cloudfront_distributions_using_waf.metadata.json index 7b9c23efdf..70aa528347 100644 --- a/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_waf/cloudfront_distributions_using_waf.metadata.json +++ b/prowler/providers/aws/services/cloudfront/cloudfront_distributions_using_waf/cloudfront_distributions_using_waf.metadata.json @@ -11,17 +11,17 @@ "Severity": "medium", "ResourceType": "AwsCloudFrontDistribution", "Description": "Check if CloudFront distributions are using WAF.", - "Risk": "Potential attacks and / or abuse of service; more even for even for internet reachable services.", + "Risk": "Potential attacks and / or abuse of service, more even for even for internet reachable services.", "RelatedUrl": "https://docs.aws.amazon.com/waf/latest/developerguide/cloudfront-features.html", "Remediation": { "Code": { "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudFront/cloudfront-integrated-with-waf.html", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_27#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/bc_aws_general_27#cloudfront-console", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_27#terraform" + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_27#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_27#cloudfront-console", + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_27#terraform" }, "Recommendation": { - "Text": "Use AWS WAF to protect your service from common web exploits. These could affect availability and performance; compromise security; or consume excessive resources.", + "Text": "Use AWS WAF to protect your service from common web exploits. These could affect availability and performance, compromise security, or consume excessive resources.", "Url": "https://docs.aws.amazon.com/waf/latest/developerguide/cloudfront-features.html" } }, diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.py index 9cf039dcd5..8feec3de79 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.py @@ -8,28 +8,29 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class cloudtrail_bucket_requires_mfa_delete(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - if trail.is_logging: - trail_bucket_is_in_account = False - trail_bucket = trail.s3_bucket - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "FAIL" - report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) does not have MFA delete enabled." - for bucket in s3_client.buckets: - if trail_bucket == bucket.name: - trail_bucket_is_in_account = True - if bucket.mfa_delete: - report.status = "PASS" - report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) has MFA delete enabled." - # check if trail bucket is a cross account bucket - if not trail_bucket_is_in_account: - report.status = "INFO" - report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) is a cross-account bucket in another account out of Prowler's permissions scope, please check it manually." + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + if trail.is_logging: + trail_bucket_is_in_account = False + trail_bucket = trail.s3_bucket + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "FAIL" + report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) does not have MFA delete enabled." + for bucket in s3_client.buckets: + if trail_bucket == bucket.name: + trail_bucket_is_in_account = True + if bucket.mfa_delete: + report.status = "PASS" + report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) has MFA delete enabled." + # check if trail bucket is a cross account bucket + if not trail_bucket_is_in_account: + report.status = "INFO" + report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) is a cross-account bucket in another account out of Prowler's permissions scope, please check it manually." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.metadata.json index 279e272b33..046ed10af7 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.metadata.json @@ -13,13 +13,13 @@ "Severity": "low", "ResourceType": "AwsCloudTrailTrail", "Description": "Ensure CloudTrail trails are integrated with CloudWatch Logs", - "Risk": "Sending CloudTrail logs to CloudWatch Logs will facilitate real-time and historic activity logging based on user; API; resource; and IP address; and provides opportunity to establish alarms and notifications for anomalous or sensitivity account activity.", + "Risk": "Sending CloudTrail logs to CloudWatch Logs will facilitate real-time and historic activity logging based on user, API, resource, and IP address, and provides opportunity to establish alarms and notifications for anomalous or sensitivity account activity.", "RelatedUrl": "", "Remediation": { "Code": { "CLI": "aws cloudtrail update-trail --name --cloudwatch-logs-log-group- arn --cloudwatch-logs-role-arn ", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/logging_4#aws-console", + "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_4#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.py index 94c7381c9e..6d502d0884 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.py @@ -11,37 +11,38 @@ maximum_time_without_logging = 1 class cloudtrail_cloudwatch_logging_enabled(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - if trail.name: - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "PASS" - if trail.is_multiregion: - report.status_extended = ( - f"Multiregion trail {trail.name} has been logging the last 24h." - ) - else: - report.status_extended = f"Single region trail {trail.name} has been logging the last 24h." - if trail.latest_cloudwatch_delivery_time: - last_log_delivery = ( - datetime.now().replace(tzinfo=timezone.utc) - - trail.latest_cloudwatch_delivery_time - ) - if last_log_delivery > timedelta(days=maximum_time_without_logging): + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + if trail.name: + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "PASS" + if trail.is_multiregion: + report.status_extended = f"Multiregion trail {trail.name} has been logging the last 24h." + else: + report.status_extended = f"Single region trail {trail.name} has been logging the last 24h." + if trail.latest_cloudwatch_delivery_time: + last_log_delivery = ( + datetime.now().replace(tzinfo=timezone.utc) + - trail.latest_cloudwatch_delivery_time + ) + if last_log_delivery > timedelta( + days=maximum_time_without_logging + ): + report.status = "FAIL" + if trail.is_multiregion: + report.status_extended = f"Multiregion trail {trail.name} is not logging in the last 24h." + else: + report.status_extended = f"Single region trail {trail.name} is not logging in the last 24h." + else: report.status = "FAIL" if trail.is_multiregion: - report.status_extended = f"Multiregion trail {trail.name} is not logging in the last 24h." + report.status_extended = f"Multiregion trail {trail.name} is not logging in the last 24h or not configured to deliver logs." else: - report.status_extended = f"Single region trail {trail.name} is not logging in the last 24h." - else: - report.status = "FAIL" - if trail.is_multiregion: - report.status_extended = f"Multiregion trail {trail.name} is not logging in the last 24h or not configured to deliver logs." - else: - report.status_extended = f"Single region trail {trail.name} is not logging in the last 24h or not configured to deliver logs." - findings.append(report) + report.status_extended = f"Single region trail {trail.name} is not logging in the last 24h or not configured to deliver logs." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist.py index a175c4fa1f..c24aaa2c26 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist.py @@ -7,19 +7,18 @@ from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( class cloudtrail_insights_exist(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - if trail.is_logging: - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "FAIL" - report.status_extended = f"Trail {trail.name} does not have insight selectors and it is logging." - if trail.has_insight_selectors: - report.status = "PASS" - report.status_extended = ( - f"Trail {trail.name} has insight selectors and it is logging." - ) - findings.append(report) + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + if trail.is_logging: + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "FAIL" + report.status_extended = f"Trail {trail.name} does not have insight selectors and it is logging." + if trail.has_insight_selectors: + report.status = "PASS" + report.status_extended = f"Trail {trail.name} has insight selectors and it is logging." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.metadata.json index 9345e3a769..d20a08ad78 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.metadata.json @@ -13,12 +13,12 @@ "Severity": "medium", "ResourceType": "AwsCloudTrailTrail", "Description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs", - "Risk": "By default; the log files delivered by CloudTrail to your bucket are encrypted by Amazon server-side encryption with Amazon S3-managed encryption keys (SSE-S3). To provide a security layer that is directly manageable; you can instead use server-side encryption with AWS KMS–managed keys (SSE-KMS) for your CloudTrail log files.", + "Risk": "By default, the log files delivered by CloudTrail to your bucket are encrypted by Amazon server-side encryption with Amazon S3-managed encryption keys (SSE-S3). To provide a security layer that is directly manageable, you can instead use server-side encryption with AWS KMS–managed keys (SSE-KMS) for your CloudTrail log files.", "RelatedUrl": "", "Remediation": { "Code": { "CLI": "aws cloudtrail update-trail --name --kms-id aws kms put-key-policy --key-id --policy ", - "NativeIaC": "https://docs.bridgecrew.io/docs/logging_7#fix---buildtime", + "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_7#fix---buildtime", "Other": "", "Terraform": "" }, diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.py index 68b4b0c7d5..85fb994541 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.py @@ -7,32 +7,29 @@ from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( class cloudtrail_kms_encryption_enabled(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - if trail.name: - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "FAIL" - if trail.is_multiregion: - report.status_extended = ( - f"Multiregion trail {trail.name} has encryption disabled." - ) - else: - report.status_extended = ( - f"Single region trail {trail.name} has encryption disabled." - ) - if trail.kms_key: - report.status = "PASS" + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + if trail.name: + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "FAIL" if trail.is_multiregion: report.status_extended = ( - f"Multiregion trail {trail.name} has encryption enabled." + f"Multiregion trail {trail.name} has encryption disabled." ) else: report.status_extended = ( - f"Single region trail {trail.name} has encryption enabled." + f"Single region trail {trail.name} has encryption disabled." ) - findings.append(report) + if trail.kms_key: + report.status = "PASS" + if trail.is_multiregion: + report.status_extended = f"Multiregion trail {trail.name} has encryption enabled." + else: + report.status_extended = f"Single region trail {trail.name} has encryption enabled." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.metadata.json index 8f47e72ea7..95e0fdd478 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.metadata.json @@ -18,9 +18,9 @@ "Remediation": { "Code": { "CLI": "aws cloudtrail update-trail --name --enable-log-file-validation", - "NativeIaC": "https://docs.bridgecrew.io/docs/logging_2#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_2#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/logging_2#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_2#terraform" }, "Recommendation": { "Text": "Ensure LogFileValidationEnabled is set to true for each trail.", diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.py index f7aa0fbf75..a2d6c6fee3 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.py @@ -7,26 +7,25 @@ from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( class cloudtrail_log_file_validation_enabled(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - if trail.name: - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "FAIL" - if trail.is_multiregion: - report.status_extended = ( - f"Multiregion trail {trail.name} log file validation disabled." - ) - else: - report.status_extended = f"Single region trail {trail.name} log file validation disabled." - if trail.log_file_validation_enabled: - report.status = "PASS" + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + if trail.name: + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "FAIL" if trail.is_multiregion: - report.status_extended = f"Multiregion trail {trail.name} log file validation enabled." + report.status_extended = f"Multiregion trail {trail.name} log file validation disabled." else: - report.status_extended = f"Single region trail {trail.name} log file validation enabled." - findings.append(report) + report.status_extended = f"Single region trail {trail.name} log file validation disabled." + if trail.log_file_validation_enabled: + report.status = "PASS" + if trail.is_multiregion: + report.status_extended = f"Multiregion trail {trail.name} log file validation enabled." + else: + report.status_extended = f"Single region trail {trail.name} log file validation enabled." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.metadata.json index bf916fee94..1dba458d47 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.metadata.json @@ -13,17 +13,17 @@ "Severity": "medium", "ResourceType": "AwsCloudTrailTrail", "Description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket", - "Risk": "Server access logs can assist you in security and access audits; help you learn about your customer base; and understand your Amazon S3 bill.", + "Risk": "Server access logs can assist you in security and access audits, help you learn about your customer base, and understand your Amazon S3 bill.", "RelatedUrl": "", "Remediation": { "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/logging_6#aws-console", + "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_6#aws-console", "Terraform": "" }, "Recommendation": { - "Text": "Ensure that S3 buckets have Logging enabled. CloudTrail data events can be used in place of S3 bucket logging. If that is the case; this finding can be considered a false positive.", + "Text": "Ensure that S3 buckets have Logging enabled. CloudTrail data events can be used in place of S3 bucket logging. If that is the case, this finding can be considered a false positive.", "Url": "https://docs.aws.amazon.com/AmazonS3/latest/dev/security-best-practices.html" } }, diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.py index 801f8f54e6..0f2c0643f9 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.py @@ -8,35 +8,36 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class cloudtrail_logs_s3_bucket_access_logging_enabled(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - if trail.name: - trail_bucket_is_in_account = False - trail_bucket = trail.s3_bucket - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "FAIL" - if trail.is_multiregion: - report.status_extended = f"Multiregion Trail {trail.name} S3 bucket access logging is not enabled for bucket {trail_bucket}." - else: - report.status_extended = f"Single region Trail {trail.name} S3 bucket access logging is not enabled for bucket {trail_bucket}." - for bucket in s3_client.buckets: - if trail_bucket == bucket.name: - trail_bucket_is_in_account = True - if bucket.logging: - report.status = "PASS" - if trail.is_multiregion: - report.status_extended = f"Multiregion trail {trail.name} S3 bucket access logging is enabled for bucket {trail_bucket}." - else: - report.status_extended = f"Single region trail {trail.name} S3 bucket access logging is enabled for bucket {trail_bucket}." - break + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + if trail.name: + trail_bucket_is_in_account = False + trail_bucket = trail.s3_bucket + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "FAIL" + if trail.is_multiregion: + report.status_extended = f"Multiregion Trail {trail.name} S3 bucket access logging is not enabled for bucket {trail_bucket}." + else: + report.status_extended = f"Single region Trail {trail.name} S3 bucket access logging is not enabled for bucket {trail_bucket}." + for bucket in s3_client.buckets: + if trail_bucket == bucket.name: + trail_bucket_is_in_account = True + if bucket.logging: + report.status = "PASS" + if trail.is_multiregion: + report.status_extended = f"Multiregion trail {trail.name} S3 bucket access logging is enabled for bucket {trail_bucket}." + else: + report.status_extended = f"Single region trail {trail.name} S3 bucket access logging is enabled for bucket {trail_bucket}." + break - # check if trail is delivering logs in a cross account bucket - if not trail_bucket_is_in_account: - report.status = "INFO" - report.status_extended = f"Trail {trail.name} is delivering logs in a cross-account bucket {trail_bucket} in another account out of Prowler's permissions scope, please check it manually." - findings.append(report) + # check if trail is delivering logs in a cross account bucket + if not trail_bucket_is_in_account: + report.status = "INFO" + report.status_extended = f"Trail {trail.name} is delivering logs in a cross-account bucket {trail_bucket} in another account out of Prowler's permissions scope, please check it manually." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.metadata.json index 3b5440558c..fe3af7114d 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.metadata.json @@ -19,7 +19,7 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/logging_3#aws-console", + "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_3#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.py index 82465e1427..ef503f8f94 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.py @@ -8,41 +8,42 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class cloudtrail_logs_s3_bucket_is_not_publicly_accessible(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - if trail.name: - trail_bucket_is_in_account = False - trail_bucket = trail.s3_bucket - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "PASS" - if trail.is_multiregion: - report.status_extended = f"S3 Bucket {trail_bucket} from multiregion trail {trail.name} is not publicly accessible." - else: - report.status_extended = f"S3 Bucket {trail_bucket} from single region trail {trail.name} is not publicly accessible." - for bucket in s3_client.buckets: - # Here we need to ensure that acl_grantee is filled since if we don't have permissions to query the api for a concrete region - # (for example due to a SCP) we are going to try access an attribute from a None type - if trail_bucket == bucket.name: - trail_bucket_is_in_account = True - if bucket.acl_grantees: - for grant in bucket.acl_grantees: - if ( - grant.URI - == "http://acs.amazonaws.com/groups/global/AllUsers" - ): - report.status = "FAIL" - if trail.is_multiregion: - report.status_extended = f"S3 Bucket {trail_bucket} from multiregion trail {trail.name} is publicly accessible." - else: - report.status_extended = f"S3 Bucket {trail_bucket} from single region trail {trail.name} is publicly accessible." - break - # check if trail bucket is a cross account bucket - if not trail_bucket_is_in_account: - report.status = "INFO" - report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) is a cross-account bucket in another account out of Prowler's permissions scope, please check it manually." - findings.append(report) + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + if trail.name: + trail_bucket_is_in_account = False + trail_bucket = trail.s3_bucket + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "PASS" + if trail.is_multiregion: + report.status_extended = f"S3 Bucket {trail_bucket} from multiregion trail {trail.name} is not publicly accessible." + else: + report.status_extended = f"S3 Bucket {trail_bucket} from single region trail {trail.name} is not publicly accessible." + for bucket in s3_client.buckets: + # Here we need to ensure that acl_grantee is filled since if we don't have permissions to query the api for a concrete region + # (for example due to a SCP) we are going to try access an attribute from a None type + if trail_bucket == bucket.name: + trail_bucket_is_in_account = True + if bucket.acl_grantees: + for grant in bucket.acl_grantees: + if ( + grant.URI + == "http://acs.amazonaws.com/groups/global/AllUsers" + ): + report.status = "FAIL" + if trail.is_multiregion: + report.status_extended = f"S3 Bucket {trail_bucket} from multiregion trail {trail.name} is publicly accessible." + else: + report.status_extended = f"S3 Bucket {trail_bucket} from single region trail {trail.name} is publicly accessible." + break + # check if trail bucket is a cross account bucket + if not trail_bucket_is_in_account: + report.status = "INFO" + report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) is a cross-account bucket in another account out of Prowler's permissions scope, please check it manually." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.metadata.json index 285568750b..4ec89226eb 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.metadata.json @@ -13,14 +13,14 @@ "Severity": "high", "ResourceType": "AwsCloudTrailTrail", "Description": "Ensure CloudTrail is enabled in all regions", - "Risk": "AWS CloudTrail is a web service that records AWS API calls for your account and delivers log files to you. The recorded information includes the identity of the API caller; the time of the API call; the source IP address of the API caller; the request parameters; and the response elements returned by the AWS service.", + "Risk": "AWS CloudTrail is a web service that records AWS API calls for your account and delivers log files to you. The recorded information includes the identity of the API caller, the time of the API call, the source IP address of the API caller, the request parameters, and the response elements returned by the AWS service.", "RelatedUrl": "", "Remediation": { "Code": { "CLI": "aws cloudtrail create-trail --name --bucket-name --is-multi-region-trail aws cloudtrail update-trail --name --is-multi-region-trail ", - "NativeIaC": "https://docs.bridgecrew.io/docs/logging_1#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/logging_1#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/logging_1#terraform" + "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_1#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_1#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_1#terraform" }, "Recommendation": { "Text": "Ensure Logging is set to ON on all regions (even if they are not being used at the moment.", diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.py index 17646fef78..b04a5a93fc 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.py @@ -7,36 +7,35 @@ from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( class cloudtrail_multi_region_enabled(Check): def execute(self): findings = [] - for region in cloudtrail_client.regional_clients.keys(): - report = Check_Report_AWS(self.metadata()) - report.region = region - for trail in cloudtrail_client.trails.values(): - if trail.region == region or trail.is_multiregion: - if trail.is_logging: - report.status = "PASS" - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - if trail.is_multiregion: - report.status_extended = ( - f"Trail {trail.name} is multiregion and it is logging." - ) + if cloudtrail_client.trails is not None: + for region in cloudtrail_client.regional_clients.keys(): + report = Check_Report_AWS(self.metadata()) + report.region = region + for trail in cloudtrail_client.trails.values(): + if trail.region == region or trail.is_multiregion: + if trail.is_logging: + report.status = "PASS" + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + if trail.is_multiregion: + report.status_extended = f"Trail {trail.name} is multiregion and it is logging." + else: + report.status_extended = f"Trail {trail.name} is not multiregion and it is logging." + # Since there exists a logging trail in that region there is no point in checking the remaining trails + # Store the finding and exit the loop + findings.append(report) + break else: - report.status_extended = f"Trail {trail.name} is not multiregion and it is logging." - # Since there exists a logging trail in that region there is no point in checking the remaining trails - # Store the finding and exit the loop - findings.append(report) - break - else: - report.status = "FAIL" - report.status_extended = ( - "No CloudTrail trails enabled and logging were found." - ) - report.resource_arn = ( - cloudtrail_client.__get_trail_arn_template__(region) - ) - report.resource_id = cloudtrail_client.audited_account - # If there are no trails logging it is needed to store the FAIL once all the trails have been checked - if report.status == "FAIL": - findings.append(report) + report.status = "FAIL" + report.status_extended = ( + "No CloudTrail trails enabled and logging were found." + ) + report.resource_arn = ( + cloudtrail_client.__get_trail_arn_template__(region) + ) + report.resource_id = cloudtrail_client.audited_account + # If there are no trails logging it is needed to store the FAIL once all the trails have been checked + if report.status == "FAIL": + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.metadata.json index e0aa2ebefa..b4b0978ffe 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.metadata.json @@ -12,17 +12,17 @@ "ResourceType": "AwsCloudTrailTrail", "Description": "Ensure CloudTrail logging management events in All Regions", "Risk": "AWS CloudTrail enables governance, compliance, operational auditing, and risk auditing of your AWS account. To meet FTR requirements, you must have management events enabled for all AWS accounts and in all regions and aggregate these logs into an Amazon Simple Storage Service (Amazon S3) bucket owned by a separate AWS account.", - "RelatedUrl": "https://docs.bridgecrew.io/docs/logging_14", + "RelatedUrl": "https://docs.prowler.com/checks/aws/logging-policies/logging_14", "Remediation": { "Code": { "CLI": "aws cloudtrail update-trail --name --is-multi-region-trail", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/logging_14", - "Terraform": "https://docs.bridgecrew.io/docs/logging_14#terraform" + "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_14", + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_14#terraform" }, "Recommendation": { "Text": "Enable CloudTrail logging management events in All Regions", - "Url": "https://docs.bridgecrew.io/docs/logging_14" + "Url": "https://docs.prowler.com/checks/aws/logging-policies/logging_14" } }, "Categories": [ diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.py index e97159d4b1..ac6b5a9db1 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.py @@ -7,48 +7,49 @@ from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( class cloudtrail_multi_region_enabled_logging_management_events(Check): def execute(self): findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No trail found with multi-region enabled and logging management events." - ) - report.region = cloudtrail_client.region - report.resource_id = cloudtrail_client.audited_account - report.resource_arn = cloudtrail_client.trail_arn_template + if cloudtrail_client.trails is not None: + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No trail found with multi-region enabled and logging management events." + report.region = cloudtrail_client.region + report.resource_id = cloudtrail_client.audited_account + report.resource_arn = cloudtrail_client.trail_arn_template - for trail in cloudtrail_client.trails.values(): - if trail.is_logging: - if trail.is_multiregion: - for event in trail.data_events: - # Classic event selectors - if not event.is_advanced: - # Check if trail has IncludeManagementEvents and ReadWriteType is All - if ( - event.event_selector["ReadWriteType"] == "All" - and event.event_selector["IncludeManagementEvents"] - ): - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "PASS" - report.status_extended = f"Trail {trail.name} from home region {trail.home_region} is multi-region, is logging and have management events enabled." + for trail in cloudtrail_client.trails.values(): + if trail.is_logging: + if trail.is_multiregion: + for event in trail.data_events: + # Classic event selectors + if not event.is_advanced: + # Check if trail has IncludeManagementEvents and ReadWriteType is All + if ( + event.event_selector["ReadWriteType"] == "All" + and event.event_selector["IncludeManagementEvents"] + ): + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "PASS" + report.status_extended = f"Trail {trail.name} from home region {trail.home_region} is multi-region, is logging and have management events enabled." - # Advanced event selectors - elif event.is_advanced: - if event.event_selector.get( - "Name" - ) == "Management events selector" and all( - [ - field["Field"] != "readOnly" - for field in event.event_selector["FieldSelectors"] - ] - ): - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "PASS" - report.status_extended = f"Trail {trail.name} from home region {trail.home_region} is multi-region, is logging and have management events enabled." - findings.append(report) + # Advanced event selectors + elif event.is_advanced: + if event.event_selector.get( + "Name" + ) == "Management events selector" and all( + [ + field["Field"] != "readOnly" + for field in event.event_selector[ + "FieldSelectors" + ] + ] + ): + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "PASS" + report.status_extended = f"Trail {trail.name} from home region {trail.home_region} is multi-region, is logging and have management events enabled." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.py index 5b63bf4196..237054b1be 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.py @@ -8,23 +8,41 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class cloudtrail_s3_dataevents_read_enabled(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - for data_event in trail.data_events: - # classic event selectors - if not data_event.is_advanced: - # Check if trail has a data event for all S3 Buckets for read - if ( - data_event.event_selector["ReadWriteType"] == "ReadOnly" - or data_event.event_selector["ReadWriteType"] == "All" - ): - for resource in data_event.event_selector["DataResources"]: - if "AWS::S3::Object" == resource["Type"] and ( - f"arn:{cloudtrail_client.audited_partition}:s3" - in resource["Values"] - or f"arn:{cloudtrail_client.audited_partition}:s3:::" - in resource["Values"] - or f"arn:{cloudtrail_client.audited_partition}:s3:::*/*" - in resource["Values"] + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + for data_event in trail.data_events: + # classic event selectors + if not data_event.is_advanced: + # Check if trail has a data event for all S3 Buckets for read + if ( + data_event.event_selector["ReadWriteType"] == "ReadOnly" + or data_event.event_selector["ReadWriteType"] == "All" + ): + for resource in data_event.event_selector["DataResources"]: + if "AWS::S3::Object" == resource["Type"] and ( + f"arn:{cloudtrail_client.audited_partition}:s3" + in resource["Values"] + or f"arn:{cloudtrail_client.audited_partition}:s3:::" + in resource["Values"] + or f"arn:{cloudtrail_client.audited_partition}:s3:::*/*" + in resource["Values"] + ): + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "PASS" + report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has a classic data event selector to record all S3 object-level API operations." + findings.append(report) + # advanced event selectors + elif data_event.is_advanced: + for field_selector in data_event.event_selector[ + "FieldSelectors" + ]: + if ( + field_selector["Field"] == "resources.type" + and field_selector["Equals"][0] == "AWS::S3::Object" ): report = Check_Report_AWS(self.metadata()) report.region = trail.region @@ -32,31 +50,17 @@ class cloudtrail_s3_dataevents_read_enabled(Check): report.resource_arn = trail.arn report.resource_tags = trail.tags report.status = "PASS" - report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has a classic data event selector to record all S3 object-level API operations." + report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has an advanced data event selector to record all S3 object-level API operations." findings.append(report) - # advanced event selectors - elif data_event.is_advanced: - for field_selector in data_event.event_selector["FieldSelectors"]: - if ( - field_selector["Field"] == "resources.type" - and field_selector["Equals"][0] == "AWS::S3::Object" - ): - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "PASS" - report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has an advanced data event selector to record all S3 object-level API operations." - findings.append(report) - if not findings and ( - s3_client.buckets or not cloudtrail_client.audit_info.ignore_unused_services - ): - report = Check_Report_AWS(self.metadata()) - report.region = cloudtrail_client.region - report.resource_arn = cloudtrail_client.trail_arn_template - report.resource_id = cloudtrail_client.audited_account - report.status = "FAIL" - report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations." - findings.append(report) + if not findings and ( + s3_client.buckets + or not cloudtrail_client.audit_info.ignore_unused_services + ): + report = Check_Report_AWS(self.metadata()) + report.region = cloudtrail_client.region + report.resource_arn = cloudtrail_client.trail_arn_template + report.resource_id = cloudtrail_client.audited_account + report.status = "FAIL" + report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.py index 9035694670..247c85971d 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.py @@ -8,23 +8,41 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class cloudtrail_s3_dataevents_write_enabled(Check): def execute(self): findings = [] - for trail in cloudtrail_client.trails.values(): - for data_event in trail.data_events: - # Classic event selectors - if not data_event.is_advanced: - # Check if trail has a data event for all S3 Buckets for write - if ( - data_event.event_selector["ReadWriteType"] == "All" - or data_event.event_selector["ReadWriteType"] == "WriteOnly" - ): - for resource in data_event.event_selector["DataResources"]: - if "AWS::S3::Object" == resource["Type"] and ( - f"arn:{cloudtrail_client.audited_partition}:s3" - in resource["Values"] - or f"arn:{cloudtrail_client.audited_partition}:s3:::" - in resource["Values"] - or f"arn:{cloudtrail_client.audited_partition}:s3:::*/*" - in resource["Values"] + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + for data_event in trail.data_events: + # Classic event selectors + if not data_event.is_advanced: + # Check if trail has a data event for all S3 Buckets for write + if ( + data_event.event_selector["ReadWriteType"] == "All" + or data_event.event_selector["ReadWriteType"] == "WriteOnly" + ): + for resource in data_event.event_selector["DataResources"]: + if "AWS::S3::Object" == resource["Type"] and ( + f"arn:{cloudtrail_client.audited_partition}:s3" + in resource["Values"] + or f"arn:{cloudtrail_client.audited_partition}:s3:::" + in resource["Values"] + or f"arn:{cloudtrail_client.audited_partition}:s3:::*/*" + in resource["Values"] + ): + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "PASS" + report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has a classic data event selector to record all S3 object-level API operations." + findings.append(report) + # Advanced event selectors + elif data_event.is_advanced: + for field_selector in data_event.event_selector[ + "FieldSelectors" + ]: + if ( + field_selector["Field"] == "resources.type" + and field_selector["Equals"][0] == "AWS::S3::Object" ): report = Check_Report_AWS(self.metadata()) report.region = trail.region @@ -32,31 +50,17 @@ class cloudtrail_s3_dataevents_write_enabled(Check): report.resource_arn = trail.arn report.resource_tags = trail.tags report.status = "PASS" - report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has a classic data event selector to record all S3 object-level API operations." + report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has an advanced data event selector to record all S3 object-level API operations." findings.append(report) - # Advanced event selectors - elif data_event.is_advanced: - for field_selector in data_event.event_selector["FieldSelectors"]: - if ( - field_selector["Field"] == "resources.type" - and field_selector["Equals"][0] == "AWS::S3::Object" - ): - report = Check_Report_AWS(self.metadata()) - report.region = trail.region - report.resource_id = trail.name - report.resource_arn = trail.arn - report.resource_tags = trail.tags - report.status = "PASS" - report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has an advanced data event selector to record all S3 object-level API operations." - findings.append(report) - if not findings and ( - s3_client.buckets or not cloudtrail_client.audit_info.ignore_unused_services - ): - report = Check_Report_AWS(self.metadata()) - report.region = cloudtrail_client.region - report.resource_arn = cloudtrail_client.trail_arn_template - report.resource_id = cloudtrail_client.audited_account - report.status = "FAIL" - report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations." - findings.append(report) + if not findings and ( + s3_client.buckets + or not cloudtrail_client.audit_info.ignore_unused_services + ): + report = Check_Report_AWS(self.metadata()) + report.region = cloudtrail_client.region + report.resource_arn = cloudtrail_client.trail_arn_template + report.resource_id = cloudtrail_client.audited_account + report.status = "FAIL" + report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_service.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_service.py index b78aaaf2fb..c0eb926fac 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_service.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_service.py @@ -17,10 +17,11 @@ class Cloudtrail(AWSService): self.trail_arn_template = f"arn:{self.audited_partition}:cloudtrail:{self.region}:{self.audited_account}:trail" self.trails = {} self.__threading_call__(self.__get_trails__) - self.__get_trail_status__() - self.__get_insight_selectors__() - self.__get_event_selectors__() - self.__list_tags_for_resource__() + if self.trails: + self.__get_trail_status__() + self.__get_insight_selectors__() + self.__get_event_selectors__() + self.__list_tags_for_resource__() def __get_trail_arn_template__(self, region): return ( @@ -45,6 +46,8 @@ class Cloudtrail(AWSService): kms_key_id = trail["KmsKeyId"] if "CloudWatchLogsLogGroupArn" in trail: log_group_arn = trail["CloudWatchLogsLogGroupArn"] + if self.trails is None: + self.trails = {} self.trails[trail["TrailARN"]] = Trail( name=trail["Name"], is_multiregion=trail["IsMultiRegionTrail"], @@ -61,12 +64,24 @@ class Cloudtrail(AWSService): has_insight_selectors=trail.get("HasInsightSelectors"), ) if trails_count == 0: + if self.trails is None: + self.trails = {} self.trails[self.__get_trail_arn_template__(regional_client.region)] = ( Trail( region=regional_client.region, ) ) - + except ClientError as error: + if error.response["Error"]["Code"] == "AccessDeniedException": + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + if not self.trails: + self.trails = None + else: + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json index 30dc216a17..d88b650108 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_11#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_11#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_11#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_11#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.py index 21ad6c6f7c..63905b4c2d 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.py @@ -15,21 +15,24 @@ class cloudwatch_changes_to_network_acls_alarm_configured(Check): def execute(self): pattern = r"\$\.eventName\s*=\s*.?CreateNetworkAcl.+\$\.eventName\s*=\s*.?CreateNetworkAclEntry.+\$\.eventName\s*=\s*.?DeleteNetworkAcl.+\$\.eventName\s*=\s*.?DeleteNetworkAclEntry.+\$\.eventName\s*=\s*.?ReplaceNetworkAclEntry.+\$\.eventName\s*=\s*.?ReplaceNetworkAclAssociation.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json index cfdcfede0a..51d7c54e96 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_12#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_12#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_12#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_12#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.py index 1c8d40994f..11de46ec26 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.py @@ -15,21 +15,24 @@ class cloudwatch_changes_to_network_gateways_alarm_configured(Check): def execute(self): pattern = r"\$\.eventName\s*=\s*.?CreateCustomerGateway.+\$\.eventName\s*=\s*.?DeleteCustomerGateway.+\$\.eventName\s*=\s*.?AttachInternetGateway.+\$\.eventName\s*=\s*.?CreateInternetGateway.+\$\.eventName\s*=\s*.?DeleteInternetGateway.+\$\.eventName\s*=\s*.?DetachInternetGateway.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json index f766cfecc3..0430c46cd5 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_13#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_13#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_13#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_13#fix---buildtime" }, "Recommendation": { "Text": "If you are using CloudTrails and CloudWatch, perform the following to setup the metric filter, alarm, SNS topic, and subscription: 1. Create a metric filter based on filter pattern provided which checks for route table changes and the taken from audit step 1. aws logs put-metric-filter --log-group-name -- filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = ec2.amazonaws.com) && (($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable)) }' Note: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together. 2. Create an SNS topic that the alarm will notify aws sns create-topic --name Note: you can execute this command once and then re-use the same topic for all monitoring alarms. 3. Create an SNS subscription to the topic created in step 2 aws sns subscribe --topic-arn --protocol - -notification-endpoint Note: you can execute this command once and then re-use the SNS subscription for all monitoring alarms. 4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 - -threshold 1 --comparison-operator GreaterThanOrEqualToThreshold -- evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions ", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.py index f602d2a7c0..3f1f2d04fb 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.py @@ -15,21 +15,24 @@ class cloudwatch_changes_to_network_route_tables_alarm_configured(Check): def execute(self): pattern = r"\$\.eventSource\s*=\s*.?ec2.amazonaws.com.+\$\.eventName\s*=\s*.?CreateRoute.+\$\.eventName\s*=\s*.?CreateRouteTable.+\$\.eventName\s*=\s*.?ReplaceRoute.+\$\.eventName\s*=\s*.?ReplaceRouteTableAssociation.+\$\.eventName\s*=\s*.?DeleteRouteTable.+\$\.eventName\s*=\s*.?DeleteRoute.+\$\.eventName\s*=\s*.?DisassociateRouteTable.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json index 0f6c265558..d280c58eed 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_14#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_14#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_14#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_14#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.py index 82afeb1fb5..5a56070828 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.py @@ -15,21 +15,24 @@ class cloudwatch_changes_to_vpcs_alarm_configured(Check): def execute(self): pattern = r"\$\.eventName\s*=\s*.?CreateVpc.+\$\.eventName\s*=\s*.?DeleteVpc.+\$\.eventName\s*=\s*.?ModifyVpcAttribute.+\$\.eventName\s*=\s*.?AcceptVpcPeeringConnection.+\$\.eventName\s*=\s*.?CreateVpcPeeringConnection.+\$\.eventName\s*=\s*.?DeleteVpcPeeringConnection.+\$\.eventName\s*=\s*.?RejectVpcPeeringConnection.+\$\.eventName\s*=\s*.?AttachClassicLinkVpc.+\$\.eventName\s*=\s*.?DetachClassicLinkVpc.+\$\.eventName\s*=\s*.?DisableVpcClassicLink.+\$\.eventName\s*=\s*.?EnableVpcClassicLink.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.py index c41954e82b..065a9d569b 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.py @@ -5,17 +5,20 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class cloudwatch_cross_account_sharing_disabled(Check): def execute(self): findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "PASS" - report.status_extended = "CloudWatch doesn't allow cross-account sharing." - report.resource_arn = iam_client.role_arn_template - report.resource_id = iam_client.audited_account - report.region = iam_client.region - for role in iam_client.roles: - if role.name == "CloudWatch-CrossAccountSharingRole": - report.resource_arn = role.arn - report.resource_id = role.name - report.status = "FAIL" - report.status_extended = "CloudWatch has allowed cross-account sharing." - findings.append(report) + if iam_client.roles is not None: + report = Check_Report_AWS(self.metadata()) + report.status = "PASS" + report.status_extended = "CloudWatch doesn't allow cross-account sharing." + report.resource_arn = iam_client.role_arn_template + report.resource_id = iam_client.audited_account + report.region = iam_client.region + for role in iam_client.roles: + if role.name == "CloudWatch-CrossAccountSharingRole": + report.resource_arn = role.arn + report.resource_id = role.name + report.status = "FAIL" + report.status_extended = ( + "CloudWatch has allowed cross-account sharing." + ) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json index b684a0e833..dcfff3163a 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json @@ -17,7 +17,7 @@ "Code": { "CLI": "associate-kms-key --log-group-name --kms-key-id ", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/logging_21#aws-console", + "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_21#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.py index e30ddfcae1..83b8bf30c0 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.py @@ -5,19 +5,18 @@ from prowler.providers.aws.services.cloudwatch.logs_client import logs_client class cloudwatch_log_group_kms_encryption_enabled(Check): def execute(self): findings = [] - for log_group in logs_client.log_groups: - report = Check_Report_AWS(self.metadata()) - report.region = log_group.region - report.resource_id = log_group.name - report.resource_arn = log_group.arn - report.resource_tags = log_group.tags - if log_group.kms_id: - report.status = "PASS" - report.status_extended = f"Log Group {log_group.name} does have AWS KMS key {log_group.kms_id} associated." - else: - report.status = "FAIL" - report.status_extended = ( - f"Log Group {log_group.name} does not have AWS KMS keys associated." - ) - findings.append(report) + if logs_client.log_groups: + for log_group in logs_client.log_groups: + report = Check_Report_AWS(self.metadata()) + report.region = log_group.region + report.resource_id = log_group.name + report.resource_arn = log_group.arn + report.resource_tags = log_group.tags + if log_group.kms_id: + report.status = "PASS" + report.status_extended = f"Log Group {log_group.name} does have AWS KMS key {log_group.kms_id} associated." + else: + report.status = "FAIL" + report.status_extended = f"Log Group {log_group.name} does not have AWS KMS keys associated." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.py index c199d01908..8b23d20285 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.py @@ -11,78 +11,86 @@ from prowler.providers.aws.services.cloudwatch.logs_client import logs_client class cloudwatch_log_group_no_secrets_in_logs(Check): def execute(self): findings = [] - for log_group in logs_client.log_groups: - report = Check_Report_AWS(self.metadata()) - report.status = "PASS" - report.status_extended = f"No secrets found in {log_group.name} log group." - report.region = log_group.region - report.resource_id = log_group.name - report.resource_arn = log_group.arn - log_group_secrets = [] - if log_group.log_streams: - for log_stream_name in log_group.log_streams: - log_stream_secrets = {} - log_stream_data = "\n".join( - [ - dumps(event["message"]) - for event in log_group.log_streams[log_stream_name] - ] - ) - log_stream_secrets_output = detect_secrets_scan(log_stream_data) - - if log_stream_secrets_output: - for secret in log_stream_secrets_output: - flagged_event = log_group.log_streams[log_stream_name][ - secret["line_number"] - 1 - ] - cloudwatch_timestamp = ( - convert_to_cloudwatch_timestamp_format( - flagged_event["timestamp"] - ) - ) - if cloudwatch_timestamp not in log_stream_secrets.keys(): - log_stream_secrets[cloudwatch_timestamp] = SecretsDict() - - try: - log_event_data = dumps( - loads(flagged_event["message"]), indent=2 - ) - except Exception: - log_event_data = dumps( - flagged_event["message"], indent=2 - ) - if len(log_event_data.split("\n")) > 1: - # Can get more informative output if there is more than 1 line. - # Will rescan just this event to get the type of secret and the line number - event_detect_secrets_output = detect_secrets_scan( - log_event_data - ) - if event_detect_secrets_output: - for secret in event_detect_secrets_output: - log_stream_secrets[ - cloudwatch_timestamp - ].add_secret( - secret["line_number"], secret["type"] - ) - else: - log_stream_secrets[cloudwatch_timestamp].add_secret( - 1, secret["type"] - ) - if log_stream_secrets: - secrets_string = "; ".join( + if logs_client.log_groups: + for log_group in logs_client.log_groups: + report = Check_Report_AWS(self.metadata()) + report.status = "PASS" + report.status_extended = ( + f"No secrets found in {log_group.name} log group." + ) + report.region = log_group.region + report.resource_id = log_group.name + report.resource_arn = log_group.arn + log_group_secrets = [] + if log_group.log_streams: + for log_stream_name in log_group.log_streams: + log_stream_secrets = {} + log_stream_data = "\n".join( [ - f"at {timestamp} - {log_stream_secrets[timestamp].to_string()}" - for timestamp in log_stream_secrets + dumps(event["message"]) + for event in log_group.log_streams[log_stream_name] ] ) - log_group_secrets.append( - f"in log stream {log_stream_name} {secrets_string}" - ) - if log_group_secrets: - secrets_string = "; ".join(log_group_secrets) - report.status = "FAIL" - report.status_extended = f"Potential secrets found in log group {log_group.name} {secrets_string}." - findings.append(report) + log_stream_secrets_output = detect_secrets_scan(log_stream_data) + + if log_stream_secrets_output: + for secret in log_stream_secrets_output: + flagged_event = log_group.log_streams[log_stream_name][ + secret["line_number"] - 1 + ] + cloudwatch_timestamp = ( + convert_to_cloudwatch_timestamp_format( + flagged_event["timestamp"] + ) + ) + if ( + cloudwatch_timestamp + not in log_stream_secrets.keys() + ): + log_stream_secrets[cloudwatch_timestamp] = ( + SecretsDict() + ) + + try: + log_event_data = dumps( + loads(flagged_event["message"]), indent=2 + ) + except Exception: + log_event_data = dumps( + flagged_event["message"], indent=2 + ) + if len(log_event_data.split("\n")) > 1: + # Can get more informative output if there is more than 1 line. + # Will rescan just this event to get the type of secret and the line number + event_detect_secrets_output = detect_secrets_scan( + log_event_data + ) + if event_detect_secrets_output: + for secret in event_detect_secrets_output: + log_stream_secrets[ + cloudwatch_timestamp + ].add_secret( + secret["line_number"], secret["type"] + ) + else: + log_stream_secrets[cloudwatch_timestamp].add_secret( + 1, secret["type"] + ) + if log_stream_secrets: + secrets_string = "; ".join( + [ + f"at {timestamp} - {log_stream_secrets[timestamp].to_string()}" + for timestamp in log_stream_secrets + ] + ) + log_group_secrets.append( + f"in log stream {log_stream_name} {secrets_string}" + ) + if log_group_secrets: + secrets_string = "; ".join(log_group_secrets) + report.status = "FAIL" + report.status_extended = f"Potential secrets found in log group {log_group.name} {secrets_string}." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json index 4f68b5a815..362422ead7 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Logs.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/logging_13#cli-command", - "NativeIaC": "https://docs.bridgecrew.io/docs/logging_13#cloudformation", + "CLI": "https://docs.prowler.com/checks/aws/logging-policies/logging_13#cli-command", + "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_13#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/logging_13#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_13#terraform" }, "Recommendation": { "Text": "Add Log Retention policy of specific days to log groups. This will persist logs and traces for a long time.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.py index 564e1f3117..342770dc8a 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.py @@ -10,23 +10,24 @@ class cloudwatch_log_group_retention_policy_specific_days_enabled(Check): specific_retention_days = logs_client.audit_config.get( "log_group_retention_days", 365 ) - for log_group in logs_client.log_groups: - report = Check_Report_AWS(self.metadata()) - report.region = log_group.region - report.resource_id = log_group.name - report.resource_arn = log_group.arn - report.resource_tags = log_group.tags - if ( - log_group.never_expire is False - and log_group.retention_days < specific_retention_days - ): - report.status = "FAIL" - report.status_extended = f"Log Group {log_group.name} has less than {specific_retention_days} days retention period ({log_group.retention_days} days)." - else: - report.status = "PASS" - if log_group.never_expire is True: - report.status_extended = f"Log Group {log_group.name} comply with {specific_retention_days} days retention period since it never expires." + if logs_client.log_groups: + for log_group in logs_client.log_groups: + report = Check_Report_AWS(self.metadata()) + report.region = log_group.region + report.resource_id = log_group.name + report.resource_arn = log_group.arn + report.resource_tags = log_group.tags + if ( + log_group.never_expire is False + and log_group.retention_days < specific_retention_days + ): + report.status = "FAIL" + report.status_extended = f"Log Group {log_group.name} has less than {specific_retention_days} days retention period ({log_group.retention_days} days)." else: - report.status_extended = f"Log Group {log_group.name} comply with {specific_retention_days} days retention period since it has {log_group.retention_days} days." - findings.append(report) + report.status = "PASS" + if log_group.never_expire is True: + report.status_extended = f"Log Group {log_group.name} comply with {specific_retention_days} days retention period since it never expires." + else: + report.status_extended = f"Log Group {log_group.name} comply with {specific_retention_days} days retention period since it has {log_group.retention_days} days." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json index 0c86f64de3..78dc472dfb 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_9#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_9#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_9#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_9#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.py index 6cc439fea6..72079b8597 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.py @@ -17,21 +17,24 @@ class cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_change def execute(self): pattern = r"\$\.eventSource\s*=\s*.?config.amazonaws.com.+\$\.eventName\s*=\s*.?StopConfigurationRecorder.+\$\.eventName\s*=\s*.?DeleteDeliveryChannel.+\$\.eventName\s*=\s*.?PutDeliveryChannel.+\$\.eventName\s*=\s*.?PutConfigurationRecorder.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json index 16da3b1a5b..902f1454d3 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_5#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_5#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_5#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_5#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.py index b6c440d454..0addc30196 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.py @@ -17,21 +17,24 @@ class cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_change def execute(self): pattern = r"\$\.eventName\s*=\s*.?CreateTrail.+\$\.eventName\s*=\s*.?UpdateTrail.+\$\.eventName\s*=\s*.?DeleteTrail.+\$\.eventName\s*=\s*.?StartLogging.+\$\.eventName\s*=\s*.?StopLogging.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json index 21998dd501..5926234887 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_6#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_6#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_6#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_6#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.py index d70c602b15..fe6f538caf 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.py @@ -15,21 +15,24 @@ class cloudwatch_log_metric_filter_authentication_failures(Check): def execute(self): pattern = r"\$\.eventName\s*=\s*.?ConsoleLogin.+\$\.errorMessage\s*=\s*.?Failed authentication.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.py index 6a700cc3b2..d9053d3160 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.py @@ -15,21 +15,24 @@ class cloudwatch_log_metric_filter_aws_organizations_changes(Check): def execute(self): pattern = r"\$\.eventSource\s*=\s*.?organizations\.amazonaws\.com.+\$\.eventName\s*=\s*.?AcceptHandshake.+\$\.eventName\s*=\s*.?AttachPolicy.+\$\.eventName\s*=\s*.?CancelHandshake.+\$\.eventName\s*=\s*.?CreateAccount.+\$\.eventName\s*=\s*.?CreateOrganization.+\$\.eventName\s*=\s*.?CreateOrganizationalUnit.+\$\.eventName\s*=\s*.?CreatePolicy.+\$\.eventName\s*=\s*.?DeclineHandshake.+\$\.eventName\s*=\s*.?DeleteOrganization.+\$\.eventName\s*=\s*.?DeleteOrganizationalUnit.+\$\.eventName\s*=\s*.?DeletePolicy.+\$\.eventName\s*=\s*.?EnableAllFeatures.+\$\.eventName\s*=\s*.?EnablePolicyType.+\$\.eventName\s*=\s*.?InviteAccountToOrganization.+\$\.eventName\s*=\s*.?LeaveOrganization.+\$\.eventName\s*=\s*.?DetachPolicy.+\$\.eventName\s*=\s*.?DisablePolicyType.+\$\.eventName\s*=\s*.?MoveAccount.+\$\.eventName\s*=\s*.?RemoveAccountFromOrganization.+\$\.eventName\s*=\s*.?UpdateOrganizationalUnit.+\$\.eventName\s*=\s*.?UpdatePolicy.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json index ba19c4ac40..b7b749897e 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_7#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_7#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_7#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_7#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.py index f2bc343333..63f99e1de1 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.py @@ -15,21 +15,24 @@ class cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk(Chec def execute(self): pattern = r"\$\.eventSource\s*=\s*.?kms.amazonaws.com.+\$\.eventName\s*=\s*.?DisableKey.+\$\.eventName\s*=\s*.?ScheduleKeyDeletion.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json index 653b00c0a5..01ec5890ac 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_8#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_8#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_8#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_8#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.py index b21f2cd099..46489bab68 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.py @@ -15,22 +15,25 @@ class cloudwatch_log_metric_filter_for_s3_bucket_policy_changes(Check): def execute(self): pattern = r"\$\.eventSource\s*=\s*.?s3.amazonaws.com.+\$\.eventName\s*=\s*.?PutBucketAcl.+\$\.eventName\s*=\s*.?PutBucketPolicy.+\$\.eventName\s*=\s*.?PutBucketCors.+\$\.eventName\s*=\s*.?PutBucketLifecycle.+\$\.eventName\s*=\s*.?PutBucketReplication.+\$\.eventName\s*=\s*.?DeleteBucketPolicy.+\$\.eventName\s*=\s*.?DeleteBucketCors.+\$\.eventName\s*=\s*.?DeleteBucketLifecycle.+\$\.eventName\s*=\s*.?DeleteBucketReplication.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json index adca7d9876..a8adb8ae6a 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_4#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_4#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_4#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_4#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.py index b5f121e33d..0b38eb7bfa 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.py @@ -15,21 +15,24 @@ class cloudwatch_log_metric_filter_policy_changes(Check): def execute(self): pattern = r"\$\.eventName\s*=\s*.?DeleteGroupPolicy.+\$\.eventName\s*=\s*.?DeleteRolePolicy.+\$\.eventName\s*=\s*.?DeleteUserPolicy.+\$\.eventName\s*=\s*.?PutGroupPolicy.+\$\.eventName\s*=\s*.?PutRolePolicy.+\$\.eventName\s*=\s*.?PutUserPolicy.+\$\.eventName\s*=\s*.?CreatePolicy.+\$\.eventName\s*=\s*.?DeletePolicy.+\$\.eventName\s*=\s*.?CreatePolicyVersion.+\$\.eventName\s*=\s*.?DeletePolicyVersion.+\$\.eventName\s*=\s*.?AttachRolePolicy.+\$\.eventName\s*=\s*.?DetachRolePolicy.+\$\.eventName\s*=\s*.?AttachUserPolicy.+\$\.eventName\s*=\s*.?DetachUserPolicy.+\$\.eventName\s*=\s*.?AttachGroupPolicy.+\$\.eventName\s*=\s*.?DetachGroupPolicy.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json index cb7f3c4b4a..6596d01a6e 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_3#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_3#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_3#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_3#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.py index 027c6d02b9..9f99ad4c13 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.py @@ -15,21 +15,24 @@ class cloudwatch_log_metric_filter_root_usage(Check): def execute(self): pattern = r"\$\.userIdentity\.type\s*=\s*.?Root.+\$\.userIdentity\.invokedBy NOT EXISTS.+\$\.eventType\s*!=\s*.?AwsServiceEvent.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json index 01bfe2f00f..5195617961 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_10#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_10#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_10#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_10#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.py index a9efd8e0a4..6240f20383 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.py @@ -15,21 +15,24 @@ class cloudwatch_log_metric_filter_security_group_changes(Check): def execute(self): pattern = r"\$\.eventName\s*=\s*.?AuthorizeSecurityGroupIngress.+\$\.eventName\s*=\s*.?AuthorizeSecurityGroupEgress.+\$\.eventName\s*=\s*.?RevokeSecurityGroupIngress.+\$\.eventName\s*=\s*.?RevokeSecurityGroupEgress.+\$\.eventName\s*=\s*.?CreateSecurityGroup.+\$\.eventName\s*=\s*.?DeleteSecurityGroup.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json index cad8a34285..2f3c4459f9 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_2#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_2#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_2#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_2#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.py index 42f0450c2d..f6657d125a 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.py @@ -15,21 +15,24 @@ class cloudwatch_log_metric_filter_sign_in_without_mfa(Check): def execute(self): pattern = r"\$\.eventName\s*=\s*.?ConsoleLogin.+\$\.additionalEventData\.MFAUsed\s*!=\s*.?Yes.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json index 90f130f758..63ca78288f 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/monitoring_1#procedure", + "CLI": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_1#procedure", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/monitoring_1#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/monitoring-policies/monitoring_1#fix---buildtime" }, "Recommendation": { "Text": "It is recommended that a metric filter and alarm be established for unauthorized requests.", diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.py index f05133c1bd..2cd8057bfc 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.py @@ -15,21 +15,24 @@ class cloudwatch_log_metric_filter_unauthorized_api_calls(Check): def execute(self): pattern = r"\$\.errorCode\s*=\s*.?\*UnauthorizedOperation.+\$\.errorCode\s*=\s*.?AccessDenied\*.?" findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = ( - "No CloudWatch log groups found with metric filters or alarms associated." - ) - report.region = logs_client.region - report.resource_id = logs_client.audited_account - report.resource_arn = logs_client.log_group_arn_template - report = check_cloudwatch_log_metric_filter( - pattern, - cloudtrail_client.trails, - logs_client.metric_filters, - cloudwatch_client.metric_alarms, - report, - ) + if ( + cloudtrail_client.trails is not None + and logs_client.metric_filters is not None + and cloudwatch_client.metric_alarms is not None + ): + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No CloudWatch log groups found with metric filters or alarms associated." + report.region = logs_client.region + report.resource_id = logs_client.audited_account + report.resource_arn = logs_client.log_group_arn_template + report = check_cloudwatch_log_metric_filter( + pattern, + cloudtrail_client.trails, + logs_client.metric_filters, + cloudwatch_client.metric_alarms, + report, + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py index e395207c42..2066ae0a6f 100644 --- a/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py +++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py @@ -16,7 +16,8 @@ class CloudWatch(AWSService): super().__init__(__class__.__name__, audit_info) self.metric_alarms = [] self.__threading_call__(self.__describe_alarms__) - self.__list_tags_for_resource__() + if self.metric_alarms: + self.__list_tags_for_resource__() def __describe_alarms__(self, regional_client): logger.info("CloudWatch - Describing alarms...") @@ -33,6 +34,8 @@ class CloudWatch(AWSService): namespace = None if "Namespace" in alarm: namespace = alarm["Namespace"] + if self.metric_alarms is None: + self.metric_alarms = [] self.metric_alarms.append( MetricAlarm( arn=alarm["AlarmArn"], @@ -42,6 +45,17 @@ class CloudWatch(AWSService): region=regional_client.region, ) ) + except ClientError as error: + if error.response["Error"]["Code"] == "AccessDenied": + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + if not self.metric_alarms: + self.metric_alarms = None + else: + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -72,15 +86,16 @@ class Logs(AWSService): self.log_groups = [] self.__threading_call__(self.__describe_metric_filters__) self.__threading_call__(self.__describe_log_groups__) - if ( - "cloudwatch_log_group_no_secrets_in_logs" - in audit_info.audit_metadata.expected_checks - ): - self.events_per_log_group_threshold = ( - 1000 # The threshold for number of events to return per log group. - ) - self.__threading_call__(self.__get_log_events__) - self.__list_tags_for_resource__() + if self.log_groups: + if ( + "cloudwatch_log_group_no_secrets_in_logs" + in audit_info.audit_metadata.expected_checks + ): + self.events_per_log_group_threshold = ( + 1000 # The threshold for number of events to return per log group. + ) + self.__threading_call__(self.__get_log_events__) + self.__list_tags_for_resource__() def __describe_metric_filters__(self, regional_client): logger.info("CloudWatch Logs - Describing metric filters...") @@ -94,6 +109,8 @@ class Logs(AWSService): if not self.audit_resources or ( is_resource_filtered(arn, self.audit_resources) ): + if self.metric_filters is None: + self.metric_filters = [] self.metric_filters.append( MetricFilter( arn=arn, @@ -104,6 +121,17 @@ class Logs(AWSService): region=regional_client.region, ) ) + except ClientError as error: + if error.response["Error"]["Code"] == "AccessDeniedException": + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + if not self.metric_filters: + self.metric_filters = [] + else: + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -126,6 +154,8 @@ class Logs(AWSService): if not retention_days: never_expire = True retention_days = 9999 + if self.log_groups is None: + self.log_groups = [] self.log_groups.append( LogGroup( arn=log_group["arn"], @@ -136,6 +166,17 @@ class Logs(AWSService): region=regional_client.region, ) ) + except ClientError as error: + if error.response["Error"]["Code"] == "AccessDeniedException": + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + if not self.log_groups: + self.log_groups = None + else: + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" diff --git a/prowler/providers/aws/services/cloudwatch/lib/metric_filters.py b/prowler/providers/aws/services/cloudwatch/lib/metric_filters.py index 1c67b1d638..a8743b6c0f 100644 --- a/prowler/providers/aws/services/cloudwatch/lib/metric_filters.py +++ b/prowler/providers/aws/services/cloudwatch/lib/metric_filters.py @@ -12,9 +12,10 @@ def check_cloudwatch_log_metric_filter( ): # 1. Iterate for CloudWatch Log Group in CloudTrail trails log_groups = [] - for trail in trails.values(): - if trail.log_group_arn: - log_groups.append(trail.log_group_arn.split(":")[6]) + if trails is not None: + for trail in trails.values(): + if trail.log_group_arn: + log_groups.append(trail.log_group_arn.split(":")[6]) # 2. Describe metric filters for previous log groups for metric_filter in metric_filters: if metric_filter.log_group in log_groups: diff --git a/prowler/providers/aws/services/config/config_recorder_all_regions_enabled/config_recorder_all_regions_enabled.metadata.json b/prowler/providers/aws/services/config/config_recorder_all_regions_enabled/config_recorder_all_regions_enabled.metadata.json index fc19821f90..c730223fae 100644 --- a/prowler/providers/aws/services/config/config_recorder_all_regions_enabled/config_recorder_all_regions_enabled.metadata.json +++ b/prowler/providers/aws/services/config/config_recorder_all_regions_enabled/config_recorder_all_regions_enabled.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "https://aws.amazon.com/blogs/mt/aws-config-best-practices/", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/logging_5-enable-aws-config-regions#cli-command", + "CLI": "https://docs.prowler.com/checks/aws/logging-policies/logging_5-enable-aws-config-regions#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/logging_5-enable-aws-config-regions#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/logging_5-enable-aws-config-regions#terraform" + "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_5-enable-aws-config-regions#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_5-enable-aws-config-regions#terraform" }, "Recommendation": { "Text": "It is recommended to enable AWS Config in all regions.", diff --git a/prowler/providers/aws/services/documentdb/documentdb_instance_storage_encrypted/documentdb_instance_storage_encrypted.metadata.json b/prowler/providers/aws/services/documentdb/documentdb_instance_storage_encrypted/documentdb_instance_storage_encrypted.metadata.json index c23412434b..c7c3270fe7 100644 --- a/prowler/providers/aws/services/documentdb/documentdb_instance_storage_encrypted/documentdb_instance_storage_encrypted.metadata.json +++ b/prowler/providers/aws/services/documentdb/documentdb_instance_storage_encrypted/documentdb_instance_storage_encrypted.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws docdb create-db-cluster --db-cluster-identifier --port 27017 --engine docdb --master-username --master-user-password --storage-encrypted", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DocumentDB/encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_28#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_28#terraform" }, "Recommendation": { "Text": "Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits.", diff --git a/prowler/providers/aws/services/dynamodb/dynamodb_accelerator_cluster_encryption_enabled/dynamodb_accelerator_cluster_encryption_enabled.metadata.json b/prowler/providers/aws/services/dynamodb/dynamodb_accelerator_cluster_encryption_enabled/dynamodb_accelerator_cluster_encryption_enabled.metadata.json index 203d956b65..bcc04b54e0 100644 --- a/prowler/providers/aws/services/dynamodb/dynamodb_accelerator_cluster_encryption_enabled/dynamodb_accelerator_cluster_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/dynamodb/dynamodb_accelerator_cluster_encryption_enabled/dynamodb_accelerator_cluster_encryption_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws dax create-cluster --cluster-name --node-type --replication-factor --iam-role-arn --sse-specification Enabled=true", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_23#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_23#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_23#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_23#terraform" }, "Recommendation": { "Text": "Re-create the cluster to enable encryption at rest if it was not enabled at creation.", diff --git a/prowler/providers/aws/services/dynamodb/dynamodb_tables_kms_cmk_encryption_enabled/dynamodb_tables_kms_cmk_encryption_enabled.metadata.json b/prowler/providers/aws/services/dynamodb/dynamodb_tables_kms_cmk_encryption_enabled/dynamodb_tables_kms_cmk_encryption_enabled.metadata.json index 752cf4a501..35321b6555 100644 --- a/prowler/providers/aws/services/dynamodb/dynamodb_tables_kms_cmk_encryption_enabled/dynamodb_tables_kms_cmk_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/dynamodb/dynamodb_tables_kms_cmk_encryption_enabled/dynamodb_tables_kms_cmk_encryption_enabled.metadata.json @@ -18,7 +18,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-dynamodb-tables-are-encrypted#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-dynamodb-tables-are-encrypted#terraform" }, "Recommendation": { "Text": "Specify an encryption key when you create a new table or switch the encryption keys on an existing table by using the AWS Management Console.", diff --git a/prowler/providers/aws/services/dynamodb/dynamodb_tables_pitr_enabled/dynamodb_tables_pitr_enabled.metadata.json b/prowler/providers/aws/services/dynamodb/dynamodb_tables_pitr_enabled/dynamodb_tables_pitr_enabled.metadata.json index a46d3a041c..2304877659 100644 --- a/prowler/providers/aws/services/dynamodb/dynamodb_tables_pitr_enabled/dynamodb_tables_pitr_enabled.metadata.json +++ b/prowler/providers/aws/services/dynamodb/dynamodb_tables_pitr_enabled/dynamodb_tables_pitr_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws dynamodb update-continuous-backups --table-name --point-in-time-recovery-specification PointInTimeRecoveryEnabled=true", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_6#cloudformation--serverless", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_6#cloudformation--serverless", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/general_6#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_6#terraform" }, "Recommendation": { "Text": "Enable point-in-time recovery, this is not enabled by default.", diff --git a/prowler/providers/aws/services/ec2/ec2_ami_public/ec2_ami_public.metadata.json b/prowler/providers/aws/services/ec2/ec2_ami_public/ec2_ami_public.metadata.json index 702da300ef..dd73671565 100644 --- a/prowler/providers/aws/services/ec2/ec2_ami_public/ec2_ami_public.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_ami_public/ec2_ami_public.metadata.json @@ -15,9 +15,9 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/public_8#cli-command", + "CLI": "https://docs.prowler.com/checks/aws/public-policies/public_8#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/public_8#aws-console", + "Other": "https://docs.prowler.com/checks/aws/public-policies/public_8#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption.metadata.json b/prowler/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption.metadata.json index 9f078bba59..ea6d27de46 100644 --- a/prowler/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption.metadata.json @@ -17,8 +17,8 @@ "Code": { "CLI": "aws ec2 enable-ebs-encryption-by-default", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/ensure-ebs-default-encryption-is-enabled#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-ebs-default-encryption-is-enabled#terraform" + "Other": "https://docs.prowler.com/checks/aws/general-policies/ensure-ebs-default-encryption-is-enabled#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-ebs-default-encryption-is-enabled#terraform" }, "Recommendation": { "Text": "Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits.", diff --git a/prowler/providers/aws/services/ec2/ec2_ebs_public_snapshot/ec2_ebs_public_snapshot.metadata.json b/prowler/providers/aws/services/ec2/ec2_ebs_public_snapshot/ec2_ebs_public_snapshot.metadata.json index d088f30fad..d0324b5816 100644 --- a/prowler/providers/aws/services/ec2/ec2_ebs_public_snapshot/ec2_ebs_public_snapshot.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_ebs_public_snapshot/ec2_ebs_public_snapshot.metadata.json @@ -15,9 +15,9 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/public_7#cli-command", + "CLI": "https://docs.prowler.com/checks/aws/public-policies/public_7#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/public_7#aws-console", + "Other": "https://docs.prowler.com/checks/aws/public-policies/public_7#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/ec2/ec2_ebs_snapshots_encrypted/ec2_ebs_snapshots_encrypted.metadata.json b/prowler/providers/aws/services/ec2/ec2_ebs_snapshots_encrypted/ec2_ebs_snapshots_encrypted.metadata.json index 68aa74ef04..d50e3a933a 100644 --- a/prowler/providers/aws/services/ec2/ec2_ebs_snapshots_encrypted/ec2_ebs_snapshots_encrypted.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_ebs_snapshots_encrypted/ec2_ebs_snapshots_encrypted.metadata.json @@ -16,12 +16,12 @@ "Remediation": { "Code": { "CLI": "aws ec2 --region enable-ebs-encryption-by-default", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_3-encrypt-eps-volume#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/general_3-encrypt-eps-volume#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/general_3-encrypt-eps-volume#terraform" + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_3-encrypt-ebs-volume#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/general-policies/general_3-encrypt-ebs-volume#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_3-encrypt-ebs-volume#terraform" }, "Recommendation": { - "Text": "Encrypt all EBS Snapshot and Enable Encryption by default. You can configure your AWS account to enforce the encryption of the new EBS volumes and snapshot copies that you create. For example; Amazon EBS encrypts the EBS volumes created when you launch an instance and the snapshots that you copy from an unencrypted snapshot.", + "Text": "Encrypt all EBS Snapshot and Enable Encryption by default. You can configure your AWS account to enforce the encryption of the new EBS volumes and snapshot copies that you create. For example, Amazon EBS encrypts the EBS volumes created when you launch an instance and the snapshots that you copy from an unencrypted snapshot.", "Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default" } }, diff --git a/prowler/providers/aws/services/ec2/ec2_ebs_volume_encryption/ec2_ebs_volume_encryption.metadata.json b/prowler/providers/aws/services/ec2/ec2_ebs_volume_encryption/ec2_ebs_volume_encryption.metadata.json index c13bf90bc3..45c48c30a7 100644 --- a/prowler/providers/aws/services/ec2/ec2_ebs_volume_encryption/ec2_ebs_volume_encryption.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_ebs_volume_encryption/ec2_ebs_volume_encryption.metadata.json @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Encrypt all EBS volumes and Enable Encryption by default You can configure your AWS account to enforce the encryption of the new EBS volumes and snapshot copies that you create. For example; Amazon EBS encrypts the EBS volumes created when you launch an instance and the snapshots that you copy from an unencrypted snapshot.", + "Text": "Encrypt all EBS volumes and Enable Encryption by default You can configure your AWS account to enforce the encryption of the new EBS volumes and snapshot copies that you create. For example, Amazon EBS encrypts the EBS volumes created when you launch an instance and the snapshots that you copy from an unencrypted snapshot.", "Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html" } }, diff --git a/prowler/providers/aws/services/ec2/ec2_elastic_ip_shodan/ec2_elastic_ip_shodan.metadata.json b/prowler/providers/aws/services/ec2/ec2_elastic_ip_shodan/ec2_elastic_ip_shodan.metadata.json index d92f648825..d3e722e377 100644 --- a/prowler/providers/aws/services/ec2/ec2_elastic_ip_shodan/ec2_elastic_ip_shodan.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_elastic_ip_shodan/ec2_elastic_ip_shodan.metadata.json @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Check Identified IPs; consider changing them to private ones and delete them from Shodan.", + "Text": "Check Identified IPs, consider changing them to private ones and delete them from Shodan.", "Url": "https://www.shodan.io/" } }, diff --git a/prowler/providers/aws/services/ec2/ec2_elastic_ip_unassigned/ec2_elastic_ip_unassigned.metadata.json b/prowler/providers/aws/services/ec2/ec2_elastic_ip_unassigned/ec2_elastic_ip_unassigned.metadata.json index e18b97174d..fa0a31c767 100644 --- a/prowler/providers/aws/services/ec2/ec2_elastic_ip_unassigned/ec2_elastic_ip_unassigned.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_elastic_ip_unassigned/ec2_elastic_ip_unassigned.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws ec2 release-address --public-ip ", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_19#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/general_19#ec2-console", - "Terraform": "https://docs.bridgecrew.io/docs/general_19#terraform" + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_19#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/general-policies/general_19#ec2-console", + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_19#terraform" }, "Recommendation": { "Text": "Ensure Elastic IPs are not unassigned.", diff --git a/prowler/providers/aws/services/ec2/ec2_instance_detailed_monitoring_enabled/ec2_instance_detailed_monitoring_enabled.metadata.json b/prowler/providers/aws/services/ec2/ec2_instance_detailed_monitoring_enabled/ec2_instance_detailed_monitoring_enabled.metadata.json index e653ea2fb1..206c13d383 100644 --- a/prowler/providers/aws/services/ec2/ec2_instance_detailed_monitoring_enabled/ec2_instance_detailed_monitoring_enabled.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_instance_detailed_monitoring_enabled/ec2_instance_detailed_monitoring_enabled.metadata.json @@ -18,7 +18,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EC2/instance-detailed-monitoring.html", "NativeIaC": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EC2/instance-detailed-monitoring.html", "Other": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch-new.html#enable-detailed-monitoring-instance", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-detailed-monitoring-is-enabled-for-ec2-instances#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/ensure-that-detailed-monitoring-is-enabled-for-ec2-instances#terraform" }, "Recommendation": { "Text": "Enable detailed monitoring for EC2 instances to gain better insights into performance metrics.", @@ -29,4 +29,4 @@ "DependsOn": [], "RelatedTo": [], "Notes": "" -} \ No newline at end of file +} diff --git a/prowler/providers/aws/services/ec2/ec2_instance_imdsv2_enabled/ec2_instance_imdsv2_enabled.metadata.json b/prowler/providers/aws/services/ec2/ec2_instance_imdsv2_enabled/ec2_instance_imdsv2_enabled.metadata.json index 6cb016ae8b..a83a12a9d7 100644 --- a/prowler/providers/aws/services/ec2/ec2_instance_imdsv2_enabled/ec2_instance_imdsv2_enabled.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_instance_imdsv2_enabled/ec2_instance_imdsv2_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws ec2 modify-instance-metadata-options --instance-id --http-tokens required --http-endpoint enabled", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_31#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_31#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EC2/require-imds-v2.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_31#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_31#terraform" }, "Recommendation": { "Text": "If you don't need IMDS you can turn it off. Using aws-cli you can force the instance to use only IMDSv2.", diff --git a/prowler/providers/aws/services/ec2/ec2_instance_public_ip/ec2_instance_public_ip.metadata.json b/prowler/providers/aws/services/ec2/ec2_instance_public_ip/ec2_instance_public_ip.metadata.json index 5a16a4b2d5..4689ec49e9 100644 --- a/prowler/providers/aws/services/ec2/ec2_instance_public_ip/ec2_instance_public_ip.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_instance_public_ip/ec2_instance_public_ip.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "", - "NativeIaC": "https://docs.bridgecrew.io/docs/public_12#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/public_12#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/public_12#terraform" + "NativeIaC": "https://docs.prowler.com/checks/aws/public-policies/public_12#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/public-policies/public_12#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/public-policies/public_12#terraform" }, "Recommendation": { "Text": "Use an ALB and apply WAF ACL.", diff --git a/prowler/providers/aws/services/ec2/ec2_instance_secrets_user_data/ec2_instance_secrets_user_data.metadata.json b/prowler/providers/aws/services/ec2/ec2_instance_secrets_user_data/ec2_instance_secrets_user_data.metadata.json index 958cbba594..2a72aa2c5d 100644 --- a/prowler/providers/aws/services/ec2/ec2_instance_secrets_user_data/ec2_instance_secrets_user_data.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_instance_secrets_user_data/ec2_instance_secrets_user_data.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_aws_secrets_1#cli-command", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_secrets_1#cloudformation", + "CLI": "https://docs.prowler.com/checks/aws/secrets-policies/bc_aws_secrets_1#cli-command", + "NativeIaC": "https://docs.prowler.com/checks/aws/secrets-policies/bc_aws_secrets_1#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_secrets_1#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/secrets-policies/bc_aws_secrets_1#terraform" }, "Recommendation": { "Text": "Implement automated detective control (e.g. using tools like Prowler) to scan accounts for passwords and secrets. Use secrets manager service to store and retrieve passwords and secrets.", diff --git a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22.metadata.json b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22.metadata.json index 641fb45173..7023e64248 100644 --- a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "", - "NativeIaC": "https://docs.bridgecrew.io/docs/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-22#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/networking-policies/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-22#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-22#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-22#terraform" }, "Recommendation": { "Text": "Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.", diff --git a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389.metadata.json b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389.metadata.json index 5d3ef66c36..8da6b463df 100644 --- a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "", - "NativeIaC": "https://docs.bridgecrew.io/docs/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-3389#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/networking-policies/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-3389#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-3389#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-3389#terraform" }, "Recommendation": { "Text": "Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.", diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.metadata.json b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.metadata.json index af6dd6737f..8c651385ae 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/networking_1-port-security#cli-command", - "NativeIaC": "https://docs.bridgecrew.io/docs/networking_1-port-security#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/networking_1-port-security#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/networking_1-port-security#terraform" + "CLI": "https://docs.prowler.com/checks/aws/networking-policies/networking_1-port-security#cli-command", + "NativeIaC": "https://docs.prowler.com/checks/aws/networking-policies/networking_1-port-security#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/networking-policies/networking_1-port-security#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/networking_1-port-security#terraform" }, "Recommendation": { "Text": "Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.", diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.metadata.json b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.metadata.json index 7e2648898f..772f43053e 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/networking_2#cli-command", - "NativeIaC": "https://docs.bridgecrew.io/docs/networking_2#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/networking_2#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/networking_2#terraform" + "CLI": "https://docs.prowler.com/checks/aws/networking-policies/networking_2#cli-command", + "NativeIaC": "https://docs.prowler.com/checks/aws/networking-policies/networking_2#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/networking-policies/networking_2#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/networking_2#terraform" }, "Recommendation": { "Text": "Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.", diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_default_restrict_traffic/ec2_securitygroup_default_restrict_traffic.metadata.json b/prowler/providers/aws/services/ec2/ec2_securitygroup_default_restrict_traffic/ec2_securitygroup_default_restrict_traffic.metadata.json index 30c2e50a5d..0ca5fcdd80 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_default_restrict_traffic/ec2_securitygroup_default_restrict_traffic.metadata.json +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_default_restrict_traffic/ec2_securitygroup_default_restrict_traffic.metadata.json @@ -17,8 +17,8 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/networking_4#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/networking_4#terraform" + "Other": "https://docs.prowler.com/checks/aws/networking-policies/networking_4#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/networking_4#terraform" }, "Recommendation": { "Text": "Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive security groups. Recommended best practices is to narrow the definition for the minimum ports required.", diff --git a/prowler/providers/aws/services/ec2/ec2_service.py b/prowler/providers/aws/services/ec2/ec2_service.py index 5a76d0110b..afb4e4afce 100644 --- a/prowler/providers/aws/services/ec2/ec2_service.py +++ b/prowler/providers/aws/services/ec2/ec2_service.py @@ -255,7 +255,7 @@ class EC2(AWSService): id=interface["NetworkInterfaceId"], association=interface.get("Association", {}), attachment=interface.get("Attachment", {}), - private_ip=interface["PrivateIpAddress"], + private_ip=interface.get("PrivateIpAddress"), type=interface["InterfaceType"], subnet_id=interface["SubnetId"], vpc_id=interface["VpcId"], @@ -451,7 +451,7 @@ class NetworkInterface(BaseModel): id: str association: dict attachment: dict - private_ip: str + private_ip: Optional[str] type: str subnet_id: str vpc_id: str diff --git a/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible.metadata.json index 39332d7911..38b1dba443 100644 --- a/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible.metadata.json @@ -17,8 +17,8 @@ "Remediation": { "Code": { "CLI": "", - "NativeIaC": "https://docs.bridgecrew.io/docs/public_1-ecr-repositories-not-public#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/public_1-ecr-repositories-not-public#aws-console", + "NativeIaC": "https://docs.prowler.com/checks/aws/public-policies/public_1-ecr-repositories-not-public#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/public-policies/public_1-ecr-repositories-not-public#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled.metadata.json b/prowler/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled.metadata.json index e4c2fceef9..5307cb7c3e 100644 --- a/prowler/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled.metadata.json +++ b/prowler/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled.metadata.json @@ -17,9 +17,9 @@ "Remediation": { "Code": { "CLI": "aws ecr create-repository --repository-name --image-scanning-configuration scanOnPush=true--region ", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_8#cli-command", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_8#cli-command", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/general_8#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_8#fix---buildtime" }, "Recommendation": { "Text": "Enable ECR image scanning and review the scan findings for information about the security of the container images that are being deployed.", diff --git a/prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.metadata.json b/prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.metadata.json index db7a3d0b0c..9c87a7c720 100644 --- a/prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.metadata.json +++ b/prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.metadata.json @@ -13,7 +13,7 @@ "Severity": "critical", "ResourceType": "AwsEcsTaskDefinition", "Description": "Check if secrets exists in ECS task definitions environment variables. If a secret is detected, the line number shown in the finding matches with the environment variable \"Name\" attribute starting to count at the \"environment\" key from the ECS Task Definition in JSON format.", - "Risk": "The use of a hard-coded password increases the possibility of password guessing. If hard-coded passwords are used; it is possible that malicious users gain access through the account in question.", + "Risk": "The use of a hard-coded password increases the possibility of password guessing. If hard-coded passwords are used, it is possible that malicious users gain access through the account in question.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/efs/efs_encryption_at_rest_enabled/efs_encryption_at_rest_enabled.metadata.json b/prowler/providers/aws/services/efs/efs_encryption_at_rest_enabled/efs_encryption_at_rest_enabled.metadata.json index 316c3bf68c..23938f0390 100644 --- a/prowler/providers/aws/services/efs/efs_encryption_at_rest_enabled/efs_encryption_at_rest_enabled.metadata.json +++ b/prowler/providers/aws/services/efs/efs_encryption_at_rest_enabled/efs_encryption_at_rest_enabled.metadata.json @@ -18,9 +18,9 @@ "Remediation": { "Code": { "CLI": "aws efs create-file-system --creation-token $(uuidgen) --performance-mode generalPurpose --encrypted --kms-key-id user/customer-managedCMKalias", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_17#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_17#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/general_17#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_17#terraform" }, "Recommendation": { "Text": "Ensure that encryption at rest is enabled for EFS file systems. Encryption at rest can only be enabled during the file system creation.", diff --git a/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.metadata.json index 021d8ba585..a20ee155cb 100644 --- a/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.metadata.json @@ -1,7 +1,7 @@ { "Provider": "aws", "CheckID": "efs_not_publicly_accessible", - "CheckTitle": "Check if EFS have policies which allow access to everyone", + "CheckTitle": "Check if EFS have policies which allow access to any client within the VPC", "CheckType": [ "Protect", "Data protection" @@ -9,10 +9,10 @@ "ServiceName": "efs", "SubServiceName": "", "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", - "Severity": "critical", + "Severity": "medium", "ResourceType": "AwsEFSFileSystem", - "Description": "Check if EFS have policies which allow access to everyone", - "Risk": "EFS accessible to everyone could expose sensitive data to bad actors", + "Description": "Check if EFS have policies which allow access to any client within the VPC", + "Risk": "Restricting access to EFS file systems is a security best practice. Allowing access to any client within the VPC can lead to unauthorized access to the file system.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.py b/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.py index 8cb33dfa41..98c348e139 100644 --- a/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.py +++ b/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.py @@ -1,5 +1,6 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.efs.efs_client import efs_client +from prowler.providers.aws.services.efs.lib.lib import is_public_access_allowed class efs_not_publicly_accessible(Check): @@ -12,30 +13,17 @@ class efs_not_publicly_accessible(Check): report.resource_arn = fs.arn report.resource_tags = fs.tags report.status = "PASS" - report.status_extended = ( - f"EFS {fs.id} has a policy which does not allow access to everyone." - ) + report.status_extended = f"EFS {fs.id} has a policy which does not allow access to any client within the VPC." if not fs.policy: report.status = "FAIL" - report.status_extended = f"EFS {fs.id} doesn't have any policy which means it grants full access to any client." + report.status_extended = f"EFS {fs.id} doesn't have any policy which means it grants full access to any client within the VPC." else: - for statement in fs.policy["Statement"]: - if statement["Effect"] == "Allow": - if ( - ("Principal" in statement and statement["Principal"] == "*") - or ( - "Principal" in statement - and "AWS" in statement["Principal"] - and statement["Principal"]["AWS"] == "*" - ) - or ( - "CanonicalUser" in statement["Principal"] - and statement["Principal"]["CanonicalUser"] == "*" - ) - ): - report.status = "FAIL" - report.status_extended = f"EFS {fs.id} has a policy which allows access to everyone." - break + for statement in fs.policy.get("Statement", []): + if statement.get("Effect") == "Allow" and is_public_access_allowed( + statement + ): + report.status = "FAIL" + report.status_extended = f"EFS {fs.id} has a policy which allows access to any client within the VPC." + break findings.append(report) - return findings diff --git a/prowler/providers/aws/services/efs/lib/__init__.py b/prowler/providers/aws/services/efs/lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prowler/providers/aws/services/efs/lib/lib.py b/prowler/providers/aws/services/efs/lib/lib.py new file mode 100644 index 0000000000..2d310fc369 --- /dev/null +++ b/prowler/providers/aws/services/efs/lib/lib.py @@ -0,0 +1,45 @@ +def is_public_access_allowed(statement): + """ + Check if the statement allows public access + Args: + statement: dict: Statement from the policy + Returns: + bool: True if the statement allows public access, False otherwise + """ + principal = statement.get("Principal") + if principal == "*" or (isinstance(principal, dict) and "*" in principal.values()): + return not has_secure_conditions(statement) + return False + + +def has_secure_conditions(statement): + """ + Check if the statement has secure conditions + Args: + statement: dict: Statement from the policy + Returns: + bool: True if the statement has secure conditions, False otherwise + """ + conditions = statement.get("Condition", {}) + allowed_conditions = { + "aws:SourceArn", + "aws:SourceVpc", + "aws:SourceVpce", + "aws:SourceOwner", + "aws:SourceAccount", + } + if ( + "Bool" in conditions + and conditions["Bool"].get("elasticfilesystem:AccessedViaMountTarget") == "true" + ): + return True + + # Check for conditions with nested keys + for _, conditions_dict in conditions.items(): + for key, value in conditions_dict.items(): + if isinstance(value, dict): + if set(value.keys()).intersection(allowed_conditions): + return True + elif key in allowed_conditions: + return True + return False diff --git a/prowler/providers/aws/services/eks/eks_cluster_kms_cmk_encryption_in_secrets_enabled/eks_cluster_kms_cmk_encryption_in_secrets_enabled.metadata.json b/prowler/providers/aws/services/eks/eks_cluster_kms_cmk_encryption_in_secrets_enabled/eks_cluster_kms_cmk_encryption_in_secrets_enabled.metadata.json index 6f5321a7d2..655400ae79 100644 --- a/prowler/providers/aws/services/eks/eks_cluster_kms_cmk_encryption_in_secrets_enabled/eks_cluster_kms_cmk_encryption_in_secrets_enabled.metadata.json +++ b/prowler/providers/aws/services/eks/eks_cluster_kms_cmk_encryption_in_secrets_enabled/eks_cluster_kms_cmk_encryption_in_secrets_enabled.metadata.json @@ -17,7 +17,7 @@ "Remediation": { "Code": { "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/enable-envelope-encryption.html", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_kubernetes_3#fix---builtime", + "NativeIaC": "https://docs.prowler.com/checks/aws/kubernetes-policies-1/bc_aws_kubernetes_3#fix---builtime", "Other": "", "Terraform": "" }, diff --git a/prowler/providers/aws/services/eks/eks_cluster_network_policy_enabled/eks_cluster_network_policy_enabled.metadata.json b/prowler/providers/aws/services/eks/eks_cluster_network_policy_enabled/eks_cluster_network_policy_enabled.metadata.json index 1692b37508..8f2c2247a2 100644 --- a/prowler/providers/aws/services/eks/eks_cluster_network_policy_enabled/eks_cluster_network_policy_enabled.metadata.json +++ b/prowler/providers/aws/services/eks/eks_cluster_network_policy_enabled/eks_cluster_network_policy_enabled.metadata.json @@ -19,7 +19,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/security-groups.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_kubernetes_1#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/kubernetes-policies-1/bc_aws_kubernetes_1#terraform" }, "Recommendation": { "Text": "Enable and configure Network Policy to enhance network security within the EKS cluster.", diff --git a/prowler/providers/aws/services/eks/eks_control_plane_endpoint_access_restricted/eks_control_plane_endpoint_access_restricted.metadata.json b/prowler/providers/aws/services/eks/eks_control_plane_endpoint_access_restricted/eks_control_plane_endpoint_access_restricted.metadata.json index ccf3c75cfd..c72fe7ff3f 100644 --- a/prowler/providers/aws/services/eks/eks_control_plane_endpoint_access_restricted/eks_control_plane_endpoint_access_restricted.metadata.json +++ b/prowler/providers/aws/services/eks/eks_control_plane_endpoint_access_restricted/eks_control_plane_endpoint_access_restricted.metadata.json @@ -11,7 +11,7 @@ "Severity": "medium", "ResourceType": "AwsEksCluster", "Description": "Restrict Access to the EKS Control Plane Endpoint", - "Risk": "By default; this API server endpoint is public to the internet; and access to the API server is secured using a combination of AWS Identity and Access Management (IAM) and native Kubernetes Role Based Access Control (RBAC).", + "Risk": "By default, this API server endpoint is public to the internet, and access to the API server is secured using a combination of AWS Identity and Access Management (IAM) and native Kubernetes Role Based Access Control (RBAC).", "RelatedUrl": "", "Remediation": { "Code": { @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "You should enable private access to the Kubernetes API server so that all communication between your nodes and the API server stays within your VPC. You can limit the IP addresses that can access your API server from the internet; or completely disable internet access to the API server.", + "Text": "You should enable private access to the Kubernetes API server so that all communication between your nodes and the API server stays within your VPC. You can limit the IP addresses that can access your API server from the internet, or completely disable internet access to the API server.", "Url": "https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html" } }, diff --git a/prowler/providers/aws/services/eks/eks_control_plane_logging_all_types_enabled/eks_control_plane_logging_all_types_enabled.metadata.json b/prowler/providers/aws/services/eks/eks_control_plane_logging_all_types_enabled/eks_control_plane_logging_all_types_enabled.metadata.json index 07f479d1be..d35ac30f10 100644 --- a/prowler/providers/aws/services/eks/eks_control_plane_logging_all_types_enabled/eks_control_plane_logging_all_types_enabled.metadata.json +++ b/prowler/providers/aws/services/eks/eks_control_plane_logging_all_types_enabled/eks_control_plane_logging_all_types_enabled.metadata.json @@ -11,14 +11,14 @@ "Severity": "medium", "ResourceType": "AwsEksCluster", "Description": "Ensure EKS Control Plane Audit Logging is enabled for all log types", - "Risk": "If logs are not enabled; monitoring of service use and threat analysis is not possible.", + "Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.", "RelatedUrl": "", "Remediation": { "Code": { "CLI": "aws eks update-cluster-config --region --name --logging '{\"clusterLogging\":[{\"types\":[\"api\",\"audit\",\"authenticator\",\"controllerManager\",\"scheduler\"],\"enabled\":true}]}'", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/bc_aws_kubernetes_4#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_kubernetes_4#fix---buildtime" + "Other": "https://docs.prowler.com/checks/aws/kubernetes-policies-1/bc_aws_kubernetes_4#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/kubernetes-policies-1/bc_aws_kubernetes_4#fix---buildtime" }, "Recommendation": { "Text": "Make sure you logging for EKS control plane is enabled.", diff --git a/prowler/providers/aws/services/elasticache/elasticache_service.py b/prowler/providers/aws/services/elasticache/elasticache_service.py index 4f33c1280a..44f7a7551d 100644 --- a/prowler/providers/aws/services/elasticache/elasticache_service.py +++ b/prowler/providers/aws/services/elasticache/elasticache_service.py @@ -32,7 +32,9 @@ class ElastiCache(AWSService): id=cache_cluster["CacheClusterId"], arn=cluster_arn, region=regional_client.region, - cache_subnet_group_id=cache_cluster["CacheSubnetGroupName"], + cache_subnet_group_id=cache_cluster.get( + "CacheSubnetGroupName", None + ), ) except Exception as error: logger.error( @@ -46,16 +48,17 @@ class ElastiCache(AWSService): if cluster.region == regional_client.region: try: subnets = [] - cache_subnet_groups = ( - regional_client.describe_cache_subnet_groups( - CacheSubnetGroupName=cluster.cache_subnet_group_id - )["CacheSubnetGroups"] - ) - for subnet_group in cache_subnet_groups: - for subnet in subnet_group["Subnets"]: - subnets.append(subnet["SubnetIdentifier"]) + if cluster.cache_subnet_group_id: + cache_subnet_groups = ( + regional_client.describe_cache_subnet_groups( + CacheSubnetGroupName=cluster.cache_subnet_group_id + )["CacheSubnetGroups"] + ) + for subnet_group in cache_subnet_groups: + for subnet in subnet_group["Subnets"]: + subnets.append(subnet["SubnetIdentifier"]) - cluster.subnets = subnets + cluster.subnets = subnets except Exception as error: logger.error( f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -97,6 +100,6 @@ class Cluster(BaseModel): id: str arn: str region: str - cache_subnet_group_id: str + cache_subnet_group_id: Optional[str] subnets: Optional[list] tags: Optional[list] diff --git a/prowler/providers/aws/services/elb/elb_insecure_ssl_ciphers/elb_insecure_ssl_ciphers.metadata.json b/prowler/providers/aws/services/elb/elb_insecure_ssl_ciphers/elb_insecure_ssl_ciphers.metadata.json index 7cd63d80e2..89418dd70e 100644 --- a/prowler/providers/aws/services/elb/elb_insecure_ssl_ciphers/elb_insecure_ssl_ciphers.metadata.json +++ b/prowler/providers/aws/services/elb/elb_insecure_ssl_ciphers/elb_insecure_ssl_ciphers.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws elb set-load-balancer-policies-of-listener --load-balancer-name --load-balancer-port 443 --policy-names ELBSecurityPolicy-TLS-1-2-2017-01", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/ELB/elb-security-policy.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_43#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_43#terraform" }, "Recommendation": { "Text": "Use a Security policy with ciphers that are as strong as possible. Drop legacy and insecure ciphers.", diff --git a/prowler/providers/aws/services/elb/elb_logging_enabled/elb_logging_enabled.metadata.json b/prowler/providers/aws/services/elb/elb_logging_enabled/elb_logging_enabled.metadata.json index 4a5f7b8562..9483ccf127 100644 --- a/prowler/providers/aws/services/elb/elb_logging_enabled/elb_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/elb/elb_logging_enabled/elb_logging_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws elb modify-load-balancer-attributes --load-balancer-name --load-balancer-attributes '{AccessLog:{Enabled:true,EmitInterval:60,S3BucketName:}}'", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_logging_23#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_23#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/ELB/elb-access-log.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_logging_23#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_23#terraform" }, "Recommendation": { "Text": "Enable ELB logging, create a log lifecycle and define use cases.", diff --git a/prowler/providers/aws/services/elbv2/elbv2_deletion_protection/elbv2_deletion_protection.metadata.json b/prowler/providers/aws/services/elbv2/elbv2_deletion_protection/elbv2_deletion_protection.metadata.json index 5c1d96838d..4f5f5784f0 100644 --- a/prowler/providers/aws/services/elbv2/elbv2_deletion_protection/elbv2_deletion_protection.metadata.json +++ b/prowler/providers/aws/services/elbv2/elbv2_deletion_protection/elbv2_deletion_protection.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws elbv2 modify-load-balancer-attributes --load-balancer-arn --attributes Key=deletion_protection.enabled,Value=true", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/ELBv2/deletion-protection.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_networking_62#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_networking_62#terraform" }, "Recommendation": { "Text": "Enable deletion protection attribute, this is not enabled by default.", diff --git a/prowler/providers/aws/services/elbv2/elbv2_desync_mitigation_mode/elbv2_desync_mitigation_mode.metadata.json b/prowler/providers/aws/services/elbv2/elbv2_desync_mitigation_mode/elbv2_desync_mitigation_mode.metadata.json index e051d4e962..e86e1064ee 100644 --- a/prowler/providers/aws/services/elbv2/elbv2_desync_mitigation_mode/elbv2_desync_mitigation_mode.metadata.json +++ b/prowler/providers/aws/services/elbv2/elbv2_desync_mitigation_mode/elbv2_desync_mitigation_mode.metadata.json @@ -11,7 +11,7 @@ "Severity": "medium", "ResourceType": "AwsElasticLoadBalancingV2LoadBalancer", "Description": "Check whether the Application Load Balancer is configured with strictest desync mitigation mode, if not check if at least is configured with the drop_invalid_header_fields attribute", - "Risk": "HTTP Desync issues can lead to request smuggling and make your applications vulnerable to request queue or cache poisoning; which could lead to credential hijacking or execution of unauthorized commands.", + "Risk": "HTTP Desync issues can lead to request smuggling and make your applications vulnerable to request queue or cache poisoning, which could lead to credential hijacking or execution of unauthorized commands.", "RelatedUrl": "https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#desync-mitigation-mode", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/elbv2/elbv2_insecure_ssl_ciphers/elbv2_insecure_ssl_ciphers.metadata.json b/prowler/providers/aws/services/elbv2/elbv2_insecure_ssl_ciphers/elbv2_insecure_ssl_ciphers.metadata.json index 5945ca6c79..aa2686ac75 100644 --- a/prowler/providers/aws/services/elbv2/elbv2_insecure_ssl_ciphers/elbv2_insecure_ssl_ciphers.metadata.json +++ b/prowler/providers/aws/services/elbv2/elbv2_insecure_ssl_ciphers/elbv2_insecure_ssl_ciphers.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws elbv2 modify-listener --listener-arn --ssl-policy ELBSecurityPolicy-TLS13-1-2-Ext2-2021-06", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/ELBv2/security-policy.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_43#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_43#terraform" }, "Recommendation": { "Text": "Use a Security policy with ciphers that are as strong as possible. Drop legacy and insecure ciphers.", diff --git a/prowler/providers/aws/services/elbv2/elbv2_logging_enabled/elbv2_logging_enabled.metadata.json b/prowler/providers/aws/services/elbv2/elbv2_logging_enabled/elbv2_logging_enabled.metadata.json index 6107d59a7a..fe9a89e3e1 100644 --- a/prowler/providers/aws/services/elbv2/elbv2_logging_enabled/elbv2_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/elbv2/elbv2_logging_enabled/elbv2_logging_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws elbv2 modify-load-balancer-attributes --load-balancer-arn --attributes Key=access_logs.s3.enabled,Value=true Key=access_logs.s3.bucket,Value= Key=access_logs.s3.prefix,Value=", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_logging_22#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_22#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/ELBv2/access-log.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_logging_22#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_22#terraform" }, "Recommendation": { "Text": "Enable ELB logging, create a log lifecycle and define use cases.", diff --git a/prowler/providers/aws/services/elbv2/elbv2_ssl_listeners/elbv2_ssl_listeners.metadata.json b/prowler/providers/aws/services/elbv2/elbv2_ssl_listeners/elbv2_ssl_listeners.metadata.json index 5f75098581..22dbe8e79b 100644 --- a/prowler/providers/aws/services/elbv2/elbv2_ssl_listeners/elbv2_ssl_listeners.metadata.json +++ b/prowler/providers/aws/services/elbv2/elbv2_ssl_listeners/elbv2_ssl_listeners.metadata.json @@ -17,7 +17,7 @@ "Code": { "CLI": "aws elbv2 create-listener --load-balancer-arn --protocol HTTPS --port 443 --ssl-policy --certificates CertificateArn=,IsDefault=true", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/networking_36#aws-ec2-console", + "Other": "https://docs.prowler.com/checks/aws/networking-policies/networking_36#aws-ec2-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/emr/emr_cluster_publicly_accesible/emr_cluster_publicly_accesible.metadata.json b/prowler/providers/aws/services/emr/emr_cluster_publicly_accesible/emr_cluster_publicly_accesible.metadata.json index 079a15b340..a207a575ba 100644 --- a/prowler/providers/aws/services/emr/emr_cluster_publicly_accesible/emr_cluster_publicly_accesible.metadata.json +++ b/prowler/providers/aws/services/emr/emr_cluster_publicly_accesible/emr_cluster_publicly_accesible.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-amazon-emr-clusters-security-groups-are-not-open-to-the-world#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/ensure-that-amazon-emr-clusters-security-groups-are-not-open-to-the-world#terraform" }, "Recommendation": { "Text": "Only make acceptable EMR clusters public.", diff --git a/prowler/providers/aws/services/fms/fms_service.py b/prowler/providers/aws/services/fms/fms_service.py index a241b44b7d..45d3db0331 100644 --- a/prowler/providers/aws/services/fms/fms_service.py +++ b/prowler/providers/aws/services/fms/fms_service.py @@ -52,6 +52,11 @@ class FMS(AWSService): ): # FMS is not enabled in this account self.fms_admin_account = False + else: + logger.error( + f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" + ) + self.fms_admin_account = None except Exception as error: logger.error( f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" diff --git a/prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json b/prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json index dd65072ff2..2e8333cd68 100644 --- a/prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json +++ b/prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-glacier-vault-access-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-glacier-vault-access-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform" }, "Recommendation": { "Text": "Ensure vault policy does not have principle as *.", diff --git a/prowler/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled.metadata.json b/prowler/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled.metadata.json index 689651474b..202daa40ba 100644 --- a/prowler/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled.metadata.json @@ -16,12 +16,12 @@ "Remediation": { "Code": { "CLI": "aws glue put-data-catalog-encryption-settings --data-catalog-encryption-settings ConnectionPasswordEncryption={ReturnConnectionPasswordEncrypted=True,AwsKmsKeyId=", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_37#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_37#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_37#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_37#terraform" }, "Recommendation": { - "Text": "On the AWS Glue console; you can enable this option on the Data catalog settings page.", + "Text": "On the AWS Glue console, you can enable this option on the Data catalog settings page.", "Url": "https://docs.aws.amazon.com/glue/latest/dg/encrypt-connection-passwords.html" } }, diff --git a/prowler/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled.metadata.json b/prowler/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled.metadata.json index daf0d0b228..5653ae151e 100644 --- a/prowler/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws glue put-data-catalog-encryption-settings --data-catalog-encryption-settings EncryptionAtRest={CatalogEncryptionMode=SSE-KMS,SseAwsKmsKeyId=", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_37#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_37#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/data-catalog-encryption-at-rest.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_37#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_37#terraform" }, "Recommendation": { "Text": "Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits.", diff --git a/prowler/providers/aws/services/glue/glue_development_endpoints_cloudwatch_logs_encryption_enabled/glue_development_endpoints_cloudwatch_logs_encryption_enabled.metadata.json b/prowler/providers/aws/services/glue/glue_development_endpoints_cloudwatch_logs_encryption_enabled/glue_development_endpoints_cloudwatch_logs_encryption_enabled.metadata.json index 5f0fbed394..dbba2e8f5a 100644 --- a/prowler/providers/aws/services/glue/glue_development_endpoints_cloudwatch_logs_encryption_enabled/glue_development_endpoints_cloudwatch_logs_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/glue/glue_development_endpoints_cloudwatch_logs_encryption_enabled/glue_development_endpoints_cloudwatch_logs_encryption_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws glue create-security-configuration --name cw-encrypted-sec-config --encryption-configuration {'CloudWatchEncryption': [{'CloudWatchEncryptionMode': 'SSE-KMS','KmsKeyArn': }]}", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/cloud-watch-logs-encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#terraform" }, "Recommendation": { "Text": "Enable Encryption in the Security configurations.", diff --git a/prowler/providers/aws/services/glue/glue_development_endpoints_job_bookmark_encryption_enabled/glue_development_endpoints_job_bookmark_encryption_enabled.metadata.json b/prowler/providers/aws/services/glue/glue_development_endpoints_job_bookmark_encryption_enabled/glue_development_endpoints_job_bookmark_encryption_enabled.metadata.json index 8c7c4c7a9a..d62d2be5c1 100644 --- a/prowler/providers/aws/services/glue/glue_development_endpoints_job_bookmark_encryption_enabled/glue_development_endpoints_job_bookmark_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/glue/glue_development_endpoints_job_bookmark_encryption_enabled/glue_development_endpoints_job_bookmark_encryption_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws glue create-security-configuration --name jb-encrypted-sec-config --encryption-configuration {'JobBookmarksEncryption': [{'JobBookmarksEncryptionMode': 'SSE-KMS','KmsKeyArn': }]}", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/job-bookmark-encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#terraform" }, "Recommendation": { "Text": "Enable Encryption in the Security configurations.", diff --git a/prowler/providers/aws/services/glue/glue_development_endpoints_s3_encryption_enabled/glue_development_endpoints_s3_encryption_enabled.metadata.json b/prowler/providers/aws/services/glue/glue_development_endpoints_s3_encryption_enabled/glue_development_endpoints_s3_encryption_enabled.metadata.json index a438e9b48b..56931fad5f 100644 --- a/prowler/providers/aws/services/glue/glue_development_endpoints_s3_encryption_enabled/glue_development_endpoints_s3_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/glue/glue_development_endpoints_s3_encryption_enabled/glue_development_endpoints_s3_encryption_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws glue create-security-configuration --name s3-encrypted-sec-config --encryption-configuration {'S3Encryption': [{'S3EncryptionMode': 'SSE-KMS','KmsKeyArn': }]}", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/s3-encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#terraform" }, "Recommendation": { "Text": "Specify AWS KMS keys to use for input and output from S3 and EBS.", diff --git a/prowler/providers/aws/services/glue/glue_etl_jobs_amazon_s3_encryption_enabled/glue_etl_jobs_amazon_s3_encryption_enabled.metadata.json b/prowler/providers/aws/services/glue/glue_etl_jobs_amazon_s3_encryption_enabled/glue_etl_jobs_amazon_s3_encryption_enabled.metadata.json index 3b125535cd..2bbcf97789 100644 --- a/prowler/providers/aws/services/glue/glue_etl_jobs_amazon_s3_encryption_enabled/glue_etl_jobs_amazon_s3_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/glue/glue_etl_jobs_amazon_s3_encryption_enabled/glue_etl_jobs_amazon_s3_encryption_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws glue create-security-configuration --name s3-encrypted-sec-config --encryption-configuration {'S3Encryption': [{'S3EncryptionMode': 'SSE-KMS','KmsKeyArn': }]}", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/s3-encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#terraform" }, "Recommendation": { "Text": "Provide the encryption properties that are used by crawlers, jobs and development endpoints.", diff --git a/prowler/providers/aws/services/glue/glue_etl_jobs_cloudwatch_logs_encryption_enabled/glue_etl_jobs_cloudwatch_logs_encryption_enabled.metadata.json b/prowler/providers/aws/services/glue/glue_etl_jobs_cloudwatch_logs_encryption_enabled/glue_etl_jobs_cloudwatch_logs_encryption_enabled.metadata.json index b21f1126ac..99130b8bc3 100644 --- a/prowler/providers/aws/services/glue/glue_etl_jobs_cloudwatch_logs_encryption_enabled/glue_etl_jobs_cloudwatch_logs_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/glue/glue_etl_jobs_cloudwatch_logs_encryption_enabled/glue_etl_jobs_cloudwatch_logs_encryption_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws glue create-security-configuration --name cw-encrypted-sec-config --encryption-configuration {'CloudWatchEncryption': [{'CloudWatchEncryptionMode': 'SSE-KMS','KmsKeyArn': }]}", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/cloud-watch-logs-encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#terraform" }, "Recommendation": { "Text": "Enable Encryption in the Security configurations.", diff --git a/prowler/providers/aws/services/glue/glue_etl_jobs_job_bookmark_encryption_enabled/glue_etl_jobs_job_bookmark_encryption_enabled.metadata.json b/prowler/providers/aws/services/glue/glue_etl_jobs_job_bookmark_encryption_enabled/glue_etl_jobs_job_bookmark_encryption_enabled.metadata.json index 3620c6ce39..70673bc0c0 100644 --- a/prowler/providers/aws/services/glue/glue_etl_jobs_job_bookmark_encryption_enabled/glue_etl_jobs_job_bookmark_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/glue/glue_etl_jobs_job_bookmark_encryption_enabled/glue_etl_jobs_job_bookmark_encryption_enabled.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws glue create-security-configuration --name jb-encrypted-sec-config --encryption-configuration {'JobBookmarksEncryption': [{'JobBookmarksEncryptionMode': 'SSE-KMS','KmsKeyArn': }]}", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/job-bookmark-encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_41#terraform" }, "Recommendation": { "Text": "Enable Encryption in the Security configurations.", diff --git a/prowler/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled.metadata.json b/prowler/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled.metadata.json index f0fdae6523..698c7b31b5 100644 --- a/prowler/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled.metadata.json +++ b/prowler/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/GuardDuty/guardduty-enabled.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/GuardDuty/guardduty-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-guardduty-is-enabled-to-specific-orgregion#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-guardduty-is-enabled-to-specific-orgregion#fix---buildtime" }, "Recommendation": { "Text": "Enable GuardDuty and analyze its findings.", 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 index ff197b5711..f1852ac1c1 100644 --- 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 @@ -13,17 +13,17 @@ "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.", + "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", + "CLI": "https://docs.prowler.com/checks/aws/iam-policies/iam_47#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/iam_47#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/iam_47#terraform" + "Other": "https://docs.prowler.com/checks/aws/iam-policies/iam_47#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/iam-policies/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.", + "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" } }, 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 index d2d9454637..962cd9e8c4 100644 --- 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 @@ -13,17 +13,17 @@ "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.", + "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", + "CLI": "https://docs.prowler.com/checks/aws/iam-policies/iam_47#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/iam_47#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/iam_47#terraform" + "Other": "https://docs.prowler.com/checks/aws/iam-policies/iam_47#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/iam-policies/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.", + "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" } }, diff --git a/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_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 index 74e27a2930..4aff2c74e5 100644 --- a/prowler/providers/aws/services/iam/iam_customer_unattached_policy_no_administrative_privileges/iam_customer_unattached_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 @@ -13,17 +13,17 @@ "Severity": "low", "ResourceType": "AwsIamPolicy", "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.", + "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", + "CLI": "https://docs.prowler.com/checks/aws/iam-policies/iam_47#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/iam_47#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/iam_47#terraform" + "Other": "https://docs.prowler.com/checks/aws/iam-policies/iam_47#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/iam-policies/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.", + "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" } }, diff --git a/prowler/providers/aws/services/iam/iam_inline_policy_no_administrative_privileges/iam_inline_policy_no_administrative_privileges.metadata.json b/prowler/providers/aws/services/iam/iam_inline_policy_no_administrative_privileges/iam_inline_policy_no_administrative_privileges.metadata.json index a9abc21164..20eb42eb41 100644 --- a/prowler/providers/aws/services/iam/iam_inline_policy_no_administrative_privileges/iam_inline_policy_no_administrative_privileges.metadata.json +++ b/prowler/providers/aws/services/iam/iam_inline_policy_no_administrative_privileges/iam_inline_policy_no_administrative_privileges.metadata.json @@ -13,17 +13,17 @@ "Severity": "high", "ResourceType": "AwsIamRole", "Description": "Ensure inline policies that allow full \"*:*\" administrative privileges are not associated to IAM identities", - "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.", + "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", + "CLI": "https://docs.prowler.com/checks/aws/iam-policies/iam_47#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/iam_47#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/iam_47#terraform" + "Other": "https://docs.prowler.com/checks/aws/iam-policies/iam_47#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/iam-policies/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.", + "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" } }, diff --git a/prowler/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less.py b/prowler/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less.py index ebb79f1437..4ae79d62ce 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less.py @@ -5,12 +5,11 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_password_policy_expires_passwords_within_90_days_or_less(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = iam_client.password_policy_arn_template - report.resource_id = iam_client.audited_account - # Check if password policy exists if iam_client.password_policy: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = iam_client.password_policy_arn_template + report.resource_id = iam_client.audited_account # Check if password policy expiration exists if iam_client.password_policy.max_age: if iam_client.password_policy.max_age <= 90: @@ -22,9 +21,6 @@ class iam_password_policy_expires_passwords_within_90_days_or_less(Check): else: report.status = "FAIL" report.status_extended = "Password expiration is not set." - else: - report.status = "FAIL" - report.status_extended = "Password policy cannot be found." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase.py b/prowler/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase.py index 4d7d5212e1..052db73bf5 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase.py @@ -5,12 +5,11 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_password_policy_lowercase(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = iam_client.password_policy_arn_template - report.resource_id = iam_client.audited_account - # Check if password policy exists if iam_client.password_policy: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = iam_client.password_policy_arn_template + report.resource_id = iam_client.audited_account # Check if lowercase flag is set if iam_client.password_policy.lowercase: report.status = "PASS" @@ -20,8 +19,5 @@ class iam_password_policy_lowercase(Check): else: report.status = "FAIL" report.status_extended = "IAM password policy does not require at least one lowercase letter." - else: - report.status = "FAIL" - report.status_extended = "Password policy cannot be found." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14.py b/prowler/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14.py index 74e9443dbb..452dee6e3a 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14.py @@ -5,12 +5,11 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_password_policy_minimum_length_14(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = iam_client.password_policy_arn_template - report.resource_id = iam_client.audited_account - # Check if password policy exists if iam_client.password_policy: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = iam_client.password_policy_arn_template + report.resource_id = iam_client.audited_account # Check password policy length if ( iam_client.password_policy.length @@ -23,8 +22,5 @@ class iam_password_policy_minimum_length_14(Check): else: report.status = "FAIL" report.status_extended = "IAM password policy does not require minimum length of 14 characters." - else: - report.status = "FAIL" - report.status_extended = "Password policy cannot be found." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number.py b/prowler/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number.py index 22f6f6d73a..aaa2956efc 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number.py @@ -5,12 +5,11 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_password_policy_number(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = iam_client.password_policy_arn_template - report.resource_id = iam_client.audited_account - # Check if password policy exists if iam_client.password_policy: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = iam_client.password_policy_arn_template + report.resource_id = iam_client.audited_account # Check if number flag is set if iam_client.password_policy.numbers: report.status = "PASS" @@ -22,8 +21,5 @@ class iam_password_policy_number(Check): report.status_extended = ( "IAM password policy does not require at least one number." ) - else: - report.status = "FAIL" - report.status_extended = "Password policy cannot be found." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24.py b/prowler/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24.py index e06ce4e51c..8ee47908bd 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24.py @@ -5,12 +5,11 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_password_policy_reuse_24(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = iam_client.password_policy_arn_template - report.resource_id = iam_client.audited_account - # Check if password policy exists if iam_client.password_policy: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = iam_client.password_policy_arn_template + report.resource_id = iam_client.audited_account # Check if reuse prevention flag is set if ( iam_client.password_policy.reuse_prevention @@ -25,8 +24,5 @@ class iam_password_policy_reuse_24(Check): report.status_extended = ( "IAM password policy reuse prevention is less than 24 or not set." ) - else: - report.status = "FAIL" - report.status_extended = "Password policy cannot be found." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol.py b/prowler/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol.py index d5d83cc765..2074e8e67a 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol.py @@ -5,12 +5,11 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_password_policy_symbol(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = iam_client.password_policy_arn_template - report.resource_id = iam_client.audited_account - # Check if password policy exists if iam_client.password_policy: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = iam_client.password_policy_arn_template + report.resource_id = iam_client.audited_account # Check if symbol flag is set if iam_client.password_policy.symbols: report.status = "PASS" @@ -22,8 +21,5 @@ class iam_password_policy_symbol(Check): report.status_extended = ( "IAM password policy does not require at least one symbol." ) - else: - report.status = "FAIL" - report.status_extended = "Password policy cannot be found." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase.py b/prowler/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase.py index 176dfabcfc..e7afbddace 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase.py @@ -5,12 +5,11 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_password_policy_uppercase(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = iam_client.password_policy_arn_template - report.resource_id = iam_client.audited_account - # Check if password policy exists if iam_client.password_policy: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = iam_client.password_policy_arn_template + report.resource_id = iam_client.audited_account # Check if uppercase flag is set if iam_client.password_policy.uppercase: report.status = "PASS" @@ -20,8 +19,5 @@ class iam_password_policy_uppercase(Check): else: report.status = "FAIL" report.status_extended = "IAM password policy does not require at least one uppercase letter." - else: - report.status = "FAIL" - report.status_extended = "Password policy cannot be found." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles.metadata.json b/prowler/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles.metadata.json index f1ba63c4db..0796299558 100644 --- a/prowler/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles.metadata.json +++ b/prowler/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles.metadata.json @@ -13,7 +13,7 @@ "Severity": "low", "ResourceType": "AwsIamUser", "Description": "Ensure IAM policies are attached only to groups or roles", - "Risk": "By default IAM users; groups; and roles have no access to AWS resources. IAM policies are the means by which privileges are granted to users; groups; or roles. It is recommended that IAM policies be applied directly to groups and roles but not users. Assigning privileges at the group or role level reduces the complexity of access management as the number of users grow. Reducing access management complexity may in-turn reduce opportunity for a principal to inadvertently receive or retain excessive privileges.", + "Risk": "By default IAM users, groups, and roles have no access to AWS resources. IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended that IAM policies be applied directly to groups and roles but not users. Assigning privileges at the group or role level reduces the complexity of access management as the number of users grow. Reducing access management complexity may in-turn reduce opportunity for a principal to inadvertently receive or retain excessive privileges.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail.metadata.json b/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail.metadata.json index dc2832749f..5bd829a179 100644 --- a/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail.metadata.json +++ b/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_cloudtrail/iam_policy_no_full_access_to_cloudtrail.metadata.json @@ -23,7 +23,7 @@ "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.", + "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" } }, diff --git a/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms.metadata.json b/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms.metadata.json index 02db1baae8..03307fba01 100644 --- a/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms.metadata.json +++ b/prowler/providers/aws/services/iam/iam_policy_no_full_access_to_kms/iam_policy_no_full_access_to_kms.metadata.json @@ -23,7 +23,7 @@ "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.", + "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" } }, diff --git a/prowler/providers/aws/services/iam/iam_role_administratoraccess_policy/iam_role_administratoraccess_policy.py b/prowler/providers/aws/services/iam/iam_role_administratoraccess_policy/iam_role_administratoraccess_policy.py index 7cb42cd3dc..2889f291fa 100644 --- a/prowler/providers/aws/services/iam/iam_role_administratoraccess_policy/iam_role_administratoraccess_policy.py +++ b/prowler/providers/aws/services/iam/iam_role_administratoraccess_policy/iam_role_administratoraccess_policy.py @@ -5,24 +5,23 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_role_administratoraccess_policy(Check): def execute(self) -> Check_Report_AWS: findings = [] - for role in iam_client.roles: - if ( - not role.is_service_role - ): # Avoid service roles since they cannot be modified by the user - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = role.arn - report.resource_id = role.name - report.resource_tags = role.tags - report.status = "PASS" - report.status_extended = ( - f"IAM Role {role.name} does not have AdministratorAccess policy." - ) - for policy in role.attached_policies: - if policy["PolicyName"] == "AdministratorAccess": - report.status_extended = f"IAM Role {role.name} has AdministratorAccess policy attached." - report.status = "FAIL" + if iam_client.roles: + for role in iam_client.roles: + if ( + not role.is_service_role + ): # Avoid service roles since they cannot be modified by the user + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = role.arn + report.resource_id = role.name + report.resource_tags = role.tags + report.status = "PASS" + report.status_extended = f"IAM Role {role.name} does not have AdministratorAccess policy." + for policy in role.attached_policies: + if policy["PolicyName"] == "AdministratorAccess": + report.status_extended = f"IAM Role {role.name} has AdministratorAccess policy attached." + report.status = "FAIL" - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_role_cross_account_readonlyaccess_policy/iam_role_cross_account_readonlyaccess_policy.py b/prowler/providers/aws/services/iam/iam_role_cross_account_readonlyaccess_policy/iam_role_cross_account_readonlyaccess_policy.py index 605ca3350a..4f71f0a4e5 100644 --- a/prowler/providers/aws/services/iam/iam_role_cross_account_readonlyaccess_policy/iam_role_cross_account_readonlyaccess_policy.py +++ b/prowler/providers/aws/services/iam/iam_role_cross_account_readonlyaccess_policy/iam_role_cross_account_readonlyaccess_policy.py @@ -5,78 +5,82 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_role_cross_account_readonlyaccess_policy(Check): def execute(self) -> Check_Report_AWS: findings = [] - for role in iam_client.roles: - if ( - not role.is_service_role - ): # Avoid service roles since they cannot be modified by the user - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = role.arn - report.resource_id = role.name - report.resource_tags = role.tags - report.status = "PASS" - report.status_extended = ( - f"IAM Role {role.name} does not have ReadOnlyAccess policy." - ) - for policy in role.attached_policies: - if policy["PolicyName"] == "ReadOnlyAccess": - report.status_extended = f"IAM Role {role.name} has read-only access but is not cross account." - cross_account_access = False - if isinstance(role.assume_role_policy["Statement"], list): - for statement in role.assume_role_policy["Statement"]: - if not cross_account_access: - if ( - statement["Effect"] == "Allow" - and "AWS" in statement["Principal"] - ): - if isinstance( - statement["Principal"]["AWS"], list + if iam_client.roles: + for role in iam_client.roles: + if ( + not role.is_service_role + ): # Avoid service roles since they cannot be modified by the user + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = role.arn + report.resource_id = role.name + report.resource_tags = role.tags + report.status = "PASS" + report.status_extended = ( + f"IAM Role {role.name} does not have ReadOnlyAccess policy." + ) + for policy in role.attached_policies: + if policy["PolicyName"] == "ReadOnlyAccess": + report.status_extended = f"IAM Role {role.name} has read-only access but is not cross account." + cross_account_access = False + if isinstance(role.assume_role_policy["Statement"], list): + for statement in role.assume_role_policy["Statement"]: + if not cross_account_access: + if ( + statement["Effect"] == "Allow" + and "AWS" in statement["Principal"] ): - for aws_account in statement["Principal"][ - "AWS" - ]: + if isinstance( + statement["Principal"]["AWS"], list + ): + for aws_account in statement[ + "Principal" + ]["AWS"]: + if ( + iam_client.audited_account + not in aws_account + or "*" == aws_account + ): + cross_account_access = True + break + else: if ( iam_client.audited_account - not in aws_account - or "*" == aws_account + not in statement["Principal"]["AWS"] + or "*" + == statement["Principal"]["AWS"] ): cross_account_access = True - break - else: + else: + break + else: + statement = role.assume_role_policy["Statement"] + if ( + statement["Effect"] == "Allow" + and "AWS" in statement["Principal"] + ): + if isinstance(statement["Principal"]["AWS"], list): + for aws_account in statement["Principal"][ + "AWS" + ]: if ( iam_client.audited_account - not in statement["Principal"]["AWS"] - or "*" == statement["Principal"]["AWS"] + not in aws_account + or "*" == aws_account ): cross_account_access = True - else: - break - else: - statement = role.assume_role_policy["Statement"] - if ( - statement["Effect"] == "Allow" - and "AWS" in statement["Principal"] - ): - if isinstance(statement["Principal"]["AWS"], list): - for aws_account in statement["Principal"]["AWS"]: + break + else: if ( iam_client.audited_account - not in aws_account - or "*" == aws_account + not in statement["Principal"]["AWS"] + or "*" == statement["Principal"]["AWS"] ): cross_account_access = True - break - else: - if ( - iam_client.audited_account - not in statement["Principal"]["AWS"] - or "*" == statement["Principal"]["AWS"] - ): - cross_account_access = True - if cross_account_access: - report.status = "FAIL" - report.status_extended = f"IAM Role {role.name} gives cross account read-only access." + if cross_account_access: + report.status = "FAIL" + report.status_extended = f"IAM Role {role.name} gives cross account read-only access." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_role_cross_service_confused_deputy_prevention/iam_role_cross_service_confused_deputy_prevention.py b/prowler/providers/aws/services/iam/iam_role_cross_service_confused_deputy_prevention/iam_role_cross_service_confused_deputy_prevention.py index 3fd7739e25..9717101927 100644 --- a/prowler/providers/aws/services/iam/iam_role_cross_service_confused_deputy_prevention/iam_role_cross_service_confused_deputy_prevention.py +++ b/prowler/providers/aws/services/iam/iam_role_cross_service_confused_deputy_prevention/iam_role_cross_service_confused_deputy_prevention.py @@ -8,36 +8,37 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_role_cross_service_confused_deputy_prevention(Check): def execute(self) -> Check_Report_AWS: findings = [] - for role in iam_client.roles: - # This check should only be performed against service roles (avoid Service Linked Roles since the trust relationship cannot be changed) - if role.is_service_role and "aws-service-role" not in role.arn: - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_arn = role.arn - report.resource_id = role.name - report.resource_tags = role.tags - report.status = "FAIL" - report.status_extended = f"IAM Service Role {role.name} does not prevent against a cross-service confused deputy attack." - for statement in role.assume_role_policy["Statement"]: - if ( - statement["Effect"] == "Allow" - and ( - "sts:AssumeRole" in statement["Action"] - or "sts:*" in statement["Action"] - or "*" in statement["Action"] - ) - # Need to make sure we are checking the part of the assume role policy document that provides a service access - and "Service" in statement["Principal"] - # Check to see if the appropriate condition statements have been implemented - and "Condition" in statement - and is_condition_block_restrictive( - statement["Condition"], iam_client.audited_account - ) - ): - report.status = "PASS" - report.status_extended = f"IAM Service Role {role.name} prevents against a cross-service confused deputy attack." - break + if iam_client.roles: + for role in iam_client.roles: + # This check should only be performed against service roles (avoid Service Linked Roles since the trust relationship cannot be changed) + if role.is_service_role and "aws-service-role" not in role.arn: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_arn = role.arn + report.resource_id = role.name + report.resource_tags = role.tags + report.status = "FAIL" + report.status_extended = f"IAM Service Role {role.name} does not prevent against a cross-service confused deputy attack." + for statement in role.assume_role_policy["Statement"]: + if ( + statement["Effect"] == "Allow" + and ( + "sts:AssumeRole" in statement["Action"] + or "sts:*" in statement["Action"] + or "*" in statement["Action"] + ) + # Need to make sure we are checking the part of the assume role policy document that provides a service access + and "Service" in statement["Principal"] + # Check to see if the appropriate condition statements have been implemented + and "Condition" in statement + and is_condition_block_restrictive( + statement["Condition"], iam_client.audited_account + ) + ): + report.status = "PASS" + report.status_extended = f"IAM Service Role {role.name} prevents against a cross-service confused deputy attack." + break - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_securityaudit_role_created/iam_securityaudit_role_created.py b/prowler/providers/aws/services/iam/iam_securityaudit_role_created/iam_securityaudit_role_created.py index 16394a30c8..8b6a2d55ed 100644 --- a/prowler/providers/aws/services/iam/iam_securityaudit_role_created/iam_securityaudit_role_created.py +++ b/prowler/providers/aws/services/iam/iam_securityaudit_role_created/iam_securityaudit_role_created.py @@ -5,15 +5,18 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_securityaudit_role_created(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_id = "SecurityAudit" - report.resource_arn = "arn:aws:iam::aws:policy/SecurityAudit" - if iam_client.entities_role_attached_to_securityaudit_policy: - report.status = "PASS" - report.status_extended = f"SecurityAudit policy attached to role {iam_client.entities_role_attached_to_securityaudit_policy[0]['RoleName']}." - else: - report.status = "FAIL" - report.status_extended = "SecurityAudit policy is not attached to any role." - findings.append(report) + if iam_client.entities_role_attached_to_securityaudit_policy is not None: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_id = "SecurityAudit" + report.resource_arn = "arn:aws:iam::aws:policy/SecurityAudit" + if iam_client.entities_role_attached_to_securityaudit_policy: + report.status = "PASS" + report.status_extended = f"SecurityAudit policy attached to role {iam_client.entities_role_attached_to_securityaudit_policy[0]['RoleName']}." + else: + report.status = "FAIL" + report.status_extended = ( + "SecurityAudit policy is not attached to any role." + ) + 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 159a3e3194..b0cb5f112d 100644 --- a/prowler/providers/aws/services/iam/iam_service.py +++ b/prowler/providers/aws/services/iam/iam_service.py @@ -117,6 +117,16 @@ class IAM(AWSService): is_service_role=is_service_role(role), ) ) + except ClientError as error: + if error.response["Error"]["Code"] == "AccessDenied": + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + roles = None + else: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -219,11 +229,28 @@ class IAM(AWSService): except ClientError as error: if error.response["Error"]["Code"] == "NoSuchEntity": - # Password policy does not exist - stored_password_policy = None + # Password policy is the IAM default + stored_password_policy = PasswordPolicy( + length=8, + symbols=False, + numbers=False, + uppercase=False, + lowercase=False, + allow_change=True, + expiration=False, + max_age=None, + reuse_prevention=None, + hard_expiry=None, + ) logger.warning( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) + elif error.response["Error"]["Code"] == "AccessDenied": + # User does not have permission to get password policy + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + stored_password_policy = None else: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -395,34 +422,35 @@ class IAM(AWSService): def __list_attached_role_policies__(self): logger.info("IAM - List Attached User Policies...") try: - for role in self.roles: - try: - attached_role_policies = [] - list_attached_role_policies_paginator = self.client.get_paginator( - "list_attached_role_policies" - ) - for page in list_attached_role_policies_paginator.paginate( - RoleName=role.name - ): - for policy in page["AttachedPolicies"]: - attached_role_policies.append(policy) - - role.attached_policies = attached_role_policies - except ClientError as error: - if error.response["Error"]["Code"] == "NoSuchEntity": - logger.warning( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + if self.roles: + for role in self.roles: + try: + attached_role_policies = [] + list_attached_role_policies_paginator = ( + self.client.get_paginator("list_attached_role_policies") ) - else: + for page in list_attached_role_policies_paginator.paginate( + RoleName=role.name + ): + for policy in page["AttachedPolicies"]: + attached_role_policies.append(policy) + + role.attached_policies = attached_role_policies + except ClientError as error: + if error.response["Error"]["Code"] == "NoSuchEntity": + logger.warning( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + else: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -548,66 +576,67 @@ class IAM(AWSService): def __list_inline_role_policies__(self): logger.info("IAM - List Inline Role Policies...") - for role in self.roles: - try: - inline_role_policies = [] - get_role_inline_policies_paginator = self.client.get_paginator( - "list_role_policies" - ) - for page in get_role_inline_policies_paginator.paginate( - RoleName=role.name - ): - for policy in page["PolicyNames"]: - try: - inline_role_policies.append(policy) - # Get inline policies & their policy documents here: - inline_policy = self.client.get_role_policy( - RoleName=role.name, PolicyName=policy - ) - inline_role_policy_doc = inline_policy["PolicyDocument"] - self.policies.append( - Policy( - name=policy, - arn=role.arn, - entity=role.name, - type="Inline", - attached=True, - version_id="v1", - document=inline_role_policy_doc, + if self.roles: + for role in self.roles: + try: + inline_role_policies = [] + get_role_inline_policies_paginator = self.client.get_paginator( + "list_role_policies" + ) + for page in get_role_inline_policies_paginator.paginate( + RoleName=role.name + ): + for policy in page["PolicyNames"]: + try: + inline_role_policies.append(policy) + # Get inline policies & their policy documents here: + inline_policy = self.client.get_role_policy( + RoleName=role.name, PolicyName=policy ) - ) - except ClientError as error: - if error.response["Error"]["Code"] == "NoSuchEntity": - logger.warning( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + inline_role_policy_doc = inline_policy["PolicyDocument"] + self.policies.append( + Policy( + name=policy, + arn=role.arn, + entity=role.name, + type="Inline", + attached=True, + version_id="v1", + document=inline_role_policy_doc, + ) ) - else: + except ClientError as error: + if error.response["Error"]["Code"] == "NoSuchEntity": + logger.warning( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + else: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) + role.inline_policies = inline_role_policies - role.inline_policies = inline_role_policies + except ClientError as error: + if error.response["Error"]["Code"] == "NoSuchEntity": + logger.warning( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + else: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) - except ClientError as error: - if error.response["Error"]["Code"] == "NoSuchEntity": - logger.warning( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - else: + except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - def __list_entities_role_for_policy__(self, policy_arn): logger.info("IAM - List Entities Role For Policy...") try: @@ -615,6 +644,17 @@ class IAM(AWSService): roles = self.client.list_entities_for_policy( PolicyArn=policy_arn, EntityFilter="Role" )["PolicyRoles"] + return roles + except ClientError as error: + if error.response["Error"]["Code"] == "AccessDenied": + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + roles = None + else: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -717,21 +757,24 @@ class IAM(AWSService): def __list_tags_for_resource__(self): logger.info("IAM - List Tags...") try: - for role in self.roles: - try: - response = self.client.list_role_tags(RoleName=role.name)["Tags"] - role.tags = response - except ClientError as error: - if error.response["Error"]["Code"] == "NoSuchEntity": - role.tags = [] - else: + if self.roles: + for role in self.roles: + try: + response = self.client.list_role_tags(RoleName=role.name)[ + "Tags" + ] + role.tags = response + except ClientError as error: + if error.response["Error"]["Code"] == "NoSuchEntity": + role.tags = [] + else: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) except Exception as error: logger.error( diff --git a/prowler/providers/aws/services/iam/iam_support_role_created/iam_support_role_created.metadata.json b/prowler/providers/aws/services/iam/iam_support_role_created/iam_support_role_created.metadata.json index e8aaf44888..61f52dedd9 100644 --- a/prowler/providers/aws/services/iam/iam_support_role_created/iam_support_role_created.metadata.json +++ b/prowler/providers/aws/services/iam/iam_support_role_created/iam_support_role_created.metadata.json @@ -13,7 +13,7 @@ "Severity": "medium", "ResourceType": "AwsIamRole", "Description": "Ensure a support role has been created to manage incidents with AWS Support", - "Risk": "AWS provides a support center that can be used for incident notification and response; as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.", + "Risk": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/iam/iam_support_role_created/iam_support_role_created.py b/prowler/providers/aws/services/iam/iam_support_role_created/iam_support_role_created.py index eba577f05b..c17bb03543 100644 --- a/prowler/providers/aws/services/iam/iam_support_role_created/iam_support_role_created.py +++ b/prowler/providers/aws/services/iam/iam_support_role_created/iam_support_role_created.py @@ -5,17 +5,18 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_support_role_created(Check): def execute(self) -> Check_Report_AWS: findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = iam_client.region - report.resource_id = "AWSSupportServiceRolePolicy" - report.resource_arn = ( - "arn:aws:iam::aws:policy/aws-service-role/AWSSupportServiceRolePolicy" - ) - if iam_client.entities_role_attached_to_support_policy: - report.status = "PASS" - report.status_extended = f"Support policy attached to role {iam_client.entities_role_attached_to_support_policy[0]['RoleName']}." - else: - report.status = "FAIL" - report.status_extended = "Support policy is not attached to any role." - findings.append(report) + if iam_client.entities_role_attached_to_support_policy is not None: + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_id = "AWSSupportServiceRolePolicy" + report.resource_arn = ( + "arn:aws:iam::aws:policy/aws-service-role/AWSSupportServiceRolePolicy" + ) + if iam_client.entities_role_attached_to_support_policy: + report.status = "PASS" + report.status_extended = f"Support policy attached to role {iam_client.entities_role_attached_to_support_policy[0]['RoleName']}." + else: + report.status = "FAIL" + report.status_extended = "Support policy is not attached to any role." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused.metadata.json b/prowler/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused.metadata.json index c5cbf8a86e..aa6e776b04 100644 --- a/prowler/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused.metadata.json +++ b/prowler/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused.metadata.json @@ -11,7 +11,7 @@ "Severity": "medium", "ResourceType": "AwsIamUser", "Description": "Ensure User Access Keys unused are disabled", - "Risk": "To increase the security of your AWS account; remove IAM user credentials (that is; passwords and access keys) that are not needed. For example; when users leave your organization or no longer need AWS access.", + "Risk": "To increase the security of your AWS account, remove IAM user credentials (that is, passwords and access keys) that are not needed. For example, when users leave your organization or no longer need AWS access.", "RelatedUrl": "", "Remediation": { "Code": { @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Find the credentials that they were using and ensure that they are no longer operational. Ideally; you delete credentials if they are no longer needed. You can always recreate them at a later date if the need arises. At the very least; you should change the password or deactivate the access keys so that the former users no longer have access.", + "Text": "Find the credentials that they were using and ensure that they are no longer operational. Ideally, you delete credentials if they are no longer needed. You can always recreate them at a later date if the need arises. At the very least, you should change the password or deactivate the access keys so that the former users no longer have access.", "Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html" } }, diff --git a/prowler/providers/aws/services/iam/iam_user_console_access_unused/iam_user_console_access_unused.metadata.json b/prowler/providers/aws/services/iam/iam_user_console_access_unused/iam_user_console_access_unused.metadata.json index aeb52eb3ba..ccee705e7a 100644 --- a/prowler/providers/aws/services/iam/iam_user_console_access_unused/iam_user_console_access_unused.metadata.json +++ b/prowler/providers/aws/services/iam/iam_user_console_access_unused/iam_user_console_access_unused.metadata.json @@ -11,7 +11,7 @@ "Severity": "medium", "ResourceType": "AwsIamUser", "Description": "Ensure unused user console access are disabled", - "Risk": "To increase the security of your AWS account; remove IAM user credentials (that is; passwords and access keys) that are not needed. For example; when users leave your organization or no longer need AWS access.", + "Risk": "To increase the security of your AWS account, remove IAM user credentials (that is, passwords and access keys) that are not needed. For example, when users leave your organization or no longer need AWS access.", "RelatedUrl": "", "Remediation": { "Code": { @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Find the credentials that they were using and ensure that they are no longer operational. Ideally; you delete credentials if they are no longer needed. You can always recreate them at a later date if the need arises. At the very least; you should change the password or deactivate the access keys so that the former users no longer have access.", + "Text": "Find the credentials that they were using and ensure that they are no longer operational. Ideally, you delete credentials if they are no longer needed. You can always recreate them at a later date if the need arises. At the very least, you should change the password or deactivate the access keys so that the former users no longer have access.", "Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html" } }, diff --git a/prowler/providers/aws/services/iam/iam_user_hardware_mfa_enabled/iam_user_hardware_mfa_enabled.metadata.json b/prowler/providers/aws/services/iam/iam_user_hardware_mfa_enabled/iam_user_hardware_mfa_enabled.metadata.json index 86db2036d1..6c5853812f 100644 --- a/prowler/providers/aws/services/iam/iam_user_hardware_mfa_enabled/iam_user_hardware_mfa_enabled.metadata.json +++ b/prowler/providers/aws/services/iam/iam_user_hardware_mfa_enabled/iam_user_hardware_mfa_enabled.metadata.json @@ -23,7 +23,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Enable hardware MFA device for an IAM user from the AWS Management Console; the command line; or the IAM API.", + "Text": "Enable hardware MFA device for an IAM user from the AWS Management Console, the command line, or the IAM API.", "Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html" } }, diff --git a/prowler/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key.metadata.json b/prowler/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key.metadata.json index cf88ce82d1..6bce20df15 100644 --- a/prowler/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key.metadata.json +++ b/prowler/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key.metadata.json @@ -13,7 +13,7 @@ "Severity": "medium", "ResourceType": "AwsIamUser", "Description": "Do not setup access keys during initial user setup for all IAM users that have a console password", - "Risk": "AWS console defaults the checkbox for creating access keys to enabled. This results in many access keys being generated unnecessarily. In addition to unnecessary credentials; it also generates unnecessary management work in auditing and rotating these keys. Requiring that additional steps be taken by the user after their profile has been created will give a stronger indication of intent that access keys are (a) necessary for their work and (b) once the access key is established on an account that the keys may be in use somewhere in the organization.", + "Risk": "AWS console defaults the checkbox for creating access keys to enabled. This results in many access keys being generated unnecessarily. In addition to unnecessary credentials, it also generates unnecessary management work in auditing and rotating these keys. Requiring that additional steps be taken by the user after their profile has been created will give a stronger indication of intent that access keys are (a) necessary for their work and (b) once the access key is established on an account that the keys may be in use somewhere in the organization.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled.metadata.json b/prowler/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled.metadata.json index 2a9d5d4563..16517826e4 100644 --- a/prowler/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled.metadata.json +++ b/prowler/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws kms enable-key-rotation --key-id ", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-kms-have-rotation-policy#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-kms-have-rotation-policy#terraform" }, "Recommendation": { "Text": "For every KMS Customer Master Keys (CMKs), ensure that Rotate this key every year is enabled.", diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_audit_logging_enabled/opensearch_service_domains_audit_logging_enabled.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_audit_logging_enabled/opensearch_service_domains_audit_logging_enabled.metadata.json index 9b92bbb968..ed067062ee 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_audit_logging_enabled/opensearch_service_domains_audit_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_audit_logging_enabled/opensearch_service_domains_audit_logging_enabled.metadata.json @@ -12,7 +12,7 @@ "Severity": "low", "ResourceType": "AwsOpenSearchDomain", "Description": "Check if Amazon Elasticsearch/Opensearch Service domains have audit logging enabled", - "Risk": "If logs are not enabled; monitoring of service use and threat analysis is not possible.", + "Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_cloudwatch_logging_enabled/opensearch_service_domains_cloudwatch_logging_enabled.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_cloudwatch_logging_enabled/opensearch_service_domains_cloudwatch_logging_enabled.metadata.json index 5ed8a418b8..0a127e6bb5 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_cloudwatch_logging_enabled/opensearch_service_domains_cloudwatch_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_cloudwatch_logging_enabled/opensearch_service_domains_cloudwatch_logging_enabled.metadata.json @@ -12,14 +12,14 @@ "Severity": "medium", "ResourceType": "AwsOpenSearchDomain", "Description": "Check if Amazon Elasticsearch/Opensearch Service domains have logging enabled", - "Risk": "Amazon ES exposes four Elasticsearch/Opensearch logs through Amazon CloudWatch Logs: error logs; search slow logs; index slow logs; and audit logs.", + "Risk": "Amazon ES exposes four Elasticsearch/Opensearch logs through Amazon CloudWatch Logs: error logs, search slow logs, index slow logs, and audit logs.", "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/elasticsearch_7#cli-command", - "NativeIaC": "https://docs.bridgecrew.io/docs/elasticsearch_7#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/elasticsearch_7#fix---runtime", - "Terraform": "https://docs.bridgecrew.io/docs/elasticsearch_7#fix---buildtime" + "CLI": "https://docs.prowler.com/checks/aws/elasticsearch-policies/elasticsearch_7#cli-command", + "NativeIaC": "https://docs.prowler.com/checks/aws/elasticsearch-policies/elasticsearch_7#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/elasticsearch-policies/elasticsearch_7#fix---runtime", + "Terraform": "https://docs.prowler.com/checks/aws/elasticsearch-policies/elasticsearch_7#fix---buildtime" }, "Recommendation": { "Text": "Enable Elasticsearch/Opensearch log. Create use cases for them. Using audit logs check for access denied events.", diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_encryption_at_rest_enabled/opensearch_service_domains_encryption_at_rest_enabled.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_encryption_at_rest_enabled/opensearch_service_domains_encryption_at_rest_enabled.metadata.json index ad705e9478..3099f98f41 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_encryption_at_rest_enabled/opensearch_service_domains_encryption_at_rest_enabled.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_encryption_at_rest_enabled/opensearch_service_domains_encryption_at_rest_enabled.metadata.json @@ -18,7 +18,7 @@ "Remediation": { "Code": { "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Elasticsearch/encryption-at-rest.html", - "NativeIaC": "https://docs.bridgecrew.io/docs/elasticsearch_3-enable-encryptionatrest#fix---builtime", + "NativeIaC": "https://docs.prowler.com/checks/aws/elasticsearch-policies/elasticsearch_3-enable-encryptionatrest#fix---builtime", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Elasticsearch/encryption-at-rest.html", "Terraform": "" }, diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_https_communications_enforced/opensearch_service_domains_https_communications_enforced.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_https_communications_enforced/opensearch_service_domains_https_communications_enforced.metadata.json index 689cad692d..c6478288bc 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_https_communications_enforced/opensearch_service_domains_https_communications_enforced.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_https_communications_enforced/opensearch_service_domains_https_communications_enforced.metadata.json @@ -18,12 +18,12 @@ "Remediation": { "Code": { "CLI": "", - "NativeIaC": "https://docs.bridgecrew.io/docs/elasticsearch_6#fix---builtime", - "Other": "https://docs.bridgecrew.io/docs/elasticsearch_6#aws-console", + "NativeIaC": "https://docs.prowler.com/checks/aws/elasticsearch-policies/elasticsearch_6#fix---builtime", + "Other": "https://docs.prowler.com/checks/aws/elasticsearch-policies/elasticsearch_6#aws-console", "Terraform": "" }, "Recommendation": { - "Text": "When creating ES Domains; enable 'Require HTTPS fo all traffic to the domain'", + "Text": "When creating ES Domains, enable 'Require HTTPS fo all traffic to the domain'", "Url": "https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-createupdatedomains.html" } }, diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_internal_user_database_enabled/opensearch_service_domains_internal_user_database_enabled.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_internal_user_database_enabled/opensearch_service_domains_internal_user_database_enabled.metadata.json index e0911c0b83..a4ec40e05e 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_internal_user_database_enabled/opensearch_service_domains_internal_user_database_enabled.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_internal_user_database_enabled/opensearch_service_domains_internal_user_database_enabled.metadata.json @@ -12,7 +12,7 @@ "Severity": "medium", "ResourceType": "AwsOpenSearchDomain", "Description": "Check if Amazon Elasticsearch/Opensearch Service domains have internal user database enabled", - "Risk": "Internal User Database is convenient for demos; for production environment use Federated authentication.", + "Risk": "Internal User Database is convenient for demos, for production environment use Federated authentication.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_node_to_node_encryption_enabled/opensearch_service_domains_node_to_node_encryption_enabled.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_node_to_node_encryption_enabled/opensearch_service_domains_node_to_node_encryption_enabled.metadata.json index 5274f0c51c..8085f11d2b 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_node_to_node_encryption_enabled/opensearch_service_domains_node_to_node_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_node_to_node_encryption_enabled/opensearch_service_domains_node_to_node_encryption_enabled.metadata.json @@ -18,12 +18,12 @@ "Remediation": { "Code": { "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Elasticsearch/node-to-node-encryption.html", - "NativeIaC": "https://docs.bridgecrew.io/docs/elasticsearch_5#fix---builtime", + "NativeIaC": "https://docs.prowler.com/checks/aws/elasticsearch-policies/elasticsearch_5#fix---builtime", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Elasticsearch/node-to-node-encryption.html", "Terraform": "" }, "Recommendation": { - "Text": "Node-to-node encryption on new domains requires Elasticsearch 6.0 or later. Enabling the feature on existing domains requires Elasticsearch 6.7 or later. Choose the existing domain in the AWS console; Actions; and Modify encryption.", + "Text": "Node-to-node encryption on new domains requires Elasticsearch 6.0 or later. Enabling the feature on existing domains requires Elasticsearch 6.7 or later. Choose the existing domain in the AWS console, Actions, and Modify encryption.", "Url": "https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ntn.html" } }, diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible.metadata.json index 65cd7abbad..4d6d5263c2 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible.metadata.json @@ -18,7 +18,7 @@ "Code": { "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Elasticsearch/elasticsearch-domain-exposed.html", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/public_3#fix---runtime", + "Other": "https://docs.prowler.com/checks/aws/public-policies/public_3#fix---runtime", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_updated_to_the_latest_service_software_version/opensearch_service_domains_updated_to_the_latest_service_software_version.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_updated_to_the_latest_service_software_version/opensearch_service_domains_updated_to_the_latest_service_software_version.metadata.json index 56b7d1c5a2..6f7a1189d2 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_updated_to_the_latest_service_software_version/opensearch_service_domains_updated_to_the_latest_service_software_version.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_updated_to_the_latest_service_software_version/opensearch_service_domains_updated_to_the_latest_service_software_version.metadata.json @@ -22,7 +22,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "The Notifications panel in the console is the easiest way to see if an update is available or check the status of an update. You can also receive these notifications through Amazon EventBridge. If you take no action on required updates; Amazon ES still updates your domain service software automatically after a certain timeframe (typically two weeks). In this situation; Amazon ES sends notifications when it starts the update and when the update is complete.", + "Text": "The Notifications panel in the console is the easiest way to see if an update is available or check the status of an update. You can also receive these notifications through Amazon EventBridge. If you take no action on required updates, Amazon ES still updates your domain service software automatically after a certain timeframe (typically two weeks). In this situation, Amazon ES sends notifications when it starts the update and when the update is complete.", "Url": "https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-service-software.html" } }, diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_use_cognito_authentication_for_kibana/opensearch_service_domains_use_cognito_authentication_for_kibana.metadata.json b/prowler/providers/aws/services/opensearch/opensearch_service_domains_use_cognito_authentication_for_kibana/opensearch_service_domains_use_cognito_authentication_for_kibana.metadata.json index 6914e40868..57b47ffe24 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_use_cognito_authentication_for_kibana/opensearch_service_domains_use_cognito_authentication_for_kibana.metadata.json +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_use_cognito_authentication_for_kibana/opensearch_service_domains_use_cognito_authentication_for_kibana.metadata.json @@ -22,7 +22,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "If you do not configure Amazon Cognito or SAML authentication; you can still protect Kibana using an IP-based access policy and a proxy server; HTTP basic authentication.", + "Text": "If you do not configure Amazon Cognito or SAML authentication, you can still protect Kibana using an IP-based access policy and a proxy server or HTTP basic authentication.", "Url": "https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-ac.html" } }, diff --git a/prowler/providers/aws/services/rds/rds_instance_backup_enabled/rds_instance_backup_enabled.metadata.json b/prowler/providers/aws/services/rds/rds_instance_backup_enabled/rds_instance_backup_enabled.metadata.json index fa560d724f..0d9f2b5743 100644 --- a/prowler/providers/aws/services/rds/rds_instance_backup_enabled/rds_instance_backup_enabled.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_backup_enabled/rds_instance_backup_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "aws rds modify-db-instance --db-instance-identifier --backup-retention-period 7 --apply-immediately", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/RDS/rds-automated-backups-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-rds-instances-have-backup-policy#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-rds-instances-have-backup-policy#terraform" }, "Recommendation": { "Text": "Enable automated backup for production data. Define a retention period and periodically test backup restoration. A Disaster Recovery process should be in place to govern Data Protection approach.", diff --git a/prowler/providers/aws/services/rds/rds_instance_deletion_protection/rds_instance_deletion_protection.metadata.json b/prowler/providers/aws/services/rds/rds_instance_deletion_protection/rds_instance_deletion_protection.metadata.json index 5dd373f358..8241f4db67 100644 --- a/prowler/providers/aws/services/rds/rds_instance_deletion_protection/rds_instance_deletion_protection.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_deletion_protection/rds_instance_deletion_protection.metadata.json @@ -16,7 +16,7 @@ "CLI": "aws rds modify-db-instance --db-instance-identifier --deletion-protection --apply-immediately", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/RDS/instance-deletion-protection.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-rds-clusters-and-instances-have-deletion-protection-enabled#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-rds-clusters-and-instances-have-deletion-protection-enabled#terraform" }, "Recommendation": { "Text": "Enable deletion protection using the AWS Management Console for production DB instances.", diff --git a/prowler/providers/aws/services/rds/rds_instance_enhanced_monitoring_enabled/rds_instance_enhanced_monitoring_enabled.metadata.json b/prowler/providers/aws/services/rds/rds_instance_enhanced_monitoring_enabled/rds_instance_enhanced_monitoring_enabled.metadata.json index 7cb7aea1b9..fee62e277a 100644 --- a/prowler/providers/aws/services/rds/rds_instance_enhanced_monitoring_enabled/rds_instance_enhanced_monitoring_enabled.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_enhanced_monitoring_enabled/rds_instance_enhanced_monitoring_enabled.metadata.json @@ -16,10 +16,10 @@ "CLI": "aws rds create-db-instance --db-instance-identifier --db-instance-class --engine --storage-encrypted true", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-enhanced-monitoring-is-enabled-for-amazon-rds-instances#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/ensure-that-enhanced-monitoring-is-enabled-for-amazon-rds-instances#terraform" }, "Recommendation": { - "Text": "To use Enhanced Monitoring, you must create an IAM role; and then enable Enhanced Monitoring.", + "Text": "To use Enhanced Monitoring, you must create an IAM role, and then enable Enhanced Monitoring.", "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.OS.html" } }, diff --git a/prowler/providers/aws/services/rds/rds_instance_integration_cloudwatch_logs/rds_instance_integration_cloudwatch_logs.metadata.json b/prowler/providers/aws/services/rds/rds_instance_integration_cloudwatch_logs/rds_instance_integration_cloudwatch_logs.metadata.json index 5cd6095445..7125e64eef 100644 --- a/prowler/providers/aws/services/rds/rds_instance_integration_cloudwatch_logs/rds_instance_integration_cloudwatch_logs.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_integration_cloudwatch_logs/rds_instance_integration_cloudwatch_logs.metadata.json @@ -16,7 +16,7 @@ "CLI": "aws rds modify-db-instance --db-instance-identifier --cloudwatch-logs-export-configuration {'EnableLogTypes':['audit',error','general','slowquery']} --apply-immediately", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/RDS/log-exports.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-respective-logs-of-amazon-relational-database-service-amazon-rds-are-enabled#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/iam-policies/ensure-that-respective-logs-of-amazon-relational-database-service-amazon-rds-are-enabled#terraform" }, "Recommendation": { "Text": "Use CloudWatch Logs to perform real-time analysis of the log data. Create alarms and view metrics.", diff --git a/prowler/providers/aws/services/rds/rds_instance_minor_version_upgrade_enabled/rds_instance_minor_version_upgrade_enabled.metadata.json b/prowler/providers/aws/services/rds/rds_instance_minor_version_upgrade_enabled/rds_instance_minor_version_upgrade_enabled.metadata.json index 7c53273e0f..abef27ec46 100644 --- a/prowler/providers/aws/services/rds/rds_instance_minor_version_upgrade_enabled/rds_instance_minor_version_upgrade_enabled.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_minor_version_upgrade_enabled/rds_instance_minor_version_upgrade_enabled.metadata.json @@ -14,9 +14,9 @@ "Remediation": { "Code": { "CLI": "aws rds modify-db-instance --db-instance-identifier --auto-minor-version-upgrade --apply-immediately", - "NativeIaC": "https://docs.bridgecrew.io/docs/ensure-aws-db-instance-gets-all-minor-upgrades-automatically#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/ensure-aws-db-instance-gets-all-minor-upgrades-automatically#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/RDS/rds-auto-minor-version-upgrade.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-aws-db-instance-gets-all-minor-upgrades-automatically#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-aws-db-instance-gets-all-minor-upgrades-automatically#terraform" }, "Recommendation": { "Text": "Enable auto minor version upgrade for all databases and environments.", diff --git a/prowler/providers/aws/services/rds/rds_instance_multi_az/rds_instance_multi_az.metadata.json b/prowler/providers/aws/services/rds/rds_instance_multi_az/rds_instance_multi_az.metadata.json index 73650e066a..5678805ea3 100644 --- a/prowler/providers/aws/services/rds/rds_instance_multi_az/rds_instance_multi_az.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_multi_az/rds_instance_multi_az.metadata.json @@ -14,9 +14,9 @@ "Remediation": { "Code": { "CLI": "aws rds create-db-instance --db-instance-identifier --multi-az true", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_73#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_73#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/RDS/rds-multi-az.html", - "Terraform": "https://docs.bridgecrew.io/docs/general_73#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_73#terraform" }, "Recommendation": { "Text": "Enable multi-AZ deployment for production databases.", diff --git a/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access.metadata.json b/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access.metadata.json index 30f9fa3d49..84680351b1 100644 --- a/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access.metadata.json @@ -14,9 +14,9 @@ "Remediation": { "Code": { "CLI": "aws rds modify-db-instance --db-instance-identifier --no-publicly-accessible --apply-immediately", - "NativeIaC": "https://docs.bridgecrew.io/docs/public_2#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/public-policies/public_2#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/RDS/rds-publicly-accessible.html", - "Terraform": "https://docs.bridgecrew.io/docs/public_2#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/public-policies/public_2#terraform" }, "Recommendation": { "Text": "Using an AWS Config rule check for RDS public instances periodically and check there is a business reason for it.", diff --git a/prowler/providers/aws/services/rds/rds_instance_storage_encrypted/rds_instance_storage_encrypted.metadata.json b/prowler/providers/aws/services/rds/rds_instance_storage_encrypted/rds_instance_storage_encrypted.metadata.json index 8f766ae62f..448a473ea1 100644 --- a/prowler/providers/aws/services/rds/rds_instance_storage_encrypted/rds_instance_storage_encrypted.metadata.json +++ b/prowler/providers/aws/services/rds/rds_instance_storage_encrypted/rds_instance_storage_encrypted.metadata.json @@ -14,9 +14,9 @@ "Remediation": { "Code": { "CLI": "aws rds create-db-instance --db-instance-identifier --db-instance-class --engine --storage-encrypted true", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_4#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_4#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/RDS/rds-encryption-enabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/general_4#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_4#terraform" }, "Recommendation": { "Text": "Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits.", diff --git a/prowler/providers/aws/services/redshift/redshift_cluster_audit_logging/redshift_cluster_audit_logging.metadata.json b/prowler/providers/aws/services/redshift/redshift_cluster_audit_logging/redshift_cluster_audit_logging.metadata.json index 99947d9dc0..b1b1934033 100644 --- a/prowler/providers/aws/services/redshift/redshift_cluster_audit_logging/redshift_cluster_audit_logging.metadata.json +++ b/prowler/providers/aws/services/redshift/redshift_cluster_audit_logging/redshift_cluster_audit_logging.metadata.json @@ -9,14 +9,14 @@ "Severity": "medium", "ResourceType": "AwsRedshiftCluster", "Description": "Check if Redshift cluster has audit logging enabled", - "Risk": "If logs are not enabled; monitoring of service use and threat analysis is not possible.", + "Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.", "RelatedUrl": "https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing.html", "Remediation": { "Code": { "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Redshift/redshift-cluster-audit-logging-enabled.html", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_logging_12#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/bc_aws_logging_12#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_logging_12#terraform" + "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_12#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_12#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_12#terraform" }, "Recommendation": { "Text": "Enable logs. Create an S3 lifecycle policy. Define use cases, metrics and automated responses where applicable.", diff --git a/prowler/providers/aws/services/redshift/redshift_cluster_automatic_upgrades/redshift_cluster_automatic_upgrades.metadata.json b/prowler/providers/aws/services/redshift/redshift_cluster_automatic_upgrades/redshift_cluster_automatic_upgrades.metadata.json index 8372ae340d..8d0f97d53c 100644 --- a/prowler/providers/aws/services/redshift/redshift_cluster_automatic_upgrades/redshift_cluster_automatic_upgrades.metadata.json +++ b/prowler/providers/aws/services/redshift/redshift_cluster_automatic_upgrades/redshift_cluster_automatic_upgrades.metadata.json @@ -9,14 +9,14 @@ "Severity": "high", "ResourceType": "AwsRedshiftCluster", "Description": "Check for Redshift Automatic Version Upgrade", - "Risk": "Without automatic version upgrade enabled; a critical Redshift Cluster version can become severly out of date", + "Risk": "Without automatic version upgrade enabled, a critical Redshift Cluster version can become severly out of date", "RelatedUrl": "https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-operations.html", "Remediation": { "Code": { "CLI": "aws redshift modify-cluster --cluster-identifier --allow-version-upgrade", - "NativeIaC": "https://docs.bridgecrew.io/docs/public_9#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/public-policies/public_9#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-redshift-clusters-allow-version-upgrade-by-default#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-redshift-clusters-allow-version-upgrade-by-default#terraform" }, "Recommendation": { "Text": "Enabled AutomaticVersionUpgrade on Redshift Cluster", diff --git a/prowler/providers/aws/services/redshift/redshift_cluster_public_access/redshift_cluster_public_access.metadata.json b/prowler/providers/aws/services/redshift/redshift_cluster_public_access/redshift_cluster_public_access.metadata.json index 7f6ec11ab9..b4fdd9c5ca 100644 --- a/prowler/providers/aws/services/redshift/redshift_cluster_public_access/redshift_cluster_public_access.metadata.json +++ b/prowler/providers/aws/services/redshift/redshift_cluster_public_access/redshift_cluster_public_access.metadata.json @@ -14,9 +14,9 @@ "Remediation": { "Code": { "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Redshift/redshift-cluster-publicly-accessible.html", - "NativeIaC": "https://docs.bridgecrew.io/docs/public_9#cloudformation", - "Other": "https://docs.bridgecrew.io/docs/public_9#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/public_9#terraform" + "NativeIaC": "https://docs.prowler.com/checks/aws/public-policies/public_9#cloudformation", + "Other": "https://docs.prowler.com/checks/aws/public-policies/public_9#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/public-policies/public_9#terraform" }, "Recommendation": { "Text": "List all shared Redshift clusters and make sure there is a business reason for them.", diff --git a/prowler/providers/aws/services/resourceexplorer2/resourceexplorer2_indexes_found/resourceexplorer2_indexes_found.py b/prowler/providers/aws/services/resourceexplorer2/resourceexplorer2_indexes_found/resourceexplorer2_indexes_found.py index 3e993a27f0..d0d4979282 100644 --- a/prowler/providers/aws/services/resourceexplorer2/resourceexplorer2_indexes_found/resourceexplorer2_indexes_found.py +++ b/prowler/providers/aws/services/resourceexplorer2/resourceexplorer2_indexes_found/resourceexplorer2_indexes_found.py @@ -7,18 +7,19 @@ from prowler.providers.aws.services.resourceexplorer2.resourceexplorer2_client i class resourceexplorer2_indexes_found(Check): def execute(self): findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = "No Resource Explorer Indexes found." - report.region = resource_explorer_2_client.region - report.resource_arn = "NoResourceExplorer" - report.resource_id = resource_explorer_2_client.audited_account - report.resource_arn = resource_explorer_2_client.index_arn_template - if resource_explorer_2_client.indexes: - report.region = resource_explorer_2_client.indexes[0].region - report.resource_arn = resource_explorer_2_client.indexes[0].arn - report.status = "PASS" - report.status_extended = f"Resource Explorer Indexes found: {len(resource_explorer_2_client.indexes)}." - findings.append(report) + if resource_explorer_2_client.indexes is not None: + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No Resource Explorer Indexes found." + report.region = resource_explorer_2_client.region + report.resource_arn = "NoResourceExplorer" + report.resource_id = resource_explorer_2_client.audited_account + report.resource_arn = resource_explorer_2_client.index_arn_template + if resource_explorer_2_client.indexes: + report.region = resource_explorer_2_client.indexes[0].region + report.resource_arn = resource_explorer_2_client.indexes[0].arn + report.status = "PASS" + report.status_extended = f"Resource Explorer Indexes found: {len(resource_explorer_2_client.indexes)}." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/resourceexplorer2/resourceexplorer2_service.py b/prowler/providers/aws/services/resourceexplorer2/resourceexplorer2_service.py index 24ef4848cb..1116babe0c 100644 --- a/prowler/providers/aws/services/resourceexplorer2/resourceexplorer2_service.py +++ b/prowler/providers/aws/services/resourceexplorer2/resourceexplorer2_service.py @@ -1,3 +1,4 @@ +from botocore.client import ClientError from pydantic import BaseModel from prowler.lib.logger import logger @@ -23,6 +24,8 @@ class ResourceExplorer2(AWSService): if not self.audit_resources or ( is_resource_filtered(index["Arn"], self.audit_resources) ): + if self.indexes is None: + self.indexes = [] self.indexes.append( Indexes( arn=index["Arn"], @@ -30,6 +33,17 @@ class ResourceExplorer2(AWSService): type=index["Type"], ) ) + except ClientError as error: + if error.response["Error"]["Code"] == "AccessDeniedException": + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + if not self.indexes: + self.indexes = None + else: + logger.error( + f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" diff --git a/prowler/providers/aws/services/route53/route53_domains_transferlock_enabled/route53_domains_transferlock_enabled.metadata.json b/prowler/providers/aws/services/route53/route53_domains_transferlock_enabled/route53_domains_transferlock_enabled.metadata.json index ebaa73e11d..76942fea27 100644 --- a/prowler/providers/aws/services/route53/route53_domains_transferlock_enabled/route53_domains_transferlock_enabled.metadata.json +++ b/prowler/providers/aws/services/route53/route53_domains_transferlock_enabled/route53_domains_transferlock_enabled.metadata.json @@ -9,7 +9,7 @@ "Severity": "medium", "ResourceType": "AwsRoute53Domain", "Description": "Enable Transfer Lock for a Route53 Domain.", - "Risk": "Without transfer lock enabled; a domain name could be incorrectly moved to a new registrar.", + "Risk": "Without transfer lock enabled, a domain name could be incorrectly moved to a new registrar.", "RelatedUrl": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-lock.html", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/route53/route53_public_hosted_zones_cloudwatch_logging_enabled/route53_public_hosted_zones_cloudwatch_logging_enabled.metadata.json b/prowler/providers/aws/services/route53/route53_public_hosted_zones_cloudwatch_logging_enabled/route53_public_hosted_zones_cloudwatch_logging_enabled.metadata.json index 8c78e116fb..7756afa7ad 100644 --- a/prowler/providers/aws/services/route53/route53_public_hosted_zones_cloudwatch_logging_enabled/route53_public_hosted_zones_cloudwatch_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/route53/route53_public_hosted_zones_cloudwatch_logging_enabled/route53_public_hosted_zones_cloudwatch_logging_enabled.metadata.json @@ -9,7 +9,7 @@ "Severity": "medium", "ResourceType": "AwsRoute53HostedZone", "Description": "Check if Route53 public hosted zones are logging queries to CloudWatch Logs.", - "Risk": "If logs are not enabled; monitoring of service use and threat analysis is not possible.", + "Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.", "RelatedUrl": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/monitoring-hosted-zones-with-cloudwatch.html", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.metadata.json b/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.metadata.json index 18a4562d03..4aa5332b1b 100644 --- a/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.metadata.json +++ b/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true --account-id ", - "NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_s3_21#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/s3-policies/bc_aws_s3_21#cloudformation", "Other": "https://github.com/cloudmatos/matos/tree/master/remediations/aws/s3/s3control/block-public-access", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_s3_21#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/s3-policies/bc_aws_s3_21#terraform" }, "Recommendation": { "Text": "You can enable Public Access Block at the account level to prevent the exposure of your data stored in S3.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.metadata.json index ed775ab6f7..984e6e74cb 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.metadata.json @@ -16,9 +16,9 @@ "Remediation": { "Code": { "CLI": "aws s3api put-bucket-encryption --bucket --server-side-encryption-configuration '{'Rules': [{'ApplyServerSideEncryptionByDefault': {'SSEAlgorithm': 'AES256'}}]}'", - "NativeIaC": "https://docs.bridgecrew.io/docs/s3_14-data-encrypted-at-rest#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/s3-policies/s3_14-data-encrypted-at-rest#cloudformation", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/s3_14-data-encrypted-at-rest#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/s3-policies/s3_14-data-encrypted-at-rest#terraform" }, "Recommendation": { "Text": "Ensure that S3 buckets have encryption at rest enabled.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_kms_encryption/s3_bucket_kms_encryption.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_kms_encryption/s3_bucket_kms_encryption.metadata.json index e36438930f..e1a1e0ddd9 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_kms_encryption/s3_bucket_kms_encryption.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_kms_encryption/s3_bucket_kms_encryption.metadata.json @@ -18,7 +18,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/S3/encrypted-with-kms-customer-master-keys.html", "NativeIaC": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/S3/encrypted-with-kms-customer-master-keys.html", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-s3-buckets-are-encrypted-with-kms-by-default#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-s3-buckets-are-encrypted-with-kms-by-default#terraform" }, "Recommendation": { "Text": "Ensure that S3 buckets have encryption at rest enabled using KMS.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.metadata.json index f742c35d36..1088ee48db 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws s3api put-public-access-block --region --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true --bucket ", "NativeIaC": "", "Other": "https://github.com/cloudmatos/matos/tree/master/remediations/aws/s3/s3/block-public-access", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_s3_20#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/s3-policies/bc_aws_s3_20#terraform" }, "Recommendation": { "Text": "You can enable Public Access Block at the bucket level to prevent the exposure of your data stored in S3.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.metadata.json index 4b0ce3e37f..15caa9c232 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws s3api put-bucket-versioning --profile my-root-profile --bucket my-bucket-name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa 'arn:aws:iam::00000000:mfa/root-account-mfa-device 123456'", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_s3_24#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/s3-policies/bc_aws_s3_24#terraform" }, "Recommendation": { "Text": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.metadata.json index 67b34fda75..8994c10754 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.metadata.json @@ -15,10 +15,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/ensure-that-s3-bucket-has-lock-configuration-enabled-by-default#cli-command", + "CLI": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-s3-bucket-has-lock-configuration-enabled-by-default#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/S3/object-lock.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-s3-bucket-has-lock-configuration-enabled-by-default#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-s3-bucket-has-lock-configuration-enabled-by-default#terraform" }, "Recommendation": { "Text": "Ensure that your Amazon S3 buckets have Object Lock feature enabled in order to prevent the objects they store from being deleted.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.metadata.json index 7f30ae81e7..25a971a11e 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.metadata.json @@ -17,11 +17,11 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/s3_16-enable-versioning#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/s3_16-enable-versioning#terraform" + "Other": "https://docs.prowler.com/checks/aws/s3-policies/s3_16-enable-versioning#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/s3-policies/s3_16-enable-versioning#terraform" }, "Recommendation": { - "Text": "Configure versioning using the Amazon console or API for buckets with sensitive information that is changing frequently; and backup may not be enough to capture all the changes.", + "Text": "Configure versioning using the Amazon console or API for buckets with sensitive information that is changing frequently, and backup may not be enough to capture all the changes.", "Url": "https://docs.aws.amazon.com/AmazonS3/latest/dev-retired/Versioning.html" } }, diff --git a/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.metadata.json index 9e66b46259..05d60d6cd5 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.metadata.json @@ -17,7 +17,7 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/s3_18-write-permissions-public#aws-console", + "Other": "https://docs.prowler.com/checks/aws/s3-policies/s3_18-write-permissions-public#aws-console", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.metadata.json index 009030e58f..e7e3783a1d 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.metadata.json @@ -18,10 +18,10 @@ "CLI": "aws s3api put-public-access-block --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true --bucket ", "NativeIaC": "", "Other": "https://github.com/cloudmatos/matos/tree/master/remediations/aws/s3/s3/block-public-access", - "Terraform": "https://docs.bridgecrew.io/docs/s3-bucket-should-have-public-access-blocks-defaults-to-false-if-the-public-access-block-is-not-attached#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/s3-bucket-should-have-public-access-blocks-defaults-to-false-if-the-public-access-block-is-not-attached#terraform" }, "Recommendation": { - "Text": "You can enable block public access settings only for access points, buckets and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account; the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.", + "Text": "You can enable block public access settings only for access points, buckets and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.", "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html" } }, diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.metadata.json index 68d062ecb0..11b76dbf6d 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.metadata.json @@ -21,7 +21,7 @@ "Terraform": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/S3/s3-bucket-public-read-access.html" }, "Recommendation": { - "Text": "You can enable block public access settings only for access points, buckets and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account; the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.", + "Text": "You can enable block public access settings only for access points, buckets and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.", "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html" } }, diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.metadata.json index 46feea818d..919eb10039 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.metadata.json @@ -21,7 +21,7 @@ "Terraform": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/S3/s3-bucket-public-write-access.html" }, "Recommendation": { - "Text": "You can enable block public access settings only for access points, buckets and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account; the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.", + "Text": "You can enable block public access settings only for access points, buckets and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.", "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html" } }, diff --git a/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.metadata.json index cdf3520b33..b680063a9e 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.metadata.json @@ -17,7 +17,7 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/s3_15-secure-data-transport#aws-console", + "Other": "https://docs.prowler.com/checks/aws/s3-policies/s3_15-secure-data-transport#aws-console", "Terraform": "" }, "Recommendation": { @@ -31,4 +31,4 @@ "DependsOn": [], "RelatedTo": [], "Notes": "" -} \ No newline at end of file +} diff --git a/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.metadata.json index 05657ecfcc..96f718e83a 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.metadata.json @@ -11,14 +11,14 @@ "Severity": "medium", "ResourceType": "AwsS3Bucket", "Description": "Check if S3 buckets have server access logging enabled", - "Risk": "Server access logs can assist you in security and access audits; help you learn about your customer base; and understand your Amazon S3 bill.", + "Risk": "Server access logs can assist you in security and access audits, help you learn about your customer base, and understand your Amazon S3 bill.", "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/s3_13-enable-logging#cli-command", + "CLI": "https://docs.prowler.com/checks/aws/s3-policies/s3_13-enable-logging#cli-command", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/s3_13-enable-logging#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/s3_13-enable-logging#terraform" + "Other": "https://docs.prowler.com/checks/aws/s3-policies/s3_13-enable-logging#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/s3-policies/s3_13-enable-logging#terraform" }, "Recommendation": { "Text": "Ensure that S3 buckets have Logging enabled. CloudTrail data events can be used in place of S3 bucket logging. If that is the case, this finding can be considered a false positive.", @@ -31,4 +31,4 @@ "DependsOn": [], "RelatedTo": [], "Notes": "" -} \ No newline at end of file +} diff --git a/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_encryption_enabled/sagemaker_notebook_instance_encryption_enabled.metadata.json b/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_encryption_enabled/sagemaker_notebook_instance_encryption_enabled.metadata.json index b356b2a221..465ebe2d56 100644 --- a/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_encryption_enabled/sagemaker_notebook_instance_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_encryption_enabled/sagemaker_notebook_instance_encryption_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SageMaker/notebook-data-encrypted.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SageMaker/notebook-data-encrypted.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_40#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/bc_aws_general_40#fix---buildtime" }, "Recommendation": { "Text": "Specify AWS KMS keys to use for input and output from S3 and EBS.", diff --git a/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_root_access_disabled/sagemaker_notebook_instance_root_access_disabled.metadata.json b/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_root_access_disabled/sagemaker_notebook_instance_root_access_disabled.metadata.json index 2413c324a5..298d015cae 100644 --- a/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_root_access_disabled/sagemaker_notebook_instance_root_access_disabled.metadata.json +++ b/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_root_access_disabled/sagemaker_notebook_instance_root_access_disabled.metadata.json @@ -9,7 +9,7 @@ "Severity": "medium", "ResourceType": "AwsSageMakerNotebookInstance", "Description": "Check if Amazon SageMaker Notebook instances have root access disabled", - "Risk": "Users with root access have administrator privileges; users can access and edit all files on a notebook instance with root access enabled", + "Risk": "Users with root access have administrator privileges, users can access and edit all files on a notebook instance with root access enabled", "RelatedUrl": "https://docs.aws.amazon.com/sagemaker/latest/dg/nbi-root-access.html", "Remediation": { "Code": { diff --git a/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_without_direct_internet_access_configured/sagemaker_notebook_instance_without_direct_internet_access_configured.metadata.json b/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_without_direct_internet_access_configured/sagemaker_notebook_instance_without_direct_internet_access_configured.metadata.json index 4e2e094f12..43f040addb 100644 --- a/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_without_direct_internet_access_configured/sagemaker_notebook_instance_without_direct_internet_access_configured.metadata.json +++ b/prowler/providers/aws/services/sagemaker/sagemaker_notebook_instance_without_direct_internet_access_configured/sagemaker_notebook_instance_without_direct_internet_access_configured.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SageMaker/notebook-direct-internet-access.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SageMaker/notebook-direct-internet-access.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-direct-internet-access-is-disabled-for-an-amazon-sagemaker-notebook-instance#fix---buildtime" + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/ensure-that-direct-internet-access-is-disabled-for-an-amazon-sagemaker-notebook-instance#fix---buildtime" }, "Recommendation": { "Text": "Restrict which traffic can access by launching Studio in a Virtual Private Cloud (VPC) of your choosing.", diff --git a/prowler/providers/aws/services/sns/sns_topics_kms_encryption_at_rest_enabled/sns_topics_kms_encryption_at_rest_enabled.metadata.json b/prowler/providers/aws/services/sns/sns_topics_kms_encryption_at_rest_enabled/sns_topics_kms_encryption_at_rest_enabled.metadata.json index b7ba5baf49..ad1e000a93 100644 --- a/prowler/providers/aws/services/sns/sns_topics_kms_encryption_at_rest_enabled/sns_topics_kms_encryption_at_rest_enabled.metadata.json +++ b/prowler/providers/aws/services/sns/sns_topics_kms_encryption_at_rest_enabled/sns_topics_kms_encryption_at_rest_enabled.metadata.json @@ -14,9 +14,9 @@ "Remediation": { "Code": { "CLI": "aws sns set-topic-attributes --topic-arn --attribute-name 'KmsMasterKeyId' --attribute-value ", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_15#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_15#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SNS/topic-encrypted-with-kms-customer-master-keys.html", - "Terraform": "https://docs.bridgecrew.io/docs/general_15#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_15#terraform" }, "Recommendation": { "Text": "Use Amazon SNS with AWS KMS.", diff --git a/prowler/providers/aws/services/sns/sns_topics_not_publicly_accessible/sns_topics_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/sns/sns_topics_not_publicly_accessible/sns_topics_not_publicly_accessible.metadata.json index 115bc96a95..7572ab4f4c 100644 --- a/prowler/providers/aws/services/sns/sns_topics_not_publicly_accessible/sns_topics_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/sns/sns_topics_not_publicly_accessible/sns_topics_not_publicly_accessible.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SNS/topics-everyone-publish.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SNS/topics-everyone-publish.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-sns-topic-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-sns-topic-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform" }, "Recommendation": { "Text": "Ensure there is a business requirement for service to be public.", diff --git a/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible.metadata.json index 497e3ba522..91d0b157d4 100644 --- a/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SQS/sqs-queue-exposed.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SQS/sqs-queue-exposed.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-sqs-queue-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-sqs-queue-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform" }, "Recommendation": { "Text": "Review service with overly permissive policies. Adhere to Principle of Least Privilege.", diff --git a/prowler/providers/aws/services/sqs/sqs_queues_server_side_encryption_enabled/sqs_queues_server_side_encryption_enabled.metadata.json b/prowler/providers/aws/services/sqs/sqs_queues_server_side_encryption_enabled/sqs_queues_server_side_encryption_enabled.metadata.json index ee2d0d8182..fa3931b75e 100644 --- a/prowler/providers/aws/services/sqs/sqs_queues_server_side_encryption_enabled/sqs_queues_server_side_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/sqs/sqs_queues_server_side_encryption_enabled/sqs_queues_server_side_encryption_enabled.metadata.json @@ -14,9 +14,9 @@ "Remediation": { "Code": { "CLI": "aws sqs set-queue-attributes --queue-url --attributes KmsMasterKeyId=", - "NativeIaC": "https://docs.bridgecrew.io/docs/general_16-encrypt-sqs-queue#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_16-encrypt-sqs-queue#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SQS/queue-encrypted-with-kms-customer-master-keys.html", - "Terraform": "https://docs.bridgecrew.io/docs/general_16-encrypt-sqs-queue#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_16-encrypt-sqs-queue#terraform" }, "Recommendation": { "Text": "Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits", diff --git a/prowler/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans.py b/prowler/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans.py index 912e1a31f8..2c47294647 100644 --- a/prowler/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans.py +++ b/prowler/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans.py @@ -7,22 +7,23 @@ from prowler.providers.aws.services.ssmincidents.ssmincidents_client import ( class ssmincidents_enabled_with_plans(Check): def execute(self): findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = "No SSM Incidents replication set exists." - report.resource_arn = ssmincidents_client.replication_set_arn_template - report.resource_id = ssmincidents_client.audited_account - report.region = ssmincidents_client.region - if ssmincidents_client.replication_set: - report.resource_arn = ssmincidents_client.replication_set[0].arn - report.resource_tags = [] # Not supported for replication sets - report.status_extended = f"SSM Incidents replication set {ssmincidents_client.replication_set[0].arn} exists but not ACTIVE." - if ssmincidents_client.replication_set[0].status == "ACTIVE": - report.status_extended = f"SSM Incidents replication set {ssmincidents_client.replication_set[0].arn} is ACTIVE but no response plans exist." - if ssmincidents_client.response_plans: - report.status = "PASS" - report.status_extended = f"SSM Incidents replication set {ssmincidents_client.replication_set[0].arn} is ACTIVE and has response plans." + if ssmincidents_client.replication_set is not None: + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No SSM Incidents replication set exists." + report.resource_arn = ssmincidents_client.replication_set_arn_template + report.resource_id = ssmincidents_client.audited_account + report.region = ssmincidents_client.region + if ssmincidents_client.replication_set: + report.resource_arn = ssmincidents_client.replication_set[0].arn + report.resource_tags = [] # Not supported for replication sets + report.status_extended = f"SSM Incidents replication set {ssmincidents_client.replication_set[0].arn} exists but not ACTIVE." + if ssmincidents_client.replication_set[0].status == "ACTIVE": + report.status_extended = f"SSM Incidents replication set {ssmincidents_client.replication_set[0].arn} is ACTIVE but no response plans exist." + if ssmincidents_client.response_plans: + report.status = "PASS" + report.status_extended = f"SSM Incidents replication set {ssmincidents_client.replication_set[0].arn} is ACTIVE and has response plans." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ssmincidents/ssmincidents_service.py b/prowler/providers/aws/services/ssmincidents/ssmincidents_service.py index 07052cb9b3..4b57448ac8 100644 --- a/prowler/providers/aws/services/ssmincidents/ssmincidents_service.py +++ b/prowler/providers/aws/services/ssmincidents/ssmincidents_service.py @@ -45,6 +45,17 @@ class SSMIncidents(AWSService): arn=replication_set, ) ] + except ClientError as error: + if error.response["Error"]["Code"] == "AccessDeniedException": + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + if not self.replication_set: + self.replication_set = None + else: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" diff --git a/prowler/providers/aws/services/trustedadvisor/trustedadvisor_errors_and_warnings/trustedadvisor_errors_and_warnings.py b/prowler/providers/aws/services/trustedadvisor/trustedadvisor_errors_and_warnings/trustedadvisor_errors_and_warnings.py index 31890de890..1436220304 100644 --- a/prowler/providers/aws/services/trustedadvisor/trustedadvisor_errors_and_warnings/trustedadvisor_errors_and_warnings.py +++ b/prowler/providers/aws/services/trustedadvisor/trustedadvisor_errors_and_warnings/trustedadvisor_errors_and_warnings.py @@ -7,28 +7,29 @@ from prowler.providers.aws.services.trustedadvisor.trustedadvisor_client import class trustedadvisor_errors_and_warnings(Check): def execute(self): findings = [] - if trustedadvisor_client.premium_support.enabled: - if trustedadvisor_client.checks: - for check in trustedadvisor_client.checks: - if ( - check.status != "not_available" - ): # avoid not_available checks since there are no resources that apply - report = Check_Report_AWS(self.metadata()) - report.region = check.region - report.resource_id = check.id - report.resource_arn = check.arn - report.status = "FAIL" - report.status_extended = f"Trusted Advisor check {check.name} is in state {check.status}." - if check.status == "ok": - report.status = "PASS" - findings.append(report) - else: - report = Check_Report_AWS(self.metadata()) - report.status = "INFO" - report.status_extended = "Amazon Web Services Premium Support Subscription is required to use this service." - report.resource_id = trustedadvisor_client.audited_account - report.resource_arn = trustedadvisor_client.account_arn_template - report.region = trustedadvisor_client.region - findings.append(report) + if trustedadvisor_client.premium_support: + if trustedadvisor_client.premium_support.enabled: + if trustedadvisor_client.checks: + for check in trustedadvisor_client.checks: + if ( + check.status != "not_available" + ): # avoid not_available checks since there are no resources that apply + report = Check_Report_AWS(self.metadata()) + report.region = check.region + report.resource_id = check.id + report.resource_arn = check.arn + report.status = "FAIL" + report.status_extended = f"Trusted Advisor check {check.name} is in state {check.status}." + if check.status == "ok": + report.status = "PASS" + findings.append(report) + else: + report = Check_Report_AWS(self.metadata()) + report.status = "INFO" + report.status_extended = "Amazon Web Services Premium Support Subscription is required to use this service." + report.resource_id = trustedadvisor_client.audited_account + report.resource_arn = trustedadvisor_client.account_arn_template + report.region = trustedadvisor_client.region + findings.append(report) return findings diff --git a/prowler/providers/aws/services/trustedadvisor/trustedadvisor_premium_support_plan_subscribed/trustedadvisor_premium_support_plan_subscribed.py b/prowler/providers/aws/services/trustedadvisor/trustedadvisor_premium_support_plan_subscribed/trustedadvisor_premium_support_plan_subscribed.py index 8d045cf43a..aed03a57c0 100644 --- a/prowler/providers/aws/services/trustedadvisor/trustedadvisor_premium_support_plan_subscribed/trustedadvisor_premium_support_plan_subscribed.py +++ b/prowler/providers/aws/services/trustedadvisor/trustedadvisor_premium_support_plan_subscribed/trustedadvisor_premium_support_plan_subscribed.py @@ -7,7 +7,12 @@ from prowler.providers.aws.services.trustedadvisor.trustedadvisor_client import class trustedadvisor_premium_support_plan_subscribed(Check): def execute(self): findings = [] - if trustedadvisor_client.audit_config.get("verify_premium_support_plans", True): + if ( + trustedadvisor_client.premium_support + and trustedadvisor_client.audit_config.get( + "verify_premium_support_plans", True + ) + ): report = Check_Report_AWS(self.metadata()) report.status = "FAIL" report.status_extended = ( diff --git a/prowler/providers/aws/services/trustedadvisor/trustedadvisor_service.py b/prowler/providers/aws/services/trustedadvisor/trustedadvisor_service.py index 32bdc5ab31..2f999f9153 100644 --- a/prowler/providers/aws/services/trustedadvisor/trustedadvisor_service.py +++ b/prowler/providers/aws/services/trustedadvisor/trustedadvisor_service.py @@ -108,6 +108,19 @@ class TrustedAdvisor(AWSService): f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:" f" {error}" ) + elif error.response["Error"]["Code"] == "AccessDeniedException": + logger.error( + f"{self.region} --" + f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:" + f" {error}" + ) + self.premium_support = None + else: + logger.error( + f"{self.region} --" + f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:" + f" {error}" + ) except Exception as error: logger.error( diff --git a/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.metadata.json b/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.metadata.json index 854476283f..18c8c12945 100644 --- a/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.metadata.json +++ b/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.metadata.json @@ -17,7 +17,7 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/networking_9#aws-vpc-endpoints-are-exposed", + "Other": "https://docs.prowler.com/checks/aws/networking-policies/networking_9#aws-vpc-endpoints-are-exposed", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.py b/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.py index 0884c2a513..936057e657 100644 --- a/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.py +++ b/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.py @@ -55,10 +55,14 @@ class vpc_endpoint_connections_trust_boundaries(Check): break else: - if isinstance(statement["Principal"]["AWS"], str): - principals = [statement["Principal"]["AWS"]] + if "AWS" in statement["Principal"]: + if isinstance(statement["Principal"]["AWS"], str): + principals = [statement["Principal"]["AWS"]] + else: + principals = statement["Principal"]["AWS"] else: - principals = statement["Principal"]["AWS"] + # If the principal is not an AWS principal, we don't need to check it since it could be a service or a federated principal + principals = [] for principal_arn in principals: report = Check_Report_AWS(self.metadata()) report.region = endpoint.region diff --git a/prowler/providers/aws/services/vpc/vpc_endpoint_services_allowed_principals_trust_boundaries/vpc_endpoint_services_allowed_principals_trust_boundaries.metadata.json b/prowler/providers/aws/services/vpc/vpc_endpoint_services_allowed_principals_trust_boundaries/vpc_endpoint_services_allowed_principals_trust_boundaries.metadata.json index 215aba5009..98f83f6613 100644 --- a/prowler/providers/aws/services/vpc/vpc_endpoint_services_allowed_principals_trust_boundaries/vpc_endpoint_services_allowed_principals_trust_boundaries.metadata.json +++ b/prowler/providers/aws/services/vpc/vpc_endpoint_services_allowed_principals_trust_boundaries/vpc_endpoint_services_allowed_principals_trust_boundaries.metadata.json @@ -17,7 +17,7 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/networking_9#aws-vpc-endpoints-are-exposed", + "Other": "https://docs.prowler.com/checks/aws/networking-policies/networking_9#aws-vpc-endpoints-are-exposed", "Terraform": "" }, "Recommendation": { diff --git a/prowler/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled.metadata.json b/prowler/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled.metadata.json index 1930a67647..af5a837946 100644 --- a/prowler/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled.metadata.json +++ b/prowler/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled.metadata.json @@ -17,8 +17,8 @@ "Code": { "CLI": "", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/logging_9-enable-vpc-flow-logging#aws-console", - "Terraform": "https://docs.bridgecrew.io/docs/logging_9-enable-vpc-flow-logging#terraform" + "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_9-enable-vpc-flow-logging#aws-console", + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_9-enable-vpc-flow-logging#terraform" }, "Recommendation": { "Text": "It is recommended that VPC Flow Logs be enabled for packet Rejects for VPCs.", diff --git a/prowler/providers/aws/services/vpc/vpc_peering_routing_tables_with_least_privilege/vpc_peering_routing_tables_with_least_privilege.metadata.json b/prowler/providers/aws/services/vpc/vpc_peering_routing_tables_with_least_privilege/vpc_peering_routing_tables_with_least_privilege.metadata.json index 9266dad83b..c985c2ad61 100644 --- a/prowler/providers/aws/services/vpc/vpc_peering_routing_tables_with_least_privilege/vpc_peering_routing_tables_with_least_privilege.metadata.json +++ b/prowler/providers/aws/services/vpc/vpc_peering_routing_tables_with_least_privilege/vpc_peering_routing_tables_with_least_privilege.metadata.json @@ -15,7 +15,7 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/networking_5#cli-command", + "CLI": "https://docs.prowler.com/checks/aws/networking-policies/networking_5#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/VPC/vpc-peering-access.html#", "Terraform": "" diff --git a/prowler/providers/aws/services/vpc/vpc_service.py b/prowler/providers/aws/services/vpc/vpc_service.py index aa8822b53a..ffed8551d7 100644 --- a/prowler/providers/aws/services/vpc/vpc_service.py +++ b/prowler/providers/aws/services/vpc/vpc_service.py @@ -345,7 +345,8 @@ class VPC(AWSService): if ( "GatewayId" in route and "igw" in route["GatewayId"] - and route["DestinationCidrBlock"] == "0.0.0.0/0" + and route.get("DestinationCidrBlock", "") + == "0.0.0.0/0" ): # If the route table has a default route to an internet gateway, the subnet is public public = True diff --git a/prowler/providers/aws/services/vpc/vpc_subnet_no_public_ip_by_default/vpc_subnet_no_public_ip_by_default.metadata.json b/prowler/providers/aws/services/vpc/vpc_subnet_no_public_ip_by_default/vpc_subnet_no_public_ip_by_default.metadata.json index 48f90334ab..ad24f4c30d 100644 --- a/prowler/providers/aws/services/vpc/vpc_subnet_no_public_ip_by_default/vpc_subnet_no_public_ip_by_default.metadata.json +++ b/prowler/providers/aws/services/vpc/vpc_subnet_no_public_ip_by_default/vpc_subnet_no_public_ip_by_default.metadata.json @@ -18,7 +18,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-vpc-subnets-do-not-assign-public-ip-by-default#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default#terraform" }, "Recommendation": { "Text": "VPC subnets should not allow automatic public IP assignment", diff --git a/prowler/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled.metadata.json b/prowler/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled.metadata.json index 1b5d15ccea..7486e5f5a0 100644 --- a/prowler/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled.metadata.json @@ -18,7 +18,7 @@ "CLI": "aws wafv2 update-web-acl-logging-configuration --scope REGIONAL --web-acl-arn arn:partition:wafv2:region:account-id:webacl/webacl-id --logging-configuration '{\"LogDestinationConfigs\": [\"arn:partition:logs:region:account-id:log-group:log-group-name\"]}'", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/WAF/enable-web-acls-logging.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_aws_logging_33#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/bc_aws_logging_33#terraform" }, "Recommendation": { "Text": "Enable AWS WAFv2 logging for your Web ACLs to monitor and analyze traffic patterns effectively.", diff --git a/prowler/providers/aws/services/workspaces/workspaces_volume_encryption_enabled/workspaces_volume_encryption_enabled.metadata.json b/prowler/providers/aws/services/workspaces/workspaces_volume_encryption_enabled/workspaces_volume_encryption_enabled.metadata.json index 5c669ed1df..4b152769d3 100644 --- a/prowler/providers/aws/services/workspaces/workspaces_volume_encryption_enabled/workspaces_volume_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/workspaces/workspaces_volume_encryption_enabled/workspaces_volume_encryption_enabled.metadata.json @@ -14,12 +14,12 @@ "Remediation": { "Code": { "CLI": "", - "NativeIaC": "https://docs.bridgecrew.io/docs/ensure-that-workspace-root-volumes-are-encrypted#cloudformation", + "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-workspace-root-volumes-are-encrypted#cloudformation", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/WorkSpaces/storage-encryption.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-workspace-root-volumes-are-encrypted#terraform" + "Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-that-workspace-root-volumes-are-encrypted#terraform" }, "Recommendation": { - "Text": "WorkSpaces is integrated with the AWS Key Management Service (AWS KMS). This enables you to encrypt storage volumes of WorkSpaces using AWS KMS Key. When you launch a WorkSpace you can encrypt the root volume (for Microsoft Windows - the C drive; for Linux - /) and the user volume (for Windows - the D drive; for Linux - /home). Doing so ensures that the data stored at rest - disk I/O to the volume - and snapshots created from the volumes are all encrypted", + "Text": "WorkSpaces is integrated with the AWS Key Management Service (AWS KMS). This enables you to encrypt storage volumes of WorkSpaces using AWS KMS Key. When you launch a WorkSpace you can encrypt the root volume (for Microsoft Windows - the C drive, for Linux - /) and the user volume (for Windows - the D drive, for Linux - /home). Doing so ensures that the data stored at rest - disk I/O to the volume - and snapshots created from the volumes are all encrypted", "Url": "https://docs.aws.amazon.com/workspaces/latest/adminguide/encrypt-workspaces.html" } }, diff --git a/prowler/providers/azure/services/aks/aks_cluster_rbac_enabled/aks_cluster_rbac_enabled.metadata.json b/prowler/providers/azure/services/aks/aks_cluster_rbac_enabled/aks_cluster_rbac_enabled.metadata.json index 67bdcd960a..418271152c 100644 --- a/prowler/providers/azure/services/aks/aks_cluster_rbac_enabled/aks_cluster_rbac_enabled.metadata.json +++ b/prowler/providers/azure/services/aks/aks_cluster_rbac_enabled/aks_cluster_rbac_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AKS/enable-role-based-access-control-for-kubernetes-service.html#", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_kubernetes_2#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-kubernetes-policies/bc_azr_kubernetes_2#terraform" }, "Recommendation": { "Text": "", diff --git a/prowler/providers/azure/services/aks/aks_network_policy_enabled/aks_network_policy_enabled.metadata.json b/prowler/providers/azure/services/aks/aks_network_policy_enabled/aks_network_policy_enabled.metadata.json index c87d2ccb20..8dce1cf5ee 100644 --- a/prowler/providers/azure/services/aks/aks_network_policy_enabled/aks_network_policy_enabled.metadata.json +++ b/prowler/providers/azure/services/aks/aks_network_policy_enabled/aks_network_policy_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_kubernetes_4#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-kubernetes-policies/bc_azr_kubernetes_4#terraform" }, "Recommendation": { "Text": "", diff --git a/prowler/providers/azure/services/app/app_client_certificates_on/app_client_certificates_on.metadata.json b/prowler/providers/azure/services/app/app_client_certificates_on/app_client_certificates_on.metadata.json index bb1094db21..8c0a0cff88 100644 --- a/prowler/providers/azure/services/app/app_client_certificates_on/app_client_certificates_on.metadata.json +++ b/prowler/providers/azure/services/app/app_client_certificates_on/app_client_certificates_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "az webapp update --resource-group --name --set clientCertEnabled=true", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_7#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_7#terraform" }, "Recommendation": { "Text": "1. Login to Azure Portal using https://portal.azure.com 2. Go to App Services 3. Click on each App 4. Under the Settings section, Click on Configuration, then General settings 5. Set the option Client certificate mode located under Incoming client certificates to Require", diff --git a/prowler/providers/azure/services/app/app_ensure_auth_is_set_up/app_ensure_auth_is_set_up.metadata.json b/prowler/providers/azure/services/app/app_ensure_auth_is_set_up/app_ensure_auth_is_set_up.metadata.json index 65308f2f09..b38b00f5ec 100644 --- a/prowler/providers/azure/services/app/app_ensure_auth_is_set_up/app_ensure_auth_is_set_up.metadata.json +++ b/prowler/providers/azure/services/app/app_ensure_auth_is_set_up/app_ensure_auth_is_set_up.metadata.json @@ -16,7 +16,7 @@ "CLI": "az webapp auth update --resource-group --name --enabled true", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AppService/enable-app-service-authentication.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_general_2#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/bc_azr_general_2#terraform" }, "Recommendation": { "Text": "1. Login to Azure Portal using https://portal.azure.com 2. Go to App Services 3. Click on each App 4. Under Setting section, click on Authentication 5. If no identity providers are set up, then click Add identity provider 6. Choose other parameters as per your requirements and click on Add", diff --git a/prowler/providers/azure/services/app/app_ensure_http_is_redirected_to_https/app_ensure_http_is_redirected_to_https.metadata.json b/prowler/providers/azure/services/app/app_ensure_http_is_redirected_to_https/app_ensure_http_is_redirected_to_https.metadata.json index 24250f0045..2907d7a5a3 100644 --- a/prowler/providers/azure/services/app/app_ensure_http_is_redirected_to_https/app_ensure_http_is_redirected_to_https.metadata.json +++ b/prowler/providers/azure/services/app/app_ensure_http_is_redirected_to_https/app_ensure_http_is_redirected_to_https.metadata.json @@ -16,7 +16,7 @@ "CLI": "az webapp update --resource-group --name --set httpsOnly=true", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AppService/enable-https-only-traffic.html#", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_5#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_5#terraform" }, "Recommendation": { "Text": "1. Login to Azure Portal using https://portal.azure.com 2. Go to App Services 3. Click on each App 4. Under Setting section, Click on Configuration 5. In the General Settings section, set the HTTPS Only to On 6. Click Save", diff --git a/prowler/providers/azure/services/app/app_ensure_java_version_is_latest/app_ensure_java_version_is_latest.metadata.json b/prowler/providers/azure/services/app/app_ensure_java_version_is_latest/app_ensure_java_version_is_latest.metadata.json index da0990f1c2..afe04bb6c7 100644 --- a/prowler/providers/azure/services/app/app_ensure_java_version_is_latest/app_ensure_java_version_is_latest.metadata.json +++ b/prowler/providers/azure/services/app/app_ensure_java_version_is_latest/app_ensure_java_version_is_latest.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AppService/latest-version-of-java.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-java-version-is-the-latest-if-used-to-run-the-web-app#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-java-version-is-the-latest-if-used-to-run-the-web-app#terraform" }, "Recommendation": { "Text": "1. Login to Azure Portal using https://portal.azure.com 2. Go to App Services 3. Click on each App 4. Under Settings section, click on Configuration 5. Click on the General settings pane and ensure that for a Stack of Java the Major Version and Minor Version reflect the latest stable and supported release, and that the Java web server version is set to the auto-update option. NOTE: No action is required if Java version is set to Off, as Java is not used by your web app.", diff --git a/prowler/providers/azure/services/app/app_ensure_php_version_is_latest/app_ensure_php_version_is_latest.metadata.json b/prowler/providers/azure/services/app/app_ensure_php_version_is_latest/app_ensure_php_version_is_latest.metadata.json index 5b370e506d..5c3458bce1 100644 --- a/prowler/providers/azure/services/app/app_ensure_php_version_is_latest/app_ensure_php_version_is_latest.metadata.json +++ b/prowler/providers/azure/services/app/app_ensure_php_version_is_latest/app_ensure_php_version_is_latest.metadata.json @@ -16,7 +16,7 @@ "CLI": "az webapp config set --resource-group --name [--linux-fx-version ][--php-version ]", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AppService/latest-version-of-php.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-php-version-is-the-latest-if-used-to-run-the-web-app#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-php-version-is-the-latest-if-used-to-run-the-web-app#terraform" }, "Recommendation": { "Text": "1. From Azure Home open the Portal Menu in the top left 2. Go to App Services 3. Click on each App 4. Under Settings section, click on Configuration 5. Click on the General settings pane, ensure that for a Stack of PHP the Major Version and Minor Version reflect the latest stable and supported release. NOTE: No action is required If PHP version is set to Off or is set with an empty value as PHP is not used by your web app", diff --git a/prowler/providers/azure/services/app/app_ensure_python_version_is_latest/app_ensure_python_version_is_latest.metadata.json b/prowler/providers/azure/services/app/app_ensure_python_version_is_latest/app_ensure_python_version_is_latest.metadata.json index b7a7430ceb..fcdbbac460 100644 --- a/prowler/providers/azure/services/app/app_ensure_python_version_is_latest/app_ensure_python_version_is_latest.metadata.json +++ b/prowler/providers/azure/services/app/app_ensure_python_version_is_latest/app_ensure_python_version_is_latest.metadata.json @@ -16,7 +16,7 @@ "CLI": "az webapp config set --resource-group --name [--linux-fx-version 'PYTHON|3.12']", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AppService/latest-version-of-python.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-python-version-is-the-latest-if-used-to-run-the-web-app" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-python-version-is-the-latest-if-used-to-run-the-web-app" }, "Recommendation": { "Text": "From Azure Portal 1. From Azure Home open the Portal Menu in the top left 2. Go to App Services 3. Click on each App 4. Under Settings section, click on Configuration 5. Click on the General settings pane and ensure that the Major Version and the Minor Version is set to the latest stable version available (Python 3.11, at the time of writing) NOTE: No action is required if Python version is set to Off, as Python is not used by your web app.", diff --git a/prowler/providers/azure/services/app/app_ftp_deployment_disabled/app_ftp_deployment_disabled.metadata.json b/prowler/providers/azure/services/app/app_ftp_deployment_disabled/app_ftp_deployment_disabled.metadata.json index 93c5a0c2d6..0c24ad4108 100644 --- a/prowler/providers/azure/services/app/app_ftp_deployment_disabled/app_ftp_deployment_disabled.metadata.json +++ b/prowler/providers/azure/services/app/app_ftp_deployment_disabled/app_ftp_deployment_disabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "az webapp config set --resource-group --name --ftps-state [disabled|FtpsOnly]", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AppService/ftp-access-disabled.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-ftp-deployments-are-disabled#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-ftp-deployments-are-disabled#terraform" }, "Recommendation": { "Text": "1. Go to the Azure Portal 2. Select App Services 3. Click on an app 4. Select Settings and then Configuration 5. Under General Settings, for the Platform Settings, the FTP state should be set to Disabled or FTPS Only", diff --git a/prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.metadata.json b/prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.metadata.json index 2b58f1c7de..361a3d0cf1 100644 --- a/prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.metadata.json +++ b/prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-app-service-enables-http-logging#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-logging-policies/ensure-that-app-service-enables-http-logging#terraform" }, "Recommendation": { "Text": "1. Go to App Services For each App Service: 2. Go to Diagnostic Settings 3. Click Add Diagnostic Setting 4. Check the checkbox next to 'HTTP logs' 5. Configure a destination based on your specific logging consumption capability (for example Stream to an event hub and then consuming with SIEM integration for Event Hub logging).", diff --git a/prowler/providers/azure/services/app/app_minimum_tls_version_12/app_minimum_tls_version_12.metadata.json b/prowler/providers/azure/services/app/app_minimum_tls_version_12/app_minimum_tls_version_12.metadata.json index 0e4f567905..6178bed00c 100644 --- a/prowler/providers/azure/services/app/app_minimum_tls_version_12/app_minimum_tls_version_12.metadata.json +++ b/prowler/providers/azure/services/app/app_minimum_tls_version_12/app_minimum_tls_version_12.metadata.json @@ -16,7 +16,7 @@ "CLI": "az webapp config set --resource-group --name --min-tls-version 1.2", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AppService/latest-version-of-tls-encryption-in-use.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_6#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_6#terraform" }, "Recommendation": { "Text": "1. Login to Azure Portal using https://portal.azure.com 2. Go to App Services 3. Click on each App 4. Under Setting section, Click on TLS/SSL settings 5. Under the Bindings pane, ensure that Minimum TLS Version set to 1.2 under Protocol Settings", diff --git a/prowler/providers/azure/services/app/app_register_with_identity/app_register_with_identity.metadata.json b/prowler/providers/azure/services/app/app_register_with_identity/app_register_with_identity.metadata.json index 5f36763487..ed4d5dbe41 100644 --- a/prowler/providers/azure/services/app/app_register_with_identity/app_register_with_identity.metadata.json +++ b/prowler/providers/azure/services/app/app_register_with_identity/app_register_with_identity.metadata.json @@ -16,7 +16,7 @@ "CLI": "az webapp identity assign --resource-group --name ", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AppService/enable-registration-with-microsoft-entra-id.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_iam_1#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-iam-policies/bc_azr_iam_1#terraform" }, "Recommendation": { "Text": "1. Login to Azure Portal using https://portal.azure.com 2. Go to App Services 3. Click on each App 4. Under Setting section, Click on Identity 5. Under the System assigned pane, set Status to On", diff --git a/prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.metadata.json b/prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.metadata.json index 4e018433c9..d28d75bec5 100644 --- a/prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.metadata.json +++ b/prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/security-contact-email.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-security-contact-emails-is-set#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-security-contact-emails-is-set#terraform" }, "Recommendation": { "Text": "1. From Azure Home select the Portal Menu 2. Select Microsoft Defender for Cloud 3. Click on Environment Settings 4. Click on the appropriate Management Group, Subscription, or Workspace 5. Click on Email notifications 6. Enter a valid security contact email address (or multiple addresses separated by commas) in the Additional email addresses field 7. Click Save", diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.metadata.json b/prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.metadata.json index dd3a4abaa8..698f58b8d4 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.metadata.json +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-app-service.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-app-service.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-azure-defender-is-set-to-on-for-app-service#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-defender-is-set-to-on-for-app-service#terraform" }, "Recommendation": { "Text": "By default, Microsoft Defender for Cloud is not enabled for your App Service instances. Enabling the Defender security service for App Service instances allows for advanced security defense using threat detection capabilities provided by Microsoft Security Response Center.", diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_azure_sql_databases_is_on/defender_ensure_defender_for_azure_sql_databases_is_on.metadata.json b/prowler/providers/azure/services/defender/defender_ensure_defender_for_azure_sql_databases_is_on/defender_ensure_defender_for_azure_sql_databases_is_on.metadata.json index 5f3ca59e09..100eb20d03 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_azure_sql_databases_is_on/defender_ensure_defender_for_azure_sql_databases_is_on.metadata.json +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_azure_sql_databases_is_on/defender_ensure_defender_for_azure_sql_databases_is_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-azure-sql.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-azure-sql.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-azure-defender-is-set-to-on-for-azure-sql-database-servers#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-defender-is-set-to-on-for-azure-sql-database-servers#terraform" }, "Recommendation": { "Text": "By default, Microsoft Defender for Cloud is disabled for all your SQL database servers. Defender for Cloud monitors your SQL database servers for threats such as SQL injection, brute-force attacks, and privilege abuse. The security service provides action-oriented security alerts with details of the suspicious activity and guidance on how to mitigate the security threats.", diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.metadata.json b/prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.metadata.json index 63589c577c..77142a2832 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.metadata.json +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-container.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-container.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-azure-defender-is-set-to-on-for-container-registries#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-defender-is-set-to-on-for-container-registries#terraform" }, "Recommendation": { "Text": "By default, Microsoft Defender for Cloud is not enabled for your Azure cloud containers. Enabling the Defender security service for Azure containers allows for advanced security defense against threats, using threat detection capabilities provided by the Microsoft Security Response Center (MSRC).", diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.metadata.json b/prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.metadata.json index b6eb47d090..5336d6ace9 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.metadata.json +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-key-vault.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-key-vault.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-azure-defender-is-set-to-on-for-key-vault#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-defender-is-set-to-on-for-key-vault#terraform" }, "Recommendation": { "Text": "Ensure that Microsoft Defender for Cloud is enabled for Azure key vaults. Key Vault is the Azure cloud service that safeguards encryption keys and secrets like certificates, connection-based strings, and passwords.", diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.metadata.json b/prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.metadata.json index 33f22f4220..c54325f1bb 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.metadata.json +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/microsoft-defender-vm-server.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/microsoft-defender-vm-server.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-azure-defender-is-set-to-on-for-servers#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-defender-is-set-to-on-for-servers#terraform" }, "Recommendation": { "Text": "Enabling Microsoft Defender for Cloud standard pricing tier allows for better security assessment with threat detection provided by the Microsoft Security Response Center (MSRC), advanced security policies, adaptive application control, network threat detection, and regulatory compliance management.", diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.metadata.json b/prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.metadata.json index 90600da1b9..cc9c0373cf 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.metadata.json +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-sql-server-virtual-machines.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-sql-server-virtual-machines.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-azure-defender-is-set-to-on-for-sql-servers-on-machines#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-defender-is-set-to-on-for-sql-servers-on-machines#terraform" }, "Recommendation": { "Text": "By default, Microsoft Defender for Cloud is disabled for the Microsoft SQL servers running on virtual machines. Defender for Cloud for SQL Server virtual machines continuously monitors your SQL database servers for threats such as SQL injection, brute-force attacks, and privilege abuse. The security service provides security alerts together with details of the suspicious activity and guidance on how to mitigate to the security threats.", diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.metadata.json b/prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.metadata.json index 306d1e26c8..b543b6bfa0 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.metadata.json +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-storage.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/defender-storage.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-azure-defender-is-set-to-on-for-storage#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-defender-is-set-to-on-for-storage#terraform" }, "Recommendation": { "Text": "By default, Microsoft Defender for Cloud is disabled for your storage accounts. Enabling the Defender security service for Azure storage accounts allows for advanced security defense using threat detection capabilities provided by the Microsoft Security Response Center (MSRC). MSRC investigates all reports of security vulnerabilities affecting Microsoft products and services, including Azure cloud services.", diff --git a/prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.metadata.json b/prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.metadata.json index 2a3fe08109..20fc3d837c 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.metadata.json +++ b/prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/enable-high-severity-email-notifications.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_general_4#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/bc_azr_general_4#terraform" }, "Recommendation": { "Text": "1. From Azure Home select the Portal Menu 2. Select Microsoft Defender for Cloud 3. Click on Environment Settings 4. Click on the appropriate Management Group, Subscription, or Workspace 5. Click on Email notifications 6. Enter a valid security contact email address (or multiple addresses separated by commas) in the Additional email addresses field 7. Click Save", diff --git a/prowler/providers/azure/services/entra/entra_global_admin_in_less_than_five_users/entra_global_admin_in_less_than_five_users.metadata.json b/prowler/providers/azure/services/entra/entra_global_admin_in_less_than_five_users/entra_global_admin_in_less_than_five_users.metadata.json index 4941e3121b..b41ee2f3d2 100644 --- a/prowler/providers/azure/services/entra/entra_global_admin_in_less_than_five_users/entra_global_admin_in_less_than_five_users.metadata.json +++ b/prowler/providers/azure/services/entra/entra_global_admin_in_less_than_five_users/entra_global_admin_in_less_than_five_users.metadata.json @@ -9,7 +9,7 @@ "Severity": "high", "ResourceType": "#microsoft.graph.directoryRole", "Description": "This recommendation aims to maintain a balance between security and operational efficiency by ensuring that a minimum of 2 and a maximum of 4 users are assigned the Global Administrator role in Microsoft Entra ID. Having at least two Global Administrators ensures redundancy, while limiting the number to four reduces the risk of excessive privileged access.", - "Risk": "The Global Administrator role has extensive privileges across all services in Microsoft Entra ID. The Global Administrator role should never be used in regular daily activities; administrators should have a regular user account for daily activities, and a separate account for administrative responsibilities. Limiting the number of Global Administrators helps mitigate the risk of unauthorized access, reduces the potential impact of human error, and aligns with the principle of least privilege to reduce the attack surface of an Azure tenant. Conversely, having at least two Global Administrators ensures that administrative functions can be performed without interruption in case of unavailability of a single admin.", + "Risk": "The Global Administrator role has extensive privileges across all services in Microsoft Entra ID. The Global Administrator role should never be used in regular daily activities, administrators should have a regular user account for daily activities, and a separate account for administrative responsibilities. Limiting the number of Global Administrators helps mitigate the risk of unauthorized access, reduces the potential impact of human error, and aligns with the principle of least privilege to reduce the attack surface of an Azure tenant. Conversely, having at least two Global Administrators ensures that administrative functions can be performed without interruption in case of unavailability of a single admin.", "RelatedUrl": "https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/best-practices#5-limit-the-number-of-global-administrators-to-less-than-5", "Remediation": { "Code": { diff --git a/prowler/providers/azure/services/entra/entra_privileged_user_has_mfa/entra_privileged_user_has_mfa.metadata.json b/prowler/providers/azure/services/entra/entra_privileged_user_has_mfa/entra_privileged_user_has_mfa.metadata.json index f76b6b39dc..130e412666 100644 --- a/prowler/providers/azure/services/entra/entra_privileged_user_has_mfa/entra_privileged_user_has_mfa.metadata.json +++ b/prowler/providers/azure/services/entra/entra_privileged_user_has_mfa/entra_privileged_user_has_mfa.metadata.json @@ -8,7 +8,7 @@ "ResourceIdTemplate": "", "Severity": "high", "ResourceType": "#microsoft.graph.users", - "Description": "Enable multi-factor authentication for all roles, groups, and users that have write access or permissions to Azure resources. These include custom created objects or built-in roles such as; - Service Co-Administrators - Subscription Owners - Contributors", + "Description": "Enable multi-factor authentication for all roles, groups, and users that have write access or permissions to Azure resources. These include custom created objects or built-in roles such as, - Service Co-Administrators - Subscription Owners - Contributors", "Risk": "Multi-factor authentication requires an individual to present a minimum of two separate forms of authentication before access is granted. Multi-factor authentication provides additional assurance that the individual attempting to gain access is who they claim to be. With multi-factor authentication, an attacker would need to compromise at least two different authentication mechanisms, increasing the difficulty of compromise and thus reducing the risk.", "RelatedUrl": "https://learn.microsoft.com/en-us/entra/identity/authentication/concept-mfa-howitworks", "Remediation": { diff --git a/prowler/providers/azure/services/keyvault/keyvault_key_expiration_set_in_non_rbac/keyvault_key_expiration_set_in_non_rbac.metadata.json b/prowler/providers/azure/services/keyvault/keyvault_key_expiration_set_in_non_rbac/keyvault_key_expiration_set_in_non_rbac.metadata.json index 55857ab4be..6df7b29f32 100644 --- a/prowler/providers/azure/services/keyvault/keyvault_key_expiration_set_in_non_rbac/keyvault_key_expiration_set_in_non_rbac.metadata.json +++ b/prowler/providers/azure/services/keyvault/keyvault_key_expiration_set_in_non_rbac/keyvault_key_expiration_set_in_non_rbac.metadata.json @@ -16,7 +16,7 @@ "CLI": "az keyvault key set-attributes --name --vault-name --expires Y-m-d'T'H:M:S'Z'", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/KeyVault/key-expiration-check.html#", - "Terraform": "https://docs.bridgecrew.io/docs/set-an-expiration-date-on-all-keys#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/set-an-expiration-date-on-all-keys#terraform" }, "Recommendation": { "Text": "From Azure Portal: 1. Go to Key vaults. 2. For each Key vault, click on Keys. 3. In the main pane, ensure that an appropriate Expiration date is set for any keys that are Enabled. From Azure CLI: Update the Expiration date for the key using the below command: az keyvault key set-attributes --name --vault-name -- expires Y-m-d'T'H:M:S'Z' Note: To view the expiration date on all keys in a Key Vault using Microsoft API, the 'List' Key permission is required. To update the expiration date for the keys: 1. Go to the Key vault, click on Access Control (IAM). 2. Click on Add role assignment and assign the role of Key Vault Crypto Officer to the appropriate user. From PowerShell: Set-AzKeyVaultKeyAttribute -VaultName -Name -Expires ", diff --git a/prowler/providers/azure/services/keyvault/keyvault_non_rbac_secret_expiration_set/keyvault_non_rbac_secret_expiration_set.metadata.json b/prowler/providers/azure/services/keyvault/keyvault_non_rbac_secret_expiration_set/keyvault_non_rbac_secret_expiration_set.metadata.json index 828d5fd27b..b0f2cf93ad 100644 --- a/prowler/providers/azure/services/keyvault/keyvault_non_rbac_secret_expiration_set/keyvault_non_rbac_secret_expiration_set.metadata.json +++ b/prowler/providers/azure/services/keyvault/keyvault_non_rbac_secret_expiration_set/keyvault_non_rbac_secret_expiration_set.metadata.json @@ -16,7 +16,7 @@ "CLI": "az keyvault secret set-attributes --name --vault-name --expires Y-m-d'T'H:M:S'Z'", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/set-an-expiration-date-on-all-secrets#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-secrets-policies/set-an-expiration-date-on-all-secrets#terraform" }, "Recommendation": { "Text": "From Azure Portal: 1. Go to Key vaults. 2. For each Key vault, click on Secrets. 3. In the main pane, ensure that the status of the secret is Enabled. 4. Set an appropriate Expiration date on all secrets. From Azure CLI: Update the Expiration date for the secret using the below command: az keyvault secret set-attributes --name --vault-name --expires Y-m-d'T'H:M:S'Z' Note: To view the expiration date on all secrets in a Key Vault using Microsoft API, the List Key permission is required. To update the expiration date for the secrets: 1. Go to Key vault, click on Access policies. 2. Click on Create and add an access policy with the Update permission (in the Secret Permissions - Secret Management Operations section). From PowerShell: For each Key vault with the EnableRbacAuthorization setting set to False or empty, run the following command. Set-AzKeyVaultSecret -VaultName -Name -Expires ", diff --git a/prowler/providers/azure/services/keyvault/keyvault_private_endpoints/keyvault_private_endpoints.metadata.json b/prowler/providers/azure/services/keyvault/keyvault_private_endpoints/keyvault_private_endpoints.metadata.json index aeda78de28..ae6cf6135f 100644 --- a/prowler/providers/azure/services/keyvault/keyvault_private_endpoints/keyvault_private_endpoints.metadata.json +++ b/prowler/providers/azure/services/keyvault/keyvault_private_endpoints/keyvault_private_endpoints.metadata.json @@ -19,7 +19,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Please see the additional information about the requirements needed before starting this remediation procedure. From Azure Portal 1. From Azure Home open the Portal Menu in the top left. 2. Select Key Vaults. 3. Select a Key Vault to audit. 4. Select Networking in the left column. 5. Select Private endpoint connections from the top row. 6. Select + Create. 7. Select the subscription the Key Vault is within, and other desired configuration. 8. Select Next. 9. For resource type select Microsoft.KeyVault/vaults. 10. Select the Key Vault to associate the Private Endpoint with. 11. Select Next. 12. In the Virtual Networking field, select the network to assign the Endpoint. 13. Select other configuration options as desired, including an existing or new application security group. 14. Select Next. 15. Select the private DNS the Private Endpoints will use. 16. Select Next. 17. Optionally add Tags. 18. Select Next : Review + Create. 19. Review the information and select Create. Follow the Audit Procedure to determine if it has successfully applied. 20. Repeat steps 3-19 for each Key Vault. From Azure CLI 1. To create an endpoint, run the following command: az network private-endpoint create --resource-group --subnet --name -- private-connection-resource-id '/subscriptions//resourceGroups//providers/Microsoft.KeyVault/vaults/' --group-ids vault --connection-name -- location --manual-request 2. To manually approve the endpoint request, run the following command: az keyvault private-endpoint-connection approve --resource-group --vault-name –name 4. Determine the Private Endpoint's IP address to connect the Key Vault to the Private DNS you have previously created: 5. Look for the property networkInterfaces then id; the value must be placed in the variable within step 7. az network private-endpoint show -g -n 6. Look for the property networkInterfaces then id; the value must be placed on in step 7. az network nic show --ids 7. Create a Private DNS record within the DNS Zone you created for the Private Endpoint: az network private-dns record-set a add-record -g -z 'privatelink.vaultcore.azure.net' -n -a 8. nslookup the private endpoint to determine if the DNS record is correct: nslookup .vault.azure.net nslookup .privatelink.vaultcore.azure.n", + "Text": "Please see the additional information about the requirements needed before starting this remediation procedure. From Azure Portal 1. From Azure Home open the Portal Menu in the top left. 2. Select Key Vaults. 3. Select a Key Vault to audit. 4. Select Networking in the left column. 5. Select Private endpoint connections from the top row. 6. Select + Create. 7. Select the subscription the Key Vault is within, and other desired configuration. 8. Select Next. 9. For resource type select Microsoft.KeyVault/vaults. 10. Select the Key Vault to associate the Private Endpoint with. 11. Select Next. 12. In the Virtual Networking field, select the network to assign the Endpoint. 13. Select other configuration options as desired, including an existing or new application security group. 14. Select Next. 15. Select the private DNS the Private Endpoints will use. 16. Select Next. 17. Optionally add Tags. 18. Select Next : Review + Create. 19. Review the information and select Create. Follow the Audit Procedure to determine if it has successfully applied. 20. Repeat steps 3-19 for each Key Vault. From Azure CLI 1. To create an endpoint, run the following command: az network private-endpoint create --resource-group --subnet --name -- private-connection-resource-id '/subscriptions//resourceGroups//providers/Microsoft.KeyVault/vaults/' --group-ids vault --connection-name -- location --manual-request 2. To manually approve the endpoint request, run the following command: az keyvault private-endpoint-connection approve --resource-group --vault-name –name 4. Determine the Private Endpoint's IP address to connect the Key Vault to the Private DNS you have previously created: 5. Look for the property networkInterfaces then id, the value must be placed in the variable within step 7. az network private-endpoint show -g -n 6. Look for the property networkInterfaces then id, the value must be placed on in step 7. az network nic show --ids 7. Create a Private DNS record within the DNS Zone you created for the Private Endpoint: az network private-dns record-set a add-record -g -z 'privatelink.vaultcore.azure.net' -n -a 8. nslookup the private endpoint to determine if the DNS record is correct: nslookup .vault.azure.net nslookup .privatelink.vaultcore.azure.n", "Url": "https://docs.microsoft.com/en-us/azure/storage/common/storage-private-endpoints" } }, diff --git a/prowler/providers/azure/services/keyvault/keyvault_rbac_key_expiration_set/keyvault_rbac_key_expiration_set.metadata.json b/prowler/providers/azure/services/keyvault/keyvault_rbac_key_expiration_set/keyvault_rbac_key_expiration_set.metadata.json index 25747cf091..1c9a1f445a 100644 --- a/prowler/providers/azure/services/keyvault/keyvault_rbac_key_expiration_set/keyvault_rbac_key_expiration_set.metadata.json +++ b/prowler/providers/azure/services/keyvault/keyvault_rbac_key_expiration_set/keyvault_rbac_key_expiration_set.metadata.json @@ -16,7 +16,7 @@ "CLI": "az keyvault key set-attributes --name --vault-name --expires Y-m-d'T'H:M:S'Z'", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/KeyVault/key-expiration-check.html#", - "Terraform": "https://docs.bridgecrew.io/docs/set-an-expiration-date-on-all-keys#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/set-an-expiration-date-on-all-keys#terraform" }, "Recommendation": { "Text": "From Azure Portal: 1. Go to Key vaults. 2. For each Key vault, click on Keys. 3. In the main pane, ensure that an appropriate Expiration date is set for any keys that are Enabled. From Azure CLI: Update the Expiration date for the key using the below command: az keyvault key set-attributes --name --vault-name -- expires Y-m-d'T'H:M:S'Z' Note: To view the expiration date on all keys in a Key Vault using Microsoft API, the 'List' Key permission is required. To update the expiration date for the keys: 1. Go to the Key vault, click on Access Control (IAM). 2. Click on Add role assignment and assign the role of Key Vault Crypto Officer to the appropriate user. From PowerShell: Set-AzKeyVaultKeyAttribute -VaultName -Name -Expires ", diff --git a/prowler/providers/azure/services/keyvault/keyvault_rbac_secret_expiration_set/keyvault_rbac_secret_expiration_set.metadata.json b/prowler/providers/azure/services/keyvault/keyvault_rbac_secret_expiration_set/keyvault_rbac_secret_expiration_set.metadata.json index 65dbb39632..05f2740626 100644 --- a/prowler/providers/azure/services/keyvault/keyvault_rbac_secret_expiration_set/keyvault_rbac_secret_expiration_set.metadata.json +++ b/prowler/providers/azure/services/keyvault/keyvault_rbac_secret_expiration_set/keyvault_rbac_secret_expiration_set.metadata.json @@ -16,7 +16,7 @@ "CLI": "az keyvault secret set-attributes --name --vault-name --expires Y-m-d'T'H:M:S'Z'", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/set-an-expiration-date-on-all-secrets#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-secrets-policies/set-an-expiration-date-on-all-secrets#terraform" }, "Recommendation": { "Text": "From Azure Portal: 1. Go to Key vaults. 2. For each Key vault, click on Secrets. 3. In the main pane, ensure that the status of the secret is Enabled. 4. For each enabled secret, ensure that an appropriate Expiration date is set. From Azure CLI: Update the Expiration date for the secret using the below command: az keyvault secret set-attributes --name --vault-name --expires Y-m-d'T'H:M:S'Z' Note: To view the expiration date on all secrets in a Key Vault using Microsoft API, the List Key permission is required. To update the expiration date for the secrets: 1. Go to the Key vault, click on Access Control (IAM). 2. Click on Add role assignment and assign the role of Key Vault Secrets Officer to the appropriate user. From PowerShell: Set-AzKeyVaultSecretAttribute -VaultName -Name - Expires ", diff --git a/prowler/providers/azure/services/keyvault/keyvault_recoverable/keyvault_recoverable.metadata.json b/prowler/providers/azure/services/keyvault/keyvault_recoverable/keyvault_recoverable.metadata.json index e9af6c043b..5d2e1e732b 100644 --- a/prowler/providers/azure/services/keyvault/keyvault_recoverable/keyvault_recoverable.metadata.json +++ b/prowler/providers/azure/services/keyvault/keyvault_recoverable/keyvault_recoverable.metadata.json @@ -16,7 +16,7 @@ "CLI": "az resource update --id /subscriptions/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups//providers/Microsoft.KeyVault/vaults/ --set properties.enablePurgeProtection=trueproperties.enableSoftDelete=true", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/KeyVault/enable-key-vault-recoverability.html#", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-the-key-vault-is-recoverable#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-the-key-vault-is-recoverable#terraform" }, "Recommendation": { "Text": "To enable 'Do Not Purge' and 'Soft Delete' for a Key Vault: From Azure Portal 1. Go to Key Vaults 2. For each Key Vault 3. Click Properties 4. Ensure the status of soft-delete reads Soft delete has been enabled on this key vault. 5. At the bottom of the page, click 'Enable Purge Protection' Note, once enabled you cannot disable it. From Azure CLI az resource update --id /subscriptions/xxxxxx-xxxx-xxxx-xxxx- xxxxxxxxxxxx/resourceGroups//providers/Microsoft.KeyVault /vaults/ --set properties.enablePurgeProtection=true properties.enableSoftDelete=true From PowerShell Update-AzKeyVault -VaultName --resource-group --encryption-key-source=Microsoft.Keyvault --encryption-key-vault --encryption-key-name --encryption-key-version ", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Monitor/use-cmk-for-activity-log-storage-container-encryption.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-storage-accounts-use-customer-managed-key-for-encryption#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-storage-accounts-use-customer-managed-key-for-encryption#terraform" }, "Recommendation": { "Text": "1. Go to Activity log 2. Select Export 3. Select Subscription 4. In section Storage Account, note the name of the Storage account 5. Close the Export Audit Logs blade. Close the Monitor - Activity Log blade. 6. In right column, Click service Storage Accounts to access Storage account blade 7. Click on the storage account name noted in step 4. This will open blade specific to that storage account 8. Under Security + networking, click Encryption. 9. Ensure Customer-managed keys is selected and Key URI is set.", diff --git a/prowler/providers/azure/services/monitor/monitor_storage_account_with_activity_logs_is_private/monitor_storage_account_with_activity_logs_is_private.metadata.json b/prowler/providers/azure/services/monitor/monitor_storage_account_with_activity_logs_is_private/monitor_storage_account_with_activity_logs_is_private.metadata.json index 7f80273be5..b294af7193 100644 --- a/prowler/providers/azure/services/monitor/monitor_storage_account_with_activity_logs_is_private/monitor_storage_account_with_activity_logs_is_private.metadata.json +++ b/prowler/providers/azure/services/monitor/monitor_storage_account_with_activity_logs_is_private/monitor_storage_account_with_activity_logs_is_private.metadata.json @@ -16,7 +16,7 @@ "CLI": "az storage container set-permission --name insights-activity-logs --account-name --public-access off", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Monitor/check-for-publicly-accessible-activity-log-storage-container.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-the-storage-container-storing-the-activity-logs-is-not-publicly-accessible#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-logging-policies/ensure-the-storage-container-storing-the-activity-logs-is-not-publicly-accessible#terraform" }, "Recommendation": { "Text": "1. From Azure Home select the Portal Menu 2. Search for Storage Accounts to access Storage account blade 3. Click on the storage account name 4. Click on Configuration under settings 5. Select Enabled under 'Allow Blob public access'", diff --git a/prowler/providers/azure/services/mysql/mysql_flexible_server_minimum_tls_version_12/mysql_flexible_server_minimum_tls_version_12.metadata.json b/prowler/providers/azure/services/mysql/mysql_flexible_server_minimum_tls_version_12/mysql_flexible_server_minimum_tls_version_12.metadata.json index 5ce7f839e6..ff0349be1a 100644 --- a/prowler/providers/azure/services/mysql/mysql_flexible_server_minimum_tls_version_12/mysql_flexible_server_minimum_tls_version_12.metadata.json +++ b/prowler/providers/azure/services/mysql/mysql_flexible_server_minimum_tls_version_12/mysql_flexible_server_minimum_tls_version_12.metadata.json @@ -16,7 +16,7 @@ "CLI": "az mysql flexible-server parameter set --name tls_version --resource-group --server-name --value TLSV1.2", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/MySQL/mysql-flexible-server-tls-version.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-mysql-is-using-the-latest-version-of-tls-encryption#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-mysql-is-using-the-latest-version-of-tls-encryption#terraform" }, "Recommendation": { "Text": "1. Login to Azure Portal using https://portal.azure.com 2. Go to Azure Database for MySQL flexible servers 3. For each database, click on Server parameters under Settings 4. In the search box, type in tls_version 5. Click on the VALUE dropdown, and ensure only TLSV1.2 is selected for tls_version", diff --git a/prowler/providers/azure/services/network/network_flow_log_more_than_90_days/network_flow_log_more_than_90_days.metadata.json b/prowler/providers/azure/services/network/network_flow_log_more_than_90_days/network_flow_log_more_than_90_days.metadata.json index 1e2e4fbc78..d4407f1f02 100644 --- a/prowler/providers/azure/services/network/network_flow_log_more_than_90_days/network_flow_log_more_than_90_days.metadata.json +++ b/prowler/providers/azure/services/network/network_flow_log_more_than_90_days/network_flow_log_more_than_90_days.metadata.json @@ -16,7 +16,7 @@ "CLI": "az network watcher flow-log configure --nsg --enabled true --resource-group --retention 91 -- storage-account ", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Network/sufficient-nsg-flow-log-retention-period.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_logging_1#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_1#terraform" }, "Recommendation": { "Text": "From Azure Portal 1. Go to Network Watcher 2. Select NSG flow logs blade in the Logs section 3. Select each Network Security Group from the list 4. Ensure Status is set to On 5. Ensure Retention (days) setting greater than 90 days 6. Select your storage account in the Storage account field 7. Select Save From Azure CLI Enable the NSG flow logs and set the Retention (days) to greater than or equal to 90 days. az network watcher flow-log configure --nsg --enabled true --resource-group --retention 91 --storage-account ", diff --git a/prowler/providers/azure/services/network/network_public_ip_shodan/network_public_ip_shodan.metadata.json b/prowler/providers/azure/services/network/network_public_ip_shodan/network_public_ip_shodan.metadata.json index c27bf219c8..41c56e221e 100644 --- a/prowler/providers/azure/services/network/network_public_ip_shodan/network_public_ip_shodan.metadata.json +++ b/prowler/providers/azure/services/network/network_public_ip_shodan/network_public_ip_shodan.metadata.json @@ -19,7 +19,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Check Identified IPs; Consider changing them to private ones and delete them from Shodan.", + "Text": "Check Identified IPs, Consider changing them to private ones and delete them from Shodan.", "Url": "https://www.shodan.io/" } }, diff --git a/prowler/providers/azure/services/network/network_rdp_internet_access_restricted/network_rdp_internet_access_restricted.metadata.json b/prowler/providers/azure/services/network/network_rdp_internet_access_restricted/network_rdp_internet_access_restricted.metadata.json index f8f4d954b2..46d6ca7da7 100644 --- a/prowler/providers/azure/services/network/network_rdp_internet_access_restricted/network_rdp_internet_access_restricted.metadata.json +++ b/prowler/providers/azure/services/network/network_rdp_internet_access_restricted/network_rdp_internet_access_restricted.metadata.json @@ -1,31 +1,30 @@ { - "Provider": "azure", - "CheckID": "network_rdp_internet_access_restricted", - "CheckTitle": "Ensure that RDP access from the Internet is evaluated and restricted", - "CheckType": [], - "ServiceName": "network", - "SubServiceName": "", - "ResourceIdTemplate": "", - "Severity": "high", - "ResourceType": "Network", - "Description": "Network security groups should be periodically evaluated for port misconfigurations. Where certain ports and protocols may be exposed to the Internet, they should be evaluated for necessity and restricted wherever they are not explicitly required.", - "Risk": "The potential security problem with using RDP over the Internet is that attackers can use various brute force techniques to gain access to Azure Virtual Machines. Once the attackers gain access, they can use a virtual machine as a launch point for compromising other machines on an Azure Virtual Network or even attack networked devices outside of Azure.", - "RelatedUrl": "https://docs.microsoft.com/en-us/azure/security/azure-security-network-security-best-practices#disable-rdpssh-access-to-azure-virtual-machines", - "Remediation": { - "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Network/unrestricted-rdp-access.html#", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_2#terraform" - }, - "Recommendation": { - "Text": "Where RDP is not explicitly required and narrowly configured for resources attached to the Network Security Group, Internet-level access to your Azure resources should be restricted or eliminated. For internal access to relevant resources, configure an encrypted network tunnel such as: ExpressRoute Site-to-site VPN Point-to-site VPN", - "Url": "https://docs.microsoft.com/en-us/security/benchmark/azure/security-controls-v3-network-security#ns-1-establish-network-segmentation-boundaries" - } + "Provider": "azure", + "CheckID": "network_rdp_internet_access_restricted", + "CheckTitle": "Ensure that RDP access from the Internet is evaluated and restricted", + "CheckType": [], + "ServiceName": "network", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "high", + "ResourceType": "Network", + "Description": "Network security groups should be periodically evaluated for port misconfigurations. Where certain ports and protocols may be exposed to the Internet, they should be evaluated for necessity and restricted wherever they are not explicitly required.", + "Risk": "The potential security problem with using RDP over the Internet is that attackers can use various brute force techniques to gain access to Azure Virtual Machines. Once the attackers gain access, they can use a virtual machine as a launch point for compromising other machines on an Azure Virtual Network or even attack networked devices outside of Azure.", + "RelatedUrl": "https://docs.microsoft.com/en-us/azure/security/azure-security-network-security-best-practices#disable-rdpssh-access-to-azure-virtual-machines", + "Remediation": { + "Code": { + "CLI": "", + "NativeIaC": "", + "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Network/unrestricted-rdp-access.html#", + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_2#terraform" }, - "Categories": [], - "DependsOn": [], - "RelatedTo": [], - "Notes": "" - } - \ No newline at end of file + "Recommendation": { + "Text": "Where RDP is not explicitly required and narrowly configured for resources attached to the Network Security Group, Internet-level access to your Azure resources should be restricted or eliminated. For internal access to relevant resources, configure an encrypted network tunnel such as: ExpressRoute Site-to-site VPN Point-to-site VPN", + "Url": "https://docs.microsoft.com/en-us/security/benchmark/azure/security-controls-v3-network-security#ns-1-establish-network-segmentation-boundaries" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/azure/services/network/network_ssh_internet_access_restricted/network_ssh_internet_access_restricted.metadata.json b/prowler/providers/azure/services/network/network_ssh_internet_access_restricted/network_ssh_internet_access_restricted.metadata.json index 609d63b67d..759cd35980 100644 --- a/prowler/providers/azure/services/network/network_ssh_internet_access_restricted/network_ssh_internet_access_restricted.metadata.json +++ b/prowler/providers/azure/services/network/network_ssh_internet_access_restricted/network_ssh_internet_access_restricted.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Network/unrestricted-ssh-access.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_3#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_3#terraform" }, "Recommendation": { "Text": "Where SSH is not explicitly required and narrowly configured for resources attached to the Network Security Group, Internet-level access to your Azure resources should be restricted or eliminated. For internal access to relevant resources, configure an encrypted network tunnel such as: ExpressRoute Site-to-site VPN Point-to-site VPN", diff --git a/prowler/providers/azure/services/network/network_udp_internet_access_restricted/network_udp_internet_access_restricted.metadata.json b/prowler/providers/azure/services/network/network_udp_internet_access_restricted/network_udp_internet_access_restricted.metadata.json index 95732507e3..0b37e96d4f 100644 --- a/prowler/providers/azure/services/network/network_udp_internet_access_restricted/network_udp_internet_access_restricted.metadata.json +++ b/prowler/providers/azure/services/network/network_udp_internet_access_restricted/network_udp_internet_access_restricted.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Network/unrestricted-udp-access.html#", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-udp-services-are-restricted-from-the-internet#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/ensure-that-udp-services-are-restricted-from-the-internet#terraform" }, "Recommendation": { "Text": "Where UDP is not explicitly required and narrowly configured for resources attached tothe Network Security Group, Internet-level access to your Azure resources should be restricted or eliminated. For internal access to relevant resources, configure an encrypted network tunnel such as: ExpressRouteSite-to-site VPN Point-to-site VPN", diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json index 5e0850280c..d45a08c34e 100644 --- a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "az postgres server firewall-rule delete --name AllowAllWindowsAzureIps --resource-group --server-name ", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/PostgreSQL/disable-all-services-access.html#", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-allow-access-to-azure-services-for-postgresql-database-server-is-disabled#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-allow-access-to-azure-services-for-postgresql-database-server-is-disabled#terraform" }, "Recommendation": { "Text": "From Azure Portal 1. Login to Azure Portal using https://portal.azure.com. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Connection security. 4. Under Firewall rules, set Allow access to Azure services to No. 5. Click Save. From Azure CLI Use the below command to delete the AllowAllWindowsAzureIps rule for PostgreSQL Database. az postgres server firewall-rule delete --name AllowAllWindowsAzureIps -- resource-group --server-name ", diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json index 445dbf5981..10052fb918 100644 --- a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "az postgres server configuration set --resource-group --server-name --name connection_throttling --value on", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/PostgreSQL/connection-throttling.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_13#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_13#terraform" }, "Recommendation": { "Text": "From Azure Portal 1. Login to Azure Portal using https://portal.azure.com. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Server parameters. 4. Search for connection_throttling. 5. Click ON and save. From Azure CLI Use the below command to update connection_throttling configuration. az postgres server configuration set --resource-group -- server-name --name connection_throttling --value on From PowerShell Use the below command to update connection_throttling configuration. Update-AzPostgreSqlConfiguration -ResourceGroupName - ServerName -Name connection_throttling -Value on", diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json index 14ceef526e..dcae4c1ba6 100644 --- a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json @@ -15,8 +15,8 @@ "Code": { "CLI": "az postgres server update --resource-group --name --ssl-enforcement Enabled", "NativeIaC": "", - "Other": "https://docs.bridgecrew.io/docs/bc_azr_networking_10", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_10#terraform" + "Other": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_10", + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_10#terraform" }, "Recommendation": { "Text": "From Azure Portal 1. Login to Azure Portal using https://portal.azure.com 2. Go to Azure Database for PostgreSQL server 3. For each database, click on Connection security 4. In SSL settings, click on ENABLED to enforce SSL connections 5. Click Save From Azure CLI Use the below command to enforce ssl connection for PostgreSQL Database. az postgres server update --resource-group --name --ssl-enforcement Enabled From PowerShell Update-AzPostgreSqlServer -ResourceGroupName -ServerName -SslEnforcement Enabled", diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json index e506a7f1fc..eb7ccfbd0a 100644 --- a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "az postgres server configuration set --resource-group --server-name --name log_checkpoints --value on", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/PostgreSQL/log-checkpoints.html#", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_11#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_11#terraform" }, "Recommendation": { "Text": "From Azure Portal 1. From Azure Home select the Portal Menu. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Server parameters. 4. Search for log_checkpoints. 5. Click ON and save. From Azure CLI Use the below command to update log_checkpoints configuration. az postgres server configuration set --resource-group -- server-name --name log_checkpoints --value on From PowerShell Update-AzPostgreSqlConfiguration -ResourceGroupName - ServerName -Name log_checkpoints -Value on", diff --git a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json index 1382dd28f6..97966077d5 100644 --- a/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json +++ b/prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json @@ -16,7 +16,7 @@ "CLI": "az postgres server configuration set --resource-group --server-name --name log_connections --value on", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/PostgreSQL/log-connections.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_12#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_12#terraform" }, "Recommendation": { "Text": "From Azure Portal 1. Login to Azure Portal using https://portal.azure.com. 2. Go to Azure Database for PostgreSQL servers. 3. For each database, click on Server parameters. 4. Search for log_connections. 5. Click ON and save. From Azure CLI Use the below command to update log_connections configuration. az postgres server configuration set --resource-group -- server-name --name log_connections --value on From PowerShell Use the below command to update log_connections configuration. Update-AzPostgreSqlConfiguration -ResourceGroupName - ServerName -Name log_connections -Value on", diff --git a/prowler/providers/azure/services/sqlserver/sqlserver_auditing_enabled/sqlserver_auditing_enabled.metadata.json b/prowler/providers/azure/services/sqlserver/sqlserver_auditing_enabled/sqlserver_auditing_enabled.metadata.json index 6ee8cf2572..bf324c4115 100644 --- a/prowler/providers/azure/services/sqlserver/sqlserver_auditing_enabled/sqlserver_auditing_enabled.metadata.json +++ b/prowler/providers/azure/services/sqlserver/sqlserver_auditing_enabled/sqlserver_auditing_enabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-database-auditing", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_azr_logging_2#cli-command", + "CLI": "https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_2#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/auditing.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_logging_2#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_2#terraform" }, "Recommendation": { "Text": "Create an audit policy for the SQL server", diff --git a/prowler/providers/azure/services/sqlserver/sqlserver_auditing_retention_90_days/sqlserver_auditing_retention_90_days.metadata.json b/prowler/providers/azure/services/sqlserver/sqlserver_auditing_retention_90_days/sqlserver_auditing_retention_90_days.metadata.json index 31396a0b61..3726871879 100644 --- a/prowler/providers/azure/services/sqlserver/sqlserver_auditing_retention_90_days/sqlserver_auditing_retention_90_days.metadata.json +++ b/prowler/providers/azure/services/sqlserver/sqlserver_auditing_retention_90_days/sqlserver_auditing_retention_90_days.metadata.json @@ -16,7 +16,7 @@ "CLI": "Set-AzSqlServerAudit -ResourceGroupName resource_group_name -ServerName SQL_Server_name -RetentionInDays 100 -LogAnalyticsTargetState Enabled -WorkspaceResourceId '/subscriptions/subscription_ID/resourceGroups/insights-integration/providers/Microsoft.OperationalInsights/workspaces/workspace_name'", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/auditing-retention.html#", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_logging_3" + "Terraform": "https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_3" }, "Recommendation": { "Text": "1. Go to SQL servers 2. For each server instance 3. Click on Auditing 4. If storage is selected, expand Advanced properties 5. Set the Retention (days) setting greater than 90 days or 0 for unlimited retention. 6. Select Save", diff --git a/prowler/providers/azure/services/sqlserver/sqlserver_azuread_administrator_enabled/sqlserver_azuread_administrator_enabled.metadata.json b/prowler/providers/azure/services/sqlserver/sqlserver_azuread_administrator_enabled/sqlserver_azuread_administrator_enabled.metadata.json index 1692a837cc..85cf50c57f 100644 --- a/prowler/providers/azure/services/sqlserver/sqlserver_azuread_administrator_enabled/sqlserver_azuread_administrator_enabled.metadata.json +++ b/prowler/providers/azure/services/sqlserver/sqlserver_azuread_administrator_enabled/sqlserver_azuread_administrator_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "az sql server ad-admin create --resource-group resource_group_name --server server_name --display-name display_name --object-id user_object_id", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/active-directory-admin.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-azure-active-directory-admin-is-configured#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-active-directory-admin-is-configured#terraform" }, "Recommendation": { "Text": "Enable an Azure Active Directory administrator", diff --git a/prowler/providers/azure/services/sqlserver/sqlserver_unrestricted_inbound_access/sqlserver_unrestricted_inbound_access.metadata.json b/prowler/providers/azure/services/sqlserver/sqlserver_unrestricted_inbound_access/sqlserver_unrestricted_inbound_access.metadata.json index 08e1008e88..be0e60758d 100644 --- a/prowler/providers/azure/services/sqlserver/sqlserver_unrestricted_inbound_access/sqlserver_unrestricted_inbound_access.metadata.json +++ b/prowler/providers/azure/services/sqlserver/sqlserver_unrestricted_inbound_access/sqlserver_unrestricted_inbound_access.metadata.json @@ -16,7 +16,7 @@ "CLI": "az sql server firewall-rule delete --resource-group resource_group_name --server sql_server_name --name rule_name", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/unrestricted-sql-database-access.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_networking_4#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_4#terraform" }, "Recommendation": { "Text": "Remove firewall rules allowing all sources and, instead, use more granular rules", diff --git a/prowler/providers/azure/services/sqlserver/sqlserver_va_emails_notifications_admins_enabled/sqlserver_va_emails_notifications_admins_enabled.metadata.json b/prowler/providers/azure/services/sqlserver/sqlserver_va_emails_notifications_admins_enabled/sqlserver_va_emails_notifications_admins_enabled.metadata.json index 23ea66bfcd..12b6a276bc 100644 --- a/prowler/providers/azure/services/sqlserver/sqlserver_va_emails_notifications_admins_enabled/sqlserver_va_emails_notifications_admins_enabled.metadata.json +++ b/prowler/providers/azure/services/sqlserver/sqlserver_va_emails_notifications_admins_enabled/sqlserver_va_emails_notifications_admins_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-va-setting-also-send-email-notifications-to-admins-and-subscription-owners-is-set-for-an-sql-server#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-also-send-email-notifications-to-admins-and-subscription-owners-is-set-for-an-sql-server#terraform" }, "Recommendation": { "Text": "1. Go to SQL servers 2. Select a server instance 3. Click on Security Center 4. Select Configure next to Enabled at subscription-level 5. In Section Vulnerability Assessment Settings, configure Storage Accounts if not already 6. Check/enable 'Also send email notifications to admins and subscription owners' 7. Click Save", diff --git a/prowler/providers/azure/services/sqlserver/sqlserver_va_periodic_recurring_scans_enabled/sqlserver_va_periodic_recurring_scans_enabled.metadata.json b/prowler/providers/azure/services/sqlserver/sqlserver_va_periodic_recurring_scans_enabled/sqlserver_va_periodic_recurring_scans_enabled.metadata.json index 3768c57540..a349528f23 100644 --- a/prowler/providers/azure/services/sqlserver/sqlserver_va_periodic_recurring_scans_enabled/sqlserver_va_periodic_recurring_scans_enabled.metadata.json +++ b/prowler/providers/azure/services/sqlserver/sqlserver_va_periodic_recurring_scans_enabled/sqlserver_va_periodic_recurring_scans_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/periodic-vulnerability-scans.html#", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-va-setting-periodic-recurring-scans-is-enabled-on-a-sql-server#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-periodic-recurring-scans-is-enabled-on-a-sql-server#terraform" }, "Recommendation": { "Text": "1. Go to SQL servers 2. For each server instance 3. Click on Security Center 4. In Section Vulnerability Assessment Settings, set Storage Account if not already 5. Toggle 'Periodic recurring scans' to ON. 6. Click Save", diff --git a/prowler/providers/azure/services/sqlserver/sqlserver_va_scan_reports_configured/sqlserver_va_scan_reports_configured.metadata.json b/prowler/providers/azure/services/sqlserver/sqlserver_va_scan_reports_configured/sqlserver_va_scan_reports_configured.metadata.json index 0b258db4eb..5f2353b819 100644 --- a/prowler/providers/azure/services/sqlserver/sqlserver_va_scan_reports_configured/sqlserver_va_scan_reports_configured.metadata.json +++ b/prowler/providers/azure/services/sqlserver/sqlserver_va_scan_reports_configured/sqlserver_va_scan_reports_configured.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-va-setting-send-scan-reports-to-is-configured-for-a-sql-server#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-send-scan-reports-to-is-configured-for-a-sql-server#terraform" }, "Recommendation": { "Text": "1. Go to SQL servers 2. Select a server instance 3. Select Microsoft Defender for Cloud 4. Select Configure next to Enablement status 5. Set Microsoft Defender for SQL to On 6. Under Vulnerability Assessment Settings, select a Storage Account 7. Set Periodic recurring scans to On 8. Under Send scan reports to, provide email addresses for data owners and stakeholders 9. Click Save", diff --git a/prowler/providers/azure/services/sqlserver/sqlserver_vulnerability_assessment_enabled/sqlserver_vulnerability_assessment_enabled.metadata.json b/prowler/providers/azure/services/sqlserver/sqlserver_vulnerability_assessment_enabled/sqlserver_vulnerability_assessment_enabled.metadata.json index 26ab2f8055..2eeeb37e01 100644 --- a/prowler/providers/azure/services/sqlserver/sqlserver_vulnerability_assessment_enabled/sqlserver_vulnerability_assessment_enabled.metadata.json +++ b/prowler/providers/azure/services/sqlserver/sqlserver_vulnerability_assessment_enabled/sqlserver_vulnerability_assessment_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "Update-AzSqlServerVulnerabilityAssessmentSetting -ResourceGroupName resource_group_name -ServerName Server_Name -StorageAccountName Storage_Name_from_same_subscription_and_same_Location -ScanResultsContainerName vulnerability-assessment -RecurringScansInterval Weekly -EmailSubscriptionAdmins $true -NotificationEmail @('mail1@mail.com' , 'mail2@mail.com')", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/vulnerability-assessment-sql-servers.html#", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-vulnerability-assessment-va-is-enabled-on-a-sql-server-by-setting-a-storage-account" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-vulnerability-assessment-va-is-enabled-on-a-sql-server-by-setting-a-storage-account" }, "Recommendation": { "Text": "1. Go to SQL servers 2. Select a server instance 3. Click on Security Center 4. Select Configure next to Enabled at subscription-level 5. In Section Vulnerability Assessment Settings, Click Select Storage account 6. Choose Storage Account (Existing or Create New). Click Ok 7. Click Save", diff --git a/prowler/providers/azure/services/storage/storage_blob_public_access_level_is_disabled/storage_blob_public_access_level_is_disabled.metadata.json b/prowler/providers/azure/services/storage/storage_blob_public_access_level_is_disabled/storage_blob_public_access_level_is_disabled.metadata.json index a43371d3c6..84b12b88c0 100644 --- a/prowler/providers/azure/services/storage/storage_blob_public_access_level_is_disabled/storage_blob_public_access_level_is_disabled.metadata.json +++ b/prowler/providers/azure/services/storage/storage_blob_public_access_level_is_disabled/storage_blob_public_access_level_is_disabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/secure-transfer-required.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/secure-transfer-required.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-storage-accounts-disallow-public-access#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/ensure-that-storage-accounts-disallow-public-access#terraform" }, "Recommendation": { "Text": "Set 'Public access level' configuration setting to 'Private (no anonymous access)'", diff --git a/prowler/providers/azure/services/storage/storage_default_network_access_rule_is_denied/storage_default_network_access_rule_is_denied.metadata.json b/prowler/providers/azure/services/storage/storage_default_network_access_rule_is_denied/storage_default_network_access_rule_is_denied.metadata.json index fda1291f1c..b17e2ebb2b 100644 --- a/prowler/providers/azure/services/storage/storage_default_network_access_rule_is_denied/storage_default_network_access_rule_is_denied.metadata.json +++ b/prowler/providers/azure/services/storage/storage_default_network_access_rule_is_denied/storage_default_network_access_rule_is_denied.metadata.json @@ -16,7 +16,7 @@ "CLI": "az storage account update --name --resource-group --default-action Deny", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/restrict-default-network-access.html", - "Terraform": "https://docs.bridgecrew.io/docs/set-default-network-access-rule-for-storage-accounts-to-deny#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/set-default-network-access-rule-for-storage-accounts-to-deny#terraform" }, "Recommendation": { "Text": "1. Go to Storage Accounts 2. For each storage account, Click on the Networking blade 3. Click the Firewalls and virtual networks heading. 4. Ensure that you have elected to allow access from Selected networks 5. Add rules to allow traffic from specific network. 6. Click Save to apply your changes.", diff --git a/prowler/providers/azure/services/storage/storage_ensure_azure_services_are_trusted_to_access_is_enabled/storage_ensure_azure_services_are_trusted_to_access_is_enabled.metadata.json b/prowler/providers/azure/services/storage/storage_ensure_azure_services_are_trusted_to_access_is_enabled/storage_ensure_azure_services_are_trusted_to_access_is_enabled.metadata.json index c88d4cfa5c..0fa4e0a1d8 100644 --- a/prowler/providers/azure/services/storage/storage_ensure_azure_services_are_trusted_to_access_is_enabled/storage_ensure_azure_services_are_trusted_to_access_is_enabled.metadata.json +++ b/prowler/providers/azure/services/storage/storage_ensure_azure_services_are_trusted_to_access_is_enabled/storage_ensure_azure_services_are_trusted_to_access_is_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "az storage account update --name --resource-group --bypass AzureServices", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/enable-trusted-microsoft-services.html", - "Terraform": "https://docs.bridgecrew.io/docs/enable-trusted-microsoft-services-for-storage-account-access#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/enable-trusted-microsoft-services-for-storage-account-access#terraform" }, "Recommendation": { "Text": "To allow these Azure services to work as intended and be able to access your storage account resources, you have to add an exception so that the trusted Microsoft Azure services can bypass your network rules", diff --git a/prowler/providers/azure/services/storage/storage_ensure_encryption_with_customer_managed_keys/storage_ensure_encryption_with_customer_managed_keys.metadata.json b/prowler/providers/azure/services/storage/storage_ensure_encryption_with_customer_managed_keys/storage_ensure_encryption_with_customer_managed_keys.metadata.json index 148ee2dbc6..c4df9ae54d 100644 --- a/prowler/providers/azure/services/storage/storage_ensure_encryption_with_customer_managed_keys/storage_ensure_encryption_with_customer_managed_keys.metadata.json +++ b/prowler/providers/azure/services/storage/storage_ensure_encryption_with_customer_managed_keys/storage_ensure_encryption_with_customer_managed_keys.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/cmk-encryption.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/cmk-encryption.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-storage-accounts-use-customer-managed-key-for-encryption#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-storage-accounts-use-customer-managed-key-for-encryption#terraform" }, "Recommendation": { "Text": "Enable sensitive data encryption at rest using Customer Managed Keys rather than Microsoft Managed keys.", diff --git a/prowler/providers/azure/services/storage/storage_ensure_minimum_tls_version_12/storage_ensure_minimum_tls_version_12.metadata.json b/prowler/providers/azure/services/storage/storage_ensure_minimum_tls_version_12/storage_ensure_minimum_tls_version_12.metadata.json index 2a3286798e..dde4338104 100644 --- a/prowler/providers/azure/services/storage/storage_ensure_minimum_tls_version_12/storage_ensure_minimum_tls_version_12.metadata.json +++ b/prowler/providers/azure/services/storage/storage_ensure_minimum_tls_version_12/storage_ensure_minimum_tls_version_12.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_azr_storage_2#cli-command", + "CLI": "https://docs.prowler.com/checks/azure/azure-storage-policies/bc_azr_storage_2#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/minimum-tls-version.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_storage_2#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-storage-policies/bc_azr_storage_2#terraform" }, "Recommendation": { "Text": "Ensure that all your Microsoft Azure Storage accounts are using the latest available version of the TLS protocol.", diff --git a/prowler/providers/azure/services/storage/storage_secure_transfer_required_is_enabled/storage_secure_transfer_required_is_enabled.metadata.json b/prowler/providers/azure/services/storage/storage_secure_transfer_required_is_enabled/storage_secure_transfer_required_is_enabled.metadata.json index 6ff461182c..f61aebc7cd 100644 --- a/prowler/providers/azure/services/storage/storage_secure_transfer_required_is_enabled/storage_secure_transfer_required_is_enabled.metadata.json +++ b/prowler/providers/azure/services/storage/storage_secure_transfer_required_is_enabled/storage_secure_transfer_required_is_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/secure-transfer-required.html", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/secure-transfer-required.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-storage-account-enables-secure-transfer" + "Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/ensure-that-storage-account-enables-secure-transfer" }, "Recommendation": { "Text": "Enable data encryption in transit.", diff --git a/prowler/providers/azure/services/vm/vm_ensure_attached_disks_encrypted_with_cmk/vm_ensure_attached_disks_encrypted_with_cmk.metadata.json b/prowler/providers/azure/services/vm/vm_ensure_attached_disks_encrypted_with_cmk/vm_ensure_attached_disks_encrypted_with_cmk.metadata.json index dc79e51548..fb664e1fc2 100644 --- a/prowler/providers/azure/services/vm/vm_ensure_attached_disks_encrypted_with_cmk/vm_ensure_attached_disks_encrypted_with_cmk.metadata.json +++ b/prowler/providers/azure/services/vm/vm_ensure_attached_disks_encrypted_with_cmk/vm_ensure_attached_disks_encrypted_with_cmk.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/sse-boot-disk-cmk.html#", - "Terraform": "https://docs.bridgecrew.io/docs/bc_azr_general_1#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/bc_azr_general_1#terraform" }, "Recommendation": { "Text": "Note: Disks must be detached from VMs to have encryption changed. 1. Go to Virtual machines 2. For each virtual machine, go to Settings 3. Click on Disks 4. Click the ellipsis (...), then click Detach to detach the disk from the VM 5. Now search for Disks and locate the unattached disk 6. Click the disk then select Encryption 7. Change your encryption type, then select your encryption set 8. Click Save 9. Go back to the VM and re-attach the disk", diff --git a/prowler/providers/azure/services/vm/vm_ensure_using_managed_disks/vm_ensure_using_managed_disks.metadata.json b/prowler/providers/azure/services/vm/vm_ensure_using_managed_disks/vm_ensure_using_managed_disks.metadata.json index 775d82610f..09b8326bae 100644 --- a/prowler/providers/azure/services/vm/vm_ensure_using_managed_disks/vm_ensure_using_managed_disks.metadata.json +++ b/prowler/providers/azure/services/vm/vm_ensure_using_managed_disks/vm_ensure_using_managed_disks.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/managed-disks-in-use.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-virtual-machines-are-utilizing-managed-disks#terraform" + "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-virtual-machines-are-utilizing-managed-disks#terraform" }, "Recommendation": { "Text": "1. Using the search feature, go to Virtual Machines 2. Select the virtual machine you would like to convert 3. Select Disks in the menu for the VM 4. At the top select Migrate to managed disks 5. You may follow the prompts to convert the disk and finish by selecting Migrate to start the process", diff --git a/prowler/providers/gcp/gcp_provider.py b/prowler/providers/gcp/gcp_provider.py index 468a0d8c98..a017d3bb2c 100644 --- a/prowler/providers/gcp/gcp_provider.py +++ b/prowler/providers/gcp/gcp_provider.py @@ -1,7 +1,6 @@ import os import sys -from colorama import Fore, Style from google import auth from googleapiclient import discovery @@ -83,10 +82,16 @@ class GCP_Provider: return project_ids except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - print( - f"\n{Fore.YELLOW}Cloud Resource Manager API {Style.RESET_ALL}has not been used before or it is disabled.\nEnable it by visiting https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/ then retry." - ) - return [] + if error.__class__.__name__ == "RefreshError": + logger.critical( + "Google Cloud SDK has not been authenticated or the credentials have expired. Authenticate by running 'gcloud auth application-default login' then retry." + ) + elif "Cloud Resource Manager API has not been used" in str(error): + logger.critical( + "Cloud Resource Manager API has not been used before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/ then retry." + ) + else: + logger.critical( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + sys.exit(1) diff --git a/prowler/providers/gcp/services/bigquery/bigquery_dataset_cmk_encryption/bigquery_dataset_cmk_encryption.metadata.json b/prowler/providers/gcp/services/bigquery/bigquery_dataset_cmk_encryption/bigquery_dataset_cmk_encryption.metadata.json index d2c838788a..75a7a7823f 100644 --- a/prowler/providers/gcp/services/bigquery/bigquery_dataset_cmk_encryption/bigquery_dataset_cmk_encryption.metadata.json +++ b/prowler/providers/gcp/services/bigquery/bigquery_dataset_cmk_encryption/bigquery_dataset_cmk_encryption.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_sql_11#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/cloud-sql-policies/bc_gcp_sql_11#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/BigQuery/enable-table-encryption-with-cmks.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-gcp-big-query-tables-are-encrypted-with-customer-supplied-encryption-keys-csek-1#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/ensure-gcp-big-query-tables-are-encrypted-with-customer-supplied-encryption-keys-csek-1#terraform" }, "Recommendation": { "Text": "Encrypting datasets with Cloud KMS Customer-Managed Keys (CMKs) will allow for a more granular control over data encryption/decryption process.", diff --git a/prowler/providers/gcp/services/bigquery/bigquery_dataset_public_access/bigquery_dataset_public_access.metadata.json b/prowler/providers/gcp/services/bigquery/bigquery_dataset_public_access/bigquery_dataset_public_access.metadata.json index 228a73ccbc..1919912650 100644 --- a/prowler/providers/gcp/services/bigquery/bigquery_dataset_public_access/bigquery_dataset_public_access.metadata.json +++ b/prowler/providers/gcp/services/bigquery/bigquery_dataset_public_access/bigquery_dataset_public_access.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/BigQuery/publicly-accessible-big-query-datasets.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_general_3#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/bc_gcp_general_3#terraform" }, "Recommendation": { "Text": "It is recommended that the IAM policy on BigQuery datasets does not allow anonymous and/or public access.", diff --git a/prowler/providers/gcp/services/bigquery/bigquery_table_cmk_encryption/bigquery_table_cmk_encryption.metadata.json b/prowler/providers/gcp/services/bigquery/bigquery_table_cmk_encryption/bigquery_table_cmk_encryption.metadata.json index e3c3d7486e..cf3c391fd5 100644 --- a/prowler/providers/gcp/services/bigquery/bigquery_table_cmk_encryption/bigquery_table_cmk_encryption.metadata.json +++ b/prowler/providers/gcp/services/bigquery/bigquery_table_cmk_encryption/bigquery_table_cmk_encryption.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/BigQuery/enable-table-encryption-with-cmks.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-gcp-big-query-tables-are-encrypted-with-customer-supplied-encryption-keys-csek#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/ensure-gcp-big-query-tables-are-encrypted-with-customer-supplied-encryption-keys-csek#terraform" }, "Recommendation": { "Text": "Encrypting tables with Cloud KMS Customer-Managed Keys (CMKs) will allow for a more granular control over data encryption/decryption process.", diff --git a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_mysql_local_infile_flag/cloudsql_instance_mysql_local_infile_flag.metadata.json b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_mysql_local_infile_flag/cloudsql_instance_mysql_local_infile_flag.metadata.json index 348ba887f6..758781c7e4 100644 --- a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_mysql_local_infile_flag/cloudsql_instance_mysql_local_infile_flag.metadata.json +++ b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_mysql_local_infile_flag/cloudsql_instance_mysql_local_infile_flag.metadata.json @@ -16,7 +16,7 @@ "CLI": "gcloud sql instances patch INSTANCE_NAME --database-flags local_infile=off", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudSQL/disable-local-infile-flag.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_sql_1#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/cloud-sql-policies/bc_gcp_sql_1#terraform" }, "Recommendation": { "Text": "It is recommended to set the local_infile database flag for a Cloud SQL MySQL instance to off.", diff --git a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_connections_flag/cloudsql_instance_postgres_log_connections_flag.metadata.json b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_connections_flag/cloudsql_instance_postgres_log_connections_flag.metadata.json index c8a9315436..f8de67808d 100644 --- a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_connections_flag/cloudsql_instance_postgres_log_connections_flag.metadata.json +++ b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_connections_flag/cloudsql_instance_postgres_log_connections_flag.metadata.json @@ -16,7 +16,7 @@ "CLI": "gcloud sql instances patch INSTANCE_NAME --database-flags log_connections=on", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudSQL/enable-log-connections-flag.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_sql_3#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/cloud-sql-policies/bc_gcp_sql_3#terraform" }, "Recommendation": { "Text": "PostgreSQL does not log attempted connections by default. Enabling the log_connections setting will create log entries for each attempted connection as well as successful completion of client authentication which can be useful in troubleshooting issues and to determine any unusual connection attempts to the server.", diff --git a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_disconnections_flag/cloudsql_instance_postgres_log_disconnections_flag.metadata.json b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_disconnections_flag/cloudsql_instance_postgres_log_disconnections_flag.metadata.json index a4fe2cd4b2..b5627e00e1 100644 --- a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_disconnections_flag/cloudsql_instance_postgres_log_disconnections_flag.metadata.json +++ b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_disconnections_flag/cloudsql_instance_postgres_log_disconnections_flag.metadata.json @@ -16,7 +16,7 @@ "CLI": "gcloud sql instances patch INSTANCE_NAME --database-flags log_disconnections=on", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudSQL/enable-log-connections-flag.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_sql_4#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/cloud-sql-policies/bc_gcp_sql_4#terraform" }, "Recommendation": { "Text": "Enabling the log_disconnections setting logs the end of each session, including the session duration.", diff --git a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_min_messages_flag/cloudsql_instance_postgres_log_min_messages_flag.metadata.json b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_min_messages_flag/cloudsql_instance_postgres_log_min_messages_flag.metadata.json index 591d234b30..8a8963aea3 100644 --- a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_min_messages_flag/cloudsql_instance_postgres_log_min_messages_flag.metadata.json +++ b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_postgres_log_min_messages_flag/cloudsql_instance_postgres_log_min_messages_flag.metadata.json @@ -16,7 +16,7 @@ "CLI": "gcloud sql instances patch INSTANCE_NAME --database-flags log_min_messages=warning", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_sql_4#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/cloud-sql-policies/bc_gcp_sql_4#terraform" }, "Recommendation": { "Text": "The log_min_messages flag defines the minimum message severity level that is considered as an error statement. Messages for error statements are logged with the SQL statement. Valid values include DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, INFO, NOTICE, WARNING, ERROR, LOG, FATAL, and PANIC. Each severity level includes the subsequent levels mentioned above. ERROR is considered the best practice setting. Changes should only be made in accordance with the organization's logging policy.", diff --git a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_public_ip/cloudsql_instance_public_ip.metadata.json b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_public_ip/cloudsql_instance_public_ip.metadata.json index 197d7082fc..a4cadadbf0 100644 --- a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_public_ip/cloudsql_instance_public_ip.metadata.json +++ b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_public_ip/cloudsql_instance_public_ip.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_sql_11#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/cloud-sql-policies/bc_gcp_sql_11#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudSQL/sql-database-instances-with-public-ips.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_sql_11#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/cloud-sql-policies/bc_gcp_sql_11#terraform" }, "Recommendation": { "Text": "To lower the organization's attack surface, Cloud SQL databases should not have public IPs. Private IPs provide improved network security and lower latency for your application.", diff --git a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_sqlserver_contained_database_authentication_flag/cloudsql_instance_sqlserver_contained_database_authentication_flag.metadata.json b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_sqlserver_contained_database_authentication_flag/cloudsql_instance_sqlserver_contained_database_authentication_flag.metadata.json index 3071cf8428..36341ef0c7 100644 --- a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_sqlserver_contained_database_authentication_flag/cloudsql_instance_sqlserver_contained_database_authentication_flag.metadata.json +++ b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_sqlserver_contained_database_authentication_flag/cloudsql_instance_sqlserver_contained_database_authentication_flag.metadata.json @@ -16,7 +16,7 @@ "CLI": "gcloud sql instances patch --database-flags contained database authentication=off", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudSQL/disable-contained-database-authentication-flag.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_sql_10#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/cloud-sql-policies/bc_gcp_sql_10#terraform" }, "Recommendation": { "Text": "It is recommended to set contained database authentication database flag for Cloud SQL on the SQL Server instance to off.", diff --git a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_sqlserver_user_options_flag/cloudsql_instance_sqlserver_user_options_flag.metadata.json b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_sqlserver_user_options_flag/cloudsql_instance_sqlserver_user_options_flag.metadata.json index 24737f7671..a3d2187903 100644 --- a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_sqlserver_user_options_flag/cloudsql_instance_sqlserver_user_options_flag.metadata.json +++ b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_sqlserver_user_options_flag/cloudsql_instance_sqlserver_user_options_flag.metadata.json @@ -9,7 +9,7 @@ "Severity": "medium", "ResourceType": "DatabaseInstance", "Description": "Ensure 'user options' database flag for Cloud SQL SQL Server instance is not configured", - "Risk": "The user options option specifies global defaults for all users. A list of default query processing options is established for the duration of a user's work session. The user options option allows you to change the default values of the SET options (if the server's default settings are not appropriate). A user can override these defaults by using the SET statement. You can configure user options dynamically for new logins. After you change the setting of user options, new login sessions use the new setting; current login sessions are not affected.", + "Risk": "The user options option specifies global defaults for all users. A list of default query processing options is established for the duration of a user's work session. The user options option allows you to change the default values of the SET options (if the server's default settings are not appropriate). A user can override these defaults by using the SET statement. You can configure user options dynamically for new logins. After you change the setting of user options, new login sessions use the new setting, current login sessions are not affected.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_ssl_connections/cloudsql_instance_ssl_connections.metadata.json b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_ssl_connections/cloudsql_instance_ssl_connections.metadata.json index c4c43724b3..a76b669601 100644 --- a/prowler/providers/gcp/services/cloudsql/cloudsql_instance_ssl_connections/cloudsql_instance_ssl_connections.metadata.json +++ b/prowler/providers/gcp/services/cloudsql/cloudsql_instance_ssl_connections/cloudsql_instance_ssl_connections.metadata.json @@ -9,7 +9,7 @@ "Severity": "medium", "ResourceType": "DatabaseInstance", "Description": "Ensure That the Cloud SQL Database Instance Requires All Incoming Connections To Use SSL", - "Risk": "SQL database connections if successfully trapped (MITM); can reveal sensitive data like credentials, database queries, query outputs etc. For security, it is recommended to always use SSL encryption when connecting to your instance. This recommendation is applicable for Postgresql, MySql generation 1, MySql generation 2 and SQL Server 2017 instances.", + "Risk": "SQL database connections if successfully trapped (MITM), can reveal sensitive data like credentials, database queries, query outputs etc. For security, it is recommended to always use SSL encryption when connecting to your instance. This recommendation is applicable for Postgresql, MySql generation 1, MySql generation 2 and SQL Server 2017 instances.", "RelatedUrl": "", "Remediation": { "Code": { diff --git a/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_log_retention_policy_lock/cloudstorage_bucket_log_retention_policy_lock.metadata.json b/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_log_retention_policy_lock/cloudstorage_bucket_log_retention_policy_lock.metadata.json index 6880e298ed..7064a79d73 100644 --- a/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_log_retention_policy_lock/cloudstorage_bucket_log_retention_policy_lock.metadata.json +++ b/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_log_retention_policy_lock/cloudstorage_bucket_log_retention_policy_lock.metadata.json @@ -9,14 +9,14 @@ "Severity": "medium", "ResourceType": "Bucket", "Description": "Enabling retention policies on log buckets will protect logs stored in cloud storage buckets from being overwritten or accidentally deleted.", - "Risk": "Sinks can be configured to export logs in storage buckets. It is recommended to configure a data retention policy for these cloud storage buckets and to lock the data retention policy; thus permanently preventing the policy from being reduced or removed. This way, if the system is ever compromised by an attacker or a malicious insider who wants to cover their tracks, the activity logs are definitely preserved for forensics and security investigations.", + "Risk": "Sinks can be configured to export logs in storage buckets. It is recommended to configure a data retention policy for these cloud storage buckets and to lock the data retention policy, thus permanently preventing the policy from being reduced or removed. This way, if the system is ever compromised by an attacker or a malicious insider who wants to cover their tracks, the activity logs are definitely preserved for forensics and security investigations.", "RelatedUrl": "", "Remediation": { "Code": { "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudStorage/retention-policies-with-bucket-lock.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-retention-policies-on-log-buckets-are-configured-using-bucket-lock#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/logging-policies-1/ensure-that-retention-policies-on-log-buckets-are-configured-using-bucket-lock#terraform" }, "Recommendation": { "Text": "It is recommended to set up retention policies and configure Bucket Lock on all storage buckets that are used as log sinks.", diff --git a/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_public_access/cloudstorage_bucket_public_access.metadata.json b/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_public_access/cloudstorage_bucket_public_access.metadata.json index bb01ec499f..4be20f2f10 100644 --- a/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_public_access/cloudstorage_bucket_public_access.metadata.json +++ b/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_public_access/cloudstorage_bucket_public_access.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_public_1#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-public-policies/bc_gcp_public_1#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudStorage/publicly-accessible-storage-buckets.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_public_1#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-public-policies/bc_gcp_public_1#terraform" }, "Recommendation": { "Text": "It is recommended that IAM policy on Cloud Storage bucket does not allows anonymous or public access.", diff --git a/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_uniform_bucket_level_access/cloudstorage_bucket_uniform_bucket_level_access.metadata.json b/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_uniform_bucket_level_access/cloudstorage_bucket_uniform_bucket_level_access.metadata.json index 22a2d42f68..48b3478def 100644 --- a/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_uniform_bucket_level_access/cloudstorage_bucket_uniform_bucket_level_access.metadata.json +++ b/prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_uniform_bucket_level_access/cloudstorage_bucket_uniform_bucket_level_access.metadata.json @@ -16,7 +16,7 @@ "CLI": "gsutil uniformbucketlevelaccess set on gs://BUCKET_NAME/", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudStorage/enable-uniform-bucket-level-access.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_gcs_2#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-storage-gcs-policies/bc_gcp_gcs_2#terraform" }, "Recommendation": { "Text": "It is recommended that uniform bucket-level access is enabled on Cloud Storage buckets.", diff --git a/prowler/providers/gcp/services/compute/compute_firewall_rdp_access_from_the_internet_allowed/compute_firewall_rdp_access_from_the_internet_allowed.metadata.json b/prowler/providers/gcp/services/compute/compute_firewall_rdp_access_from_the_internet_allowed/compute_firewall_rdp_access_from_the_internet_allowed.metadata.json index c5eb00c216..14329e289a 100644 --- a/prowler/providers/gcp/services/compute/compute_firewall_rdp_access_from_the_internet_allowed/compute_firewall_rdp_access_from_the_internet_allowed.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_firewall_rdp_access_from_the_internet_allowed/compute_firewall_rdp_access_from_the_internet_allowed.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_networking_2#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_2#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudVPC/unrestricted-rdp-access.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_2#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_2#terraform" }, "Recommendation": { "Text": "Ensure that Google Cloud Virtual Private Cloud (VPC) firewall rules do not allow unrestricted access (i.e. 0.0.0.0/0) on TCP port 3389 in order to restrict Remote Desktop Protocol (RDP) traffic to trusted IP addresses or IP ranges only and reduce the attack surface. TCP port 3389 is used for secure remote GUI login to Windows VM instances by connecting a RDP client application with an RDP server.", diff --git a/prowler/providers/gcp/services/compute/compute_firewall_ssh_access_from_the_internet_allowed/compute_firewall_ssh_access_from_the_internet_allowed.metadata.json b/prowler/providers/gcp/services/compute/compute_firewall_ssh_access_from_the_internet_allowed/compute_firewall_ssh_access_from_the_internet_allowed.metadata.json index df73805a17..fb94f30358 100644 --- a/prowler/providers/gcp/services/compute/compute_firewall_ssh_access_from_the_internet_allowed/compute_firewall_ssh_access_from_the_internet_allowed.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_firewall_ssh_access_from_the_internet_allowed/compute_firewall_ssh_access_from_the_internet_allowed.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_networking_1#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_1#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudVPC/unrestricted-ssh-access.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_1#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_1#terraform" }, "Recommendation": { "Text": "Check your Google Cloud Virtual Private Cloud (VPC) firewall rules for inbound rules that allow unrestricted access (i.e. 0.0.0.0/0) on TCP port 22 and restrict the access to trusted IP addresses or IP ranges only in order to implement the principle of least privilege and reduce the attack surface. TCP port 22 is used for secure remote login by connecting an SSH client application with an SSH server. It is strongly recommended to configure your Google Cloud VPC firewall rules to limit inbound traffic on TCP port 22 to known IP addresses only.", diff --git a/prowler/providers/gcp/services/compute/compute_instance_block_project_wide_ssh_keys_disabled/compute_instance_block_project_wide_ssh_keys_disabled.metadata.json b/prowler/providers/gcp/services/compute/compute_instance_block_project_wide_ssh_keys_disabled/compute_instance_block_project_wide_ssh_keys_disabled.metadata.json index 76219675e9..ce1a4b8639 100644 --- a/prowler/providers/gcp/services/compute/compute_instance_block_project_wide_ssh_keys_disabled/compute_instance_block_project_wide_ssh_keys_disabled.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_instance_block_project_wide_ssh_keys_disabled/compute_instance_block_project_wide_ssh_keys_disabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_networking_8#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_8#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-block-project-wide-ssh-keys.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_8#cli-command" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_8#cli-command" }, "Recommendation": { "Text": "It is recommended to use Instance specific SSH keys which can limit the attack surface if the SSH keys are compromised.", diff --git a/prowler/providers/gcp/services/compute/compute_instance_default_service_account_in_use/compute_instance_default_service_account_in_use.metadata.json b/prowler/providers/gcp/services/compute/compute_instance_default_service_account_in_use/compute_instance_default_service_account_in_use.metadata.json index e1d8aa152f..47d89c92c0 100644 --- a/prowler/providers/gcp/services/compute/compute_instance_default_service_account_in_use/compute_instance_default_service_account_in_use.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_instance_default_service_account_in_use/compute_instance_default_service_account_in_use.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_iam_1#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_1#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/default-service-accounts-in-use.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_iam_1#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_1#terraform" }, "Recommendation": { "Text": "To defend against privilege escalations if your VM is compromised and prevent an attacker from gaining access to all of your project, it is recommended to not use the default Compute Engine service account. Instead, you should create a new service account and assigning only the permissions needed by your instance. The default Compute Engine service account is named `[PROJECT_NUMBER]-compute@developer.gserviceaccount.com`.", diff --git a/prowler/providers/gcp/services/compute/compute_instance_default_service_account_in_use_with_full_api_access/compute_instance_default_service_account_in_use_with_full_api_access.metadata.json b/prowler/providers/gcp/services/compute/compute_instance_default_service_account_in_use_with_full_api_access/compute_instance_default_service_account_in_use_with_full_api_access.metadata.json index 513bcc0f86..ba66fa8553 100644 --- a/prowler/providers/gcp/services/compute/compute_instance_default_service_account_in_use_with_full_api_access/compute_instance_default_service_account_in_use_with_full_api_access.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_instance_default_service_account_in_use_with_full_api_access/compute_instance_default_service_account_in_use_with_full_api_access.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_iam_2#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_2#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/default-service-accounts-with-full-access-in-use.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_iam_2#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_2#terraform" }, "Recommendation": { "Text": "To enforce the principle of least privileges and prevent potential privilege escalation, ensure that your Google Compute Engine instances are not configured to use the default service account with the Cloud API access scope set to \"Allow full access to all Cloud APIs\". The principle of least privilege (POLP), also known as the principle of least authority, is the security concept of giving the user/system/service the minimal set of permissions required to successfully perform its tasks.", diff --git a/prowler/providers/gcp/services/compute/compute_instance_encryption_with_csek_enabled/compute_instance_encryption_with_csek_enabled.metadata.json b/prowler/providers/gcp/services/compute/compute_instance_encryption_with_csek_enabled/compute_instance_encryption_with_csek_enabled.metadata.json index 3223c5135e..268d482668 100644 --- a/prowler/providers/gcp/services/compute/compute_instance_encryption_with_csek_enabled/compute_instance_encryption_with_csek_enabled.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_instance_encryption_with_csek_enabled/compute_instance_encryption_with_csek_enabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_general_x#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/bc_gcp_general_x#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-encryption-with-csek.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_general_x#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/bc_gcp_general_x#terraform" }, "Recommendation": { "Text": "Ensure that the disks attached to your production Google Compute Engine instances are encrypted with Customer-Supplied Encryption Keys (CSEKs) in order to have complete control over the data-at-rest encryption and decryption process, and meet strict compliance requirements. These custom keys, also known as Customer-Supplied Encryption Keys (CSEKs), are used by Google Compute Engine to protect the Google-generated keys used to encrypt and decrypt your instance data. Compute Engine service does not store your CSEKs on its servers and cannot access your protected data unless you provide the required key.", diff --git a/prowler/providers/gcp/services/compute/compute_instance_ip_forwarding_is_enabled/compute_instance_ip_forwarding_is_enabled.metadata.json b/prowler/providers/gcp/services/compute/compute_instance_ip_forwarding_is_enabled/compute_instance_ip_forwarding_is_enabled.metadata.json index 58f2045f9f..6da982c17e 100644 --- a/prowler/providers/gcp/services/compute/compute_instance_ip_forwarding_is_enabled/compute_instance_ip_forwarding_is_enabled.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_instance_ip_forwarding_is_enabled/compute_instance_ip_forwarding_is_enabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_networking_12#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_12#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/disable-ip-forwarding.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_12#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_12#terraform" }, "Recommendation": { "Text": "Ensure that IP Forwarding feature is not enabled at the Google Compute Engine instance level for security and compliance reasons, as instances with IP Forwarding enabled act as routers/packet forwarders. Because IP forwarding is rarely required, except when the virtual machine (VM) is used as a network virtual appliance, each Google Cloud VM instance should be reviewed in order to decide whether the IP forwarding is really needed for the verified instance. IP Forwarding is enabled at the VM instance level and applies to all network interfaces (NICs) attached to the instance. In addition, Instances created by GKE should be excluded from this recommendation because they need to have IP forwarding enabled and cannot be changed. Instances created by GKE have names that start with \"gke- \".", diff --git a/prowler/providers/gcp/services/compute/compute_instance_public_ip/compute_instance_public_ip.metadata.json b/prowler/providers/gcp/services/compute/compute_instance_public_ip/compute_instance_public_ip.metadata.json index 992c653b22..bd9ddb1a9b 100644 --- a/prowler/providers/gcp/services/compute/compute_instance_public_ip/compute_instance_public_ip.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_instance_public_ip/compute_instance_public_ip.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_public_2#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-public-policies/bc_gcp_public_2#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/Compute/instances-with-public-ip-addresses.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_public_2#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-public-policies/bc_gcp_public_2#terraform" }, "Recommendation": { "Text": "Ensure that your Google Compute Engine instances are not configured to have external IP addresses in order to minimize their exposure to the Internet.", diff --git a/prowler/providers/gcp/services/compute/compute_instance_serial_ports_in_use/compute_instance_serial_ports_in_use.metadata.json b/prowler/providers/gcp/services/compute/compute_instance_serial_ports_in_use/compute_instance_serial_ports_in_use.metadata.json index 147af062cd..e1e7877f80 100644 --- a/prowler/providers/gcp/services/compute/compute_instance_serial_ports_in_use/compute_instance_serial_ports_in_use.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_instance_serial_ports_in_use/compute_instance_serial_ports_in_use.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_networking_11#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_11#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/disable-interactive-serial-console-support.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_11#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_11#terraform" }, "Recommendation": { "Text": "Ensure that \"Enable connecting to serial ports\" configuration setting is disabled for all your production Google Compute Engine instances. A Google Cloud virtual machine (VM) instance has 4 virtual serial ports. On your VM instances, the operating system (OS), BIOS, and other system-level entities write often output data to the serial ports and can accept input, such as commands or answers, to prompts. Usually, these system-level entities use the first serial port (Port 1) and Serial Port 1 is often referred to as the interactive serial console. This interactive serial console does not support IP-based access restrictions such as IP address whitelists. To adhere to cloud security best practices and reduce the risk of unauthorized access, interactive serial console support should be disabled for all instances used in production.", diff --git a/prowler/providers/gcp/services/compute/compute_instance_shielded_vm_enabled/compute_instance_shielded_vm_enabled.metadata.json b/prowler/providers/gcp/services/compute/compute_instance_shielded_vm_enabled/compute_instance_shielded_vm_enabled.metadata.json index 305fa6d39c..7a1da1e37e 100644 --- a/prowler/providers/gcp/services/compute/compute_instance_shielded_vm_enabled/compute_instance_shielded_vm_enabled.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_instance_shielded_vm_enabled/compute_instance_shielded_vm_enabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_general_y#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/bc_gcp_general_y#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-shielded-vm.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_general_y#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/bc_gcp_general_y#terraform" }, "Recommendation": { "Text": "Ensure that your Google Compute Engine instances are configured to use Shielded VM security feature for protection against rootkits and bootkits.Google Compute Engine service can enable 3 advanced security components for Shielded VM instances: 1. Virtual Trusted Platform Module (vTPM) - this component validates the guest virtual machine (VM) pre-boot and boot integrity, and provides key generation and protection. 2. Integrity Monitoring - lets you monitor and verify the runtime boot integrity of your shielded VM instances using Google Cloud Operations reports (also known as Stackdriver reports). 3. Secure boot helps - this security component protects your VM instances against boot-level and kernel-level malware and rootkits. To defend against advanced threats and ensure that the boot loader and firmware on your Google Compute Engine instances are signed and untampered, it is strongly recommended that your production instances are launched with Shielded VM enabled.", diff --git a/prowler/providers/gcp/services/compute/compute_network_default_in_use/compute_network_default_in_use.metadata.json b/prowler/providers/gcp/services/compute/compute_network_default_in_use/compute_network_default_in_use.metadata.json index 544a80b6d8..884bead637 100644 --- a/prowler/providers/gcp/services/compute/compute_network_default_in_use/compute_network_default_in_use.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_network_default_in_use/compute_network_default_in_use.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_networking_7#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_7#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudVPC/default-vpc-in-use.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_7#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_7#terraform" }, "Recommendation": { "Text": "When an organization deletes the default network, it may need to migrate or service onto a new network.", diff --git a/prowler/providers/gcp/services/compute/compute_network_not_legacy/compute_network_not_legacy.metadata.json b/prowler/providers/gcp/services/compute/compute_network_not_legacy/compute_network_not_legacy.metadata.json index e412ff9381..698e9e76f5 100644 --- a/prowler/providers/gcp/services/compute/compute_network_not_legacy/compute_network_not_legacy.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_network_not_legacy/compute_network_not_legacy.metadata.json @@ -16,7 +16,7 @@ "CLI": "gcloud compute networks delete ", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudVPC/legacy-vpc-in-use.html#", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-legacy-networks-do-not-exist-for-a-project#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/ensure-legacy-networks-do-not-exist-for-a-project#terraform" }, "Recommendation": { "Text": "Ensure that your Google Cloud Platform (GCP) projects are not using legacy networks as this type of network is no longer recommended for production environments because it does not support advanced networking features. Instead, it is strongly recommended to use Virtual Private Cloud (VPC) networks for existing and future GCP projects.", diff --git a/prowler/providers/gcp/services/compute/compute_project_os_login_enabled/compute_project_os_login_enabled.metadata.json b/prowler/providers/gcp/services/compute/compute_project_os_login_enabled/compute_project_os_login_enabled.metadata.json index ad1fd1cc9b..dd9f987114 100644 --- a/prowler/providers/gcp/services/compute/compute_project_os_login_enabled/compute_project_os_login_enabled.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_project_os_login_enabled/compute_project_os_login_enabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_networking_9#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_9#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-os-login.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_9#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_9#terraform" }, "Recommendation": { "Text": "Ensure that the OS Login feature is enabled at the Google Cloud Platform (GCP) project level in order to provide you with centralized and automated SSH key pair management.", diff --git a/prowler/providers/gcp/services/compute/compute_public_address_shodan/compute_public_address_shodan.metadata.json b/prowler/providers/gcp/services/compute/compute_public_address_shodan/compute_public_address_shodan.metadata.json index dd905c0280..5c19d5d1f7 100644 --- a/prowler/providers/gcp/services/compute/compute_public_address_shodan/compute_public_address_shodan.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_public_address_shodan/compute_public_address_shodan.metadata.json @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Check Identified IPs; consider changing them to private ones and delete them from Shodan.", + "Text": "Check Identified IPs, consider changing them to private ones and delete them from Shodan.", "Url": "https://www.shodan.io/" } }, diff --git a/prowler/providers/gcp/services/compute/compute_subnet_flow_logs_enabled/compute_subnet_flow_logs_enabled.metadata.json b/prowler/providers/gcp/services/compute/compute_subnet_flow_logs_enabled/compute_subnet_flow_logs_enabled.metadata.json index 4f64233a7b..09db271640 100644 --- a/prowler/providers/gcp/services/compute/compute_subnet_flow_logs_enabled/compute_subnet_flow_logs_enabled.metadata.json +++ b/prowler/providers/gcp/services/compute/compute_subnet_flow_logs_enabled/compute_subnet_flow_logs_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "gcloud compute networks subnets update [SUBNET_NAME] --region [REGION] --enable-flow-logs", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudVPC/enable-vpc-flow-logs.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_logging_1#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/logging-policies-1/bc_gcp_logging_1#terraform" }, "Recommendation": { "Text": "Ensure that VPC Flow Logs is enabled for every subnet created within your production Virtual Private Cloud (VPC) network. Flow Logs is a logging feature that enables users to capture information about the IP traffic (accepted, rejected, or all traffic) going to and from the network interfaces (ENIs) available within your VPC subnets.", diff --git a/prowler/providers/gcp/services/dataproc/dataproc_encrypted_with_cmks_disabled/dataproc_encrypted_with_cmks_disabled.metadata.json b/prowler/providers/gcp/services/dataproc/dataproc_encrypted_with_cmks_disabled/dataproc_encrypted_with_cmks_disabled.metadata.json index 2e8a8a60f7..afd3aa5857 100644 --- a/prowler/providers/gcp/services/dataproc/dataproc_encrypted_with_cmks_disabled/dataproc_encrypted_with_cmks_disabled.metadata.json +++ b/prowler/providers/gcp/services/dataproc/dataproc_encrypted_with_cmks_disabled/dataproc_encrypted_with_cmks_disabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/Dataproc/enable-encryption-with-cmks-for-dataproc-clusters.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-gcp-dataproc-cluster-is-encrypted-with-customer-supplied-encryption-keys-cseks#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/ensure-gcp-dataproc-cluster-is-encrypted-with-customer-supplied-encryption-keys-cseks#terraform" }, "Recommendation": { "Text": "Ensure that your Google Cloud Dataproc clusters on Compute Engine are encrypted with Customer-Managed Keys (CMKs) in order to control the cluster data encryption/decryption process. You can create and manage your own Customer-Managed Keys (CMKs) with Cloud Key Management Service (Cloud KMS). Cloud KMS provides secure and efficient encryption key management, controlled key rotation, and revocation mechanisms.", diff --git a/prowler/providers/gcp/services/dns/dns_dnssec_disabled/dns_dnssec_disabled.metadata.json b/prowler/providers/gcp/services/dns/dns_dnssec_disabled/dns_dnssec_disabled.metadata.json index ab27972f26..cbc44fc755 100644 --- a/prowler/providers/gcp/services/dns/dns_dnssec_disabled/dns_dnssec_disabled.metadata.json +++ b/prowler/providers/gcp/services/dns/dns_dnssec_disabled/dns_dnssec_disabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_networking_5#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_5#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudDNS/enable-dns-sec.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_5#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_5#terraform" }, "Recommendation": { "Text": "Ensure that DNSSEC security feature is enabled for all your Google Cloud DNS managed zones in order to protect your domains against spoofing and cache poisoning attacks. By default, DNSSEC is not enabled for Google Cloud public DNS managed zones. DNSSEC security feature helps mitigate the risk of such attacks by encrypting signing DNS records. As a result, it prevents attackers from issuing fake DNS responses that may misdirect web clients to fake, fraudulent or scam websites.", diff --git a/prowler/providers/gcp/services/dns/dns_rsasha1_in_use_to_key_sign_in_dnssec/dns_rsasha1_in_use_to_key_sign_in_dnssec.metadata.json b/prowler/providers/gcp/services/dns/dns_rsasha1_in_use_to_key_sign_in_dnssec/dns_rsasha1_in_use_to_key_sign_in_dnssec.metadata.json index 6a65d4c941..834f802542 100644 --- a/prowler/providers/gcp/services/dns/dns_rsasha1_in_use_to_key_sign_in_dnssec/dns_rsasha1_in_use_to_key_sign_in_dnssec.metadata.json +++ b/prowler/providers/gcp/services/dns/dns_rsasha1_in_use_to_key_sign_in_dnssec/dns_rsasha1_in_use_to_key_sign_in_dnssec.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudDNS/dns-sec-key-signing-algorithm-in-use.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_6#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_6#terraform" }, "Recommendation": { "Text": "Ensure that Domain Name System Security Extensions (DNSSEC) feature is not using the deprecated RSASHA1 algorithm for the Key-Signing Key (KSK) associated with your DNS managed zone file. The algorithm used for DNSSEC signing should be a strong one, such as ECDSAP256SHA256 algorithm, as this is secure and widely deployed, and therefore it is a good choice for both DNSSEC validation and signing.", diff --git a/prowler/providers/gcp/services/dns/dns_rsasha1_in_use_to_zone_sign_in_dnssec/dns_rsasha1_in_use_to_zone_sign_in_dnssec.metadata.json b/prowler/providers/gcp/services/dns/dns_rsasha1_in_use_to_zone_sign_in_dnssec/dns_rsasha1_in_use_to_zone_sign_in_dnssec.metadata.json index 9bada30874..3ccae85385 100644 --- a/prowler/providers/gcp/services/dns/dns_rsasha1_in_use_to_zone_sign_in_dnssec/dns_rsasha1_in_use_to_zone_sign_in_dnssec.metadata.json +++ b/prowler/providers/gcp/services/dns/dns_rsasha1_in_use_to_zone_sign_in_dnssec/dns_rsasha1_in_use_to_zone_sign_in_dnssec.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudDNS/dns-sec-zone-signing-algorithm-in-use.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_networking_6#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/bc_gcp_networking_6#terraform" }, "Recommendation": { "Text": "Ensure that Domain Name System Security Extensions (DNSSEC) feature is not using the deprecated RSASHA1 algorithm for the Zone-Signing Key (ZSK) associated with your public DNS managed zone. The algorithm used for DNSSEC signing should be a strong one, such as RSASHA256, as this algorithm is secure and widely deployed, and therefore it is a good candidate for both DNSSEC validation and signing.", diff --git a/prowler/providers/gcp/services/gcr/gcr_container_scanning_enabled/gcr_container_scanning_enabled.metadata.json b/prowler/providers/gcp/services/gcr/gcr_container_scanning_enabled/gcr_container_scanning_enabled.metadata.json index e4b44dcce0..652510884f 100644 --- a/prowler/providers/gcp/services/gcr/gcr_container_scanning_enabled/gcr_container_scanning_enabled.metadata.json +++ b/prowler/providers/gcp/services/gcr/gcr_container_scanning_enabled/gcr_container_scanning_enabled.metadata.json @@ -19,7 +19,7 @@ "CLI": "gcloud services enable containerscanning.googleapis.com", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-gcp-gcr-container-vulnerability-scanning-is-enabled#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-networking-policies/ensure-gcp-gcr-container-vulnerability-scanning-is-enabled#terraform" }, "Recommendation": { "Text": "Enable vulnerability scanning for images stored in GCR using GCR Container Scanning or a third-party provider.", diff --git a/prowler/providers/gcp/services/gke/gke_cluster_no_default_service_account/gke_cluster_no_default_service_account.metadata.json b/prowler/providers/gcp/services/gke/gke_cluster_no_default_service_account/gke_cluster_no_default_service_account.metadata.json index 18fac537df..d7a8eef9c4 100644 --- a/prowler/providers/gcp/services/gke/gke_cluster_no_default_service_account/gke_cluster_no_default_service_account.metadata.json +++ b/prowler/providers/gcp/services/gke/gke_cluster_no_default_service_account/gke_cluster_no_default_service_account.metadata.json @@ -19,7 +19,7 @@ "CLI": "gcloud container node-pools create [NODE_POOL] --service-account=[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com --cluster=[CLUSTER_NAME] --zone [COMPUTE_ZONE]", "NativeIaC": "", "Other": "", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-gke-clusters-are-not-running-using-the-compute-engine-default-service-account#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-kubernetes-policies/ensure-gke-clusters-are-not-running-using-the-compute-engine-default-service-account#terraform" }, "Recommendation": { "Text": "Create and use minimally privileged service accounts for GKE cluster nodes instead of using the Compute Engine default service account.", diff --git a/prowler/providers/gcp/services/iam/iam_audit_logs_enabled/iam_audit_logs_enabled.metadata.json b/prowler/providers/gcp/services/iam/iam_audit_logs_enabled/iam_audit_logs_enabled.metadata.json index a723c53a53..e3d448c257 100644 --- a/prowler/providers/gcp/services/iam/iam_audit_logs_enabled/iam_audit_logs_enabled.metadata.json +++ b/prowler/providers/gcp/services/iam/iam_audit_logs_enabled/iam_audit_logs_enabled.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/record-all-activities.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-cloud-audit-logging-is-configured-properly-across-all-services-and-all-users-from-a-project#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/logging-policies-1/ensure-that-cloud-audit-logging-is-configured-properly-across-all-services-and-all-users-from-a-project#terraform" }, "Recommendation": { "Text": "It is recommended that Cloud Audit Logging is configured to track all admin activities and read, write access to user data.", diff --git a/prowler/providers/gcp/services/iam/iam_no_service_roles_at_project_level/iam_no_service_roles_at_project_level.metadata.json b/prowler/providers/gcp/services/iam/iam_no_service_roles_at_project_level/iam_no_service_roles_at_project_level.metadata.json index 70cfa5e6f9..cf74bd7d8b 100644 --- a/prowler/providers/gcp/services/iam/iam_no_service_roles_at_project_level/iam_no_service_roles_at_project_level.metadata.json +++ b/prowler/providers/gcp/services/iam/iam_no_service_roles_at_project_level/iam_no_service_roles_at_project_level.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_iam_3#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_3#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/check-for-iam-users-with-service-roles.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_iam_3#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_3#terraform" }, "Recommendation": { "Text": "Ensure that the Service Account User and Service Account Token Creator roles are assigned to a user for a specific GCP service account rather than to a user at the GCP project level, in order to implement the principle of least privilege (POLP). The principle of least privilege (also known as the principle of minimal privilege) is the practice of providing every user the minimal amount of access required to perform its tasks. Google Cloud Platform (GCP) IAM users should not have assigned the Service Account User or Service Account Token Creator roles at the GCP project level. Instead, these roles should be allocated to a user associated with a specific service account, providing that user access to the service account only.", diff --git a/prowler/providers/gcp/services/iam/iam_role_sa_enforce_separation_of_duties/iam_role_sa_enforce_separation_of_duties.metadata.json b/prowler/providers/gcp/services/iam/iam_role_sa_enforce_separation_of_duties/iam_role_sa_enforce_separation_of_duties.metadata.json index 925d086316..1afd7e17e8 100644 --- a/prowler/providers/gcp/services/iam/iam_role_sa_enforce_separation_of_duties/iam_role_sa_enforce_separation_of_duties.metadata.json +++ b/prowler/providers/gcp/services/iam/iam_role_sa_enforce_separation_of_duties/iam_role_sa_enforce_separation_of_duties.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/enforce-separation-of-duties-for-service-account-roles.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_iam_10#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_10#terraform" }, "Recommendation": { "Text": "Ensure that separation of duties (also known as segregation of duties - SoD) is enforced for all Google Cloud Platform (GCP) service-account related roles. The security principle of separation of duties has as its primary objective the prevention of fraud and human error. This objective is achieved by disbanding the tasks and associated privileges for a specific business process among multiple users/members. To follow security best practices, your GCP service accounts should not have the Service Account Admin and Service Account User roles assigned at the same time.", diff --git a/prowler/providers/gcp/services/iam/iam_sa_no_administrative_privileges/iam_sa_no_administrative_privileges.metadata.json b/prowler/providers/gcp/services/iam/iam_sa_no_administrative_privileges/iam_sa_no_administrative_privileges.metadata.json index f8e71cd892..8f13d0cf0f 100644 --- a/prowler/providers/gcp/services/iam/iam_sa_no_administrative_privileges/iam_sa_no_administrative_privileges.metadata.json +++ b/prowler/providers/gcp/services/iam/iam_sa_no_administrative_privileges/iam_sa_no_administrative_privileges.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_iam_4#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_4#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/restrict-admin-access-for-service-accounts.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_iam_4#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-iam-policies/bc_gcp_iam_4#terraform" }, "Recommendation": { "Text": "Ensure that your Google Cloud user-managed service accounts are not using privileged (administrator) roles, in order to implement the principle of least privilege and prevent any accidental or intentional modifications that may lead to data leaks and/or data loss.", diff --git a/prowler/providers/gcp/services/iam/iam_service.py b/prowler/providers/gcp/services/iam/iam_service.py index d9690ff396..c23985d869 100644 --- a/prowler/providers/gcp/services/iam/iam_service.py +++ b/prowler/providers/gcp/services/iam/iam_service.py @@ -116,12 +116,11 @@ class AccessApproval(GCPService): name=f"projects/{project_id}/accessApprovalSettings" ) ).execute() - self.settings[project_id].append( - Setting( - name=response["name"], - project_id=project_id, - ) + self.settings[project_id] = Setting( + name=response["name"], + project_id=project_id, ) + except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -155,7 +154,7 @@ class EssentialContacts(GCPService): self.organizations.append( Organization( name=org.name, - email=org.id, + id=org.id, contacts=contacts, ) ) diff --git a/prowler/providers/gcp/services/kms/kms_key_not_publicly_accessible/kms_key_not_publicly_accessible.metadata.json b/prowler/providers/gcp/services/kms/kms_key_not_publicly_accessible/kms_key_not_publicly_accessible.metadata.json index f74d58eb2d..5c828ce7a2 100644 --- a/prowler/providers/gcp/services/kms/kms_key_not_publicly_accessible/kms_key_not_publicly_accessible.metadata.json +++ b/prowler/providers/gcp/services/kms/kms_key_not_publicly_accessible/kms_key_not_publicly_accessible.metadata.json @@ -16,7 +16,7 @@ "CLI": "", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudKMS/publicly-accessible-kms-cryptokeys.html", - "Terraform": "https://docs.bridgecrew.io/docs/ensure-that-cloud-kms-cryptokeys-are-not-anonymously-or-publicly-accessible#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/ensure-that-cloud-kms-cryptokeys-are-not-anonymously-or-publicly-accessible#terraform" }, "Recommendation": { "Text": "To deny access from anonymous and public users, remove the bindings for 'allUsers' and 'allAuthenticatedUsers' members from the KMS key's IAM policy.", diff --git a/prowler/providers/gcp/services/kms/kms_key_rotation_enabled/kms_key_rotation_enabled.metadata.json b/prowler/providers/gcp/services/kms/kms_key_rotation_enabled/kms_key_rotation_enabled.metadata.json index 62803f12ea..7f898bcbb0 100644 --- a/prowler/providers/gcp/services/kms/kms_key_rotation_enabled/kms_key_rotation_enabled.metadata.json +++ b/prowler/providers/gcp/services/kms/kms_key_rotation_enabled/kms_key_rotation_enabled.metadata.json @@ -13,10 +13,10 @@ "RelatedUrl": "", "Remediation": { "Code": { - "CLI": "https://docs.bridgecrew.io/docs/bc_gcp_general_4#cli-command", + "CLI": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/bc_gcp_general_4#cli-command", "NativeIaC": "", "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudKMS/rotate-kms-encryption-keys.html", - "Terraform": "https://docs.bridgecrew.io/docs/bc_gcp_general_4#terraform" + "Terraform": "https://docs.prowler.com/checks/gcp/google-cloud-general-policies/bc_gcp_general_4#terraform" }, "Recommendation": { "Text": "After a successful key rotation, the older key version is required in order to decrypt the data encrypted by that previous key version.", diff --git a/tests/lib/check/check_loader_test.py b/tests/lib/check/check_loader_test.py index 5b887d3b95..c562a6465e 100644 --- a/tests/lib/check/check_loader_test.py +++ b/tests/lib/check/check_loader_test.py @@ -40,7 +40,7 @@ class TestCheckLoader: Remediation=Remediation( Code=Code( NativeIaC="", - Terraform="https://docs.bridgecrew.io/docs/bc_aws_s3_20#terraform", + Terraform="https://docs.prowler.com/checks/aws/s3-policies/bc_aws_s3_20#terraform", CLI="aws s3api put-public-access-block --region --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true --bucket ", Other="https://github.com/cloudmatos/matos/tree/master/remediations/aws/s3/s3/block-public-access", ), diff --git a/tests/lib/check/custom_checks_metadata_test.py b/tests/lib/check/custom_checks_metadata_test.py index c7f12459d9..b51f7e83a5 100644 --- a/tests/lib/check/custom_checks_metadata_test.py +++ b/tests/lib/check/custom_checks_metadata_test.py @@ -45,7 +45,7 @@ class TestCustomChecksMetadata: Remediation=Remediation( Code=Code( NativeIaC="", - Terraform="https://docs.bridgecrew.io/docs/bc_aws_s3_20#terraform", + Terraform="https://docs.prowler.com/checks/aws/s3-policies/bc_aws_s3_20#terraform", CLI="aws s3api put-public-access-block --region --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true --bucket ", Other="https://github.com/cloudmatos/matos/tree/master/remediations/aws/s3/s3/block-public-access", ), diff --git a/tests/lib/check/fixtures/bulk_checks_metadata.py b/tests/lib/check/fixtures/bulk_checks_metadata.py index e6afce2641..977f40bbb1 100644 --- a/tests/lib/check/fixtures/bulk_checks_metadata.py +++ b/tests/lib/check/fixtures/bulk_checks_metadata.py @@ -23,7 +23,7 @@ test_bulk_checks_metadata = { Code=Code( NativeIaC="", Terraform="", - CLI="https://docs.bridgecrew.io/docs/networking_5#cli-command", + CLI="https://docs.prowler.com/checks/networking_5#cli-command", Other="", ), Recommendation=Recommendation( @@ -107,8 +107,8 @@ test_bulk_checks_metadata = { RelatedUrl="https://docs.aws.amazon.com/workspaces/latest/adminguide/encrypt-workspaces.html", Remediation=Remediation( Code=Code( - NativeIaC="https://docs.bridgecrew.io/docs/ensure-that-workspace-root-volumes-are-encrypted#cloudformation", - Terraform="https://docs.bridgecrew.io/docs/ensure-that-workspace-root-volumes-are-encrypted#terraform", + NativeIaC="https://docs.prowler.com/checks/ensure-that-workspace-root-volumes-are-encrypted#cloudformation", + Terraform="https://docs.prowler.com/checks/ensure-that-workspace-root-volumes-are-encrypted#terraform", CLI="", Other="https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/WorkSpaces/storage-encryption.html", ), diff --git a/tests/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations_test.py b/tests/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations_test.py index 898d6785a1..d2aac9c79a 100644 --- a/tests/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations_test.py +++ b/tests/providers/aws/services/account/account_maintain_different_contact_details_to_security_billing_and_operations/account_maintain_different_contact_details_to_security_billing_and_operations_test.py @@ -101,3 +101,29 @@ class Test_account_maintain_different_contact_details_to_security_billing_and_op assert result[0].region == AWS_REGION assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert result[0].resource_arn == AWS_ACCOUNT_ARN + + def test_access_denied(self): + account_client = mock.MagicMock + account_client.region = AWS_REGION + account_client.audited_account = AWS_ACCOUNT_NUMBER + account_client.audited_account_arn = AWS_ACCOUNT_ARN + account_client.contact_base = None + + with mock.patch( + "prowler.providers.aws.services.account.account_service.Account", + new=account_client, + ), mock.patch( + "prowler.providers.aws.services.account.account_client.account_client", + new=account_client, + ): + # Test Check + from prowler.providers.aws.services.account.account_maintain_different_contact_details_to_security_billing_and_operations.account_maintain_different_contact_details_to_security_billing_and_operations import ( + account_maintain_different_contact_details_to_security_billing_and_operations, + ) + + check = ( + account_maintain_different_contact_details_to_security_billing_and_operations() + ) + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/backup/backup_vaults_exist/backup_vaults_exist_test.py b/tests/providers/aws/services/backup/backup_vaults_exist/backup_vaults_exist_test.py index 857ae0d9c5..c8da157443 100644 --- a/tests/providers/aws/services/backup/backup_vaults_exist/backup_vaults_exist_test.py +++ b/tests/providers/aws/services/backup/backup_vaults_exist/backup_vaults_exist_test.py @@ -85,3 +85,28 @@ class Test_backup_vaults_exist: assert result[0].resource_id == "MyBackupVault" assert result[0].resource_arn == backup_vault_arn assert result[0].region == AWS_REGION + + def test_access_denied(self): + backup_client = mock.MagicMock + backup_client.audited_account = AWS_ACCOUNT_NUMBER + backup_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + backup_client.region = AWS_REGION + backup_client.audited_partition = "aws" + backup_client.backup_vault_arn_template = f"arn:{backup_client.audited_partition}:backup:{backup_client.region}:{backup_client.audited_account}:backup-vault" + backup_client.__get_backup_vault_arn_template__ = mock.MagicMock( + return_value=backup_client.backup_vault_arn_template + ) + backup_client.backup_vaults = None + with mock.patch( + "prowler.providers.aws.services.backup.backup_service.Backup", + new=backup_client, + ): + # Test Check + from prowler.providers.aws.services.backup.backup_vaults_exist.backup_vaults_exist import ( + backup_vaults_exist, + ) + + check = backup_vaults_exist() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete_test.py index 39634ee1ed..bc35bff92c 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete_test.py @@ -254,3 +254,35 @@ class Test_cloudtrail_bucket_requires_mfa_delete: assert result[0].region == AWS_REGION_US_EAST_1 assert result[0].resource_arn == trail_us["TrailARN"] assert result[0].resource_tags == [] + + @mock_aws + @patch( + "botocore.client.BaseClient._make_api_call", + new=mock_make_api_call_getbucketversioning_mfadelete_enabled, + ) + def test_access_denied(self): + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1] + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_bucket_requires_mfa_delete.cloudtrail_bucket_requires_mfa_delete.cloudtrail_client", + new=Cloudtrail(audit_info), + ) as cloudtrail_client, mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_bucket_requires_mfa_delete.cloudtrail_bucket_requires_mfa_delete.s3_client", + new=S3(audit_info), + ) as s3_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_bucket_requires_mfa_delete.cloudtrail_bucket_requires_mfa_delete import ( + cloudtrail_bucket_requires_mfa_delete, + ) + + cloudtrail_client.trails = None + s3_client.buckets = [] + + check = cloudtrail_bucket_requires_mfa_delete() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled_test.py index d4857da69f..99267c0f49 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled_test.py @@ -297,3 +297,32 @@ class Test_cloudtrail_cloudwatch_logging_enabled: == f"Single region trail {trail_name_eu} is not logging in the last 24h or not configured to deliver logs." ) assert report.resource_tags == [] + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]), + ): + with mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_cloudwatch_logging_enabled.cloudtrail_cloudwatch_logging_enabled.cloudtrail_client", + new=Cloudtrail( + set_mocked_aws_audit_info( + [AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1] + ) + ), + ) as service_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_cloudwatch_logging_enabled.cloudtrail_cloudwatch_logging_enabled import ( + cloudtrail_cloudwatch_logging_enabled, + ) + + service_client.trails = None + + check = cloudtrail_cloudwatch_logging_enabled() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist_test.py index 828bd6ed8a..537350f9c3 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist_test.py @@ -128,3 +128,26 @@ class Test_cloudtrail_insights_exist: assert result[0].region == AWS_REGION_US_EAST_1 assert result[0].resource_arn == trail_us["TrailARN"] assert result[0].resource_tags == [] + + @mock_aws + def test_access_denied(self): + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1] + ) + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_insights_exist.cloudtrail_insights_exist.cloudtrail_client", + new=Cloudtrail(audit_info), + ) as service_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_insights_exist.cloudtrail_insights_exist import ( + cloudtrail_insights_exist, + ) + + service_client.trails = None + check = cloudtrail_insights_exist() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled_test.py index d8e971e879..95ece076a3 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled_test.py @@ -131,3 +131,30 @@ class Test_cloudtrail_kms_encryption_enabled: assert result[0].resource_arn == trail_us["TrailARN"] assert result[0].resource_tags == [] assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_aws + def test_access_denied(self): + + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_kms_encryption_enabled.cloudtrail_kms_encryption_enabled.cloudtrail_client", + new=Cloudtrail( + set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]) + ), + ) as service_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_kms_encryption_enabled.cloudtrail_kms_encryption_enabled import ( + cloudtrail_kms_encryption_enabled, + ) + + service_client.trails = None + check = cloudtrail_kms_encryption_enabled() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled_test.py index 360009793b..9ba491e7c1 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled_test.py @@ -149,3 +149,29 @@ class Test_cloudtrail_log_file_validation_enabled: assert report.resource_arn == trail_eu["TrailARN"] assert report.resource_tags == [] assert report.region == AWS_REGION_EU_WEST_1 + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_log_file_validation_enabled.cloudtrail_log_file_validation_enabled.cloudtrail_client", + new=Cloudtrail( + set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]) + ), + ) as service_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_log_file_validation_enabled.cloudtrail_log_file_validation_enabled import ( + cloudtrail_log_file_validation_enabled, + ) + + service_client.trails = None + + check = cloudtrail_log_file_validation_enabled() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled_test.py index a7f6872989..4a3c82c30a 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled_test.py @@ -218,3 +218,38 @@ class Test_cloudtrail_logs_s3_bucket_access_logging_enabled: assert result[0].resource_arn == trail_us["TrailARN"] assert result[0].resource_tags == [] assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_aws + def test_access_denied(self): + + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.s3.s3_service import S3 + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_client", + new=Cloudtrail( + set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]) + ), + ) as cloudtrail_client, mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.s3_client", + new=S3( + set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]) + ), + ) as s3_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled import ( + cloudtrail_logs_s3_bucket_access_logging_enabled, + ) + + cloudtrail_client.trails = None + s3_client.buckets = [] + + check = cloudtrail_logs_s3_bucket_access_logging_enabled() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible_test.py index 262ee94bfa..551941f177 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible_test.py @@ -279,3 +279,38 @@ class Test_cloudtrail_logs_s3_bucket_is_not_publicly_accessible: ) assert result[0].resource_tags == [] assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_aws + def test_access_denied(self): + + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.s3.s3_service import S3 + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_client", + new=Cloudtrail( + set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]) + ), + ) as cloudtrail_client, mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.s3_client", + new=S3( + set_mocked_aws_audit_info([AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1]) + ), + ) as s3_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible import ( + cloudtrail_logs_s3_bucket_is_not_publicly_accessible, + ) + + cloudtrail_client.trails = None + s3_client.buckets = [] + + check = cloudtrail_logs_s3_bucket_is_not_publicly_accessible() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled_test.py index c53356785f..9e947ed03f 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled_test.py @@ -289,3 +289,31 @@ class Test_cloudtrail_multi_region_enabled: assert report.resource_id == trail_name_us assert report.resource_arn == trail_us["TrailARN"] assert report.resource_tags == [] + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1] + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled.cloudtrail_multi_region_enabled.cloudtrail_client", + new=Cloudtrail(audit_info), + ) as service_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled.cloudtrail_multi_region_enabled import ( + cloudtrail_multi_region_enabled, + ) + + service_client.trails = None + check = cloudtrail_multi_region_enabled() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events_test.py index 8f32e0c0cd..026d249be8 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events_test.py @@ -273,3 +273,29 @@ class Test_cloudtrail_multi_region_enabled_logging_management_events: result[0].status_extended == "No trail found with multi-region enabled and logging management events." ) + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled_logging_management_events.cloudtrail_multi_region_enabled_logging_management_events.cloudtrail_client", + new=Cloudtrail(audit_info), + ) as cloudtrail_client: + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled_logging_management_events.cloudtrail_multi_region_enabled_logging_management_events import ( + cloudtrail_multi_region_enabled_logging_management_events, + ) + + cloudtrail_client.trails = None + check = cloudtrail_multi_region_enabled_logging_management_events() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled_test.py index 13a151405b..fd57094a6c 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled_test.py @@ -391,3 +391,33 @@ class Test_cloudtrail_s3_dataevents_read_enabled: assert result[0].resource_arn == trail_us["TrailARN"] assert result[0].resource_tags == [] assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.s3.s3_service import S3 + + audit_info = set_mocked_aws_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", + new=Cloudtrail(audit_info), + ) as cloudtrail_client, mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.s3_client", + new=S3(audit_info), + ): + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( + cloudtrail_s3_dataevents_read_enabled, + ) + + cloudtrail_client.trails = None + check = cloudtrail_s3_dataevents_read_enabled() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled_test.py index 379ba1876b..1ac2bf6c8b 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled_test.py @@ -389,3 +389,33 @@ class Test_cloudtrail_s3_dataevents_write_enabled: assert result[0].resource_arn == trail_us["TrailARN"] assert result[0].resource_tags == [] assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.s3.s3_service import S3 + + audit_info = set_mocked_aws_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", + new=Cloudtrail(audit_info), + ) as cloudtrail_service, mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.s3_client", + new=S3(audit_info), + ): + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( + cloudtrail_s3_dataevents_write_enabled, + ) + + cloudtrail_service.trails = None + check = cloudtrail_s3_dataevents_write_enabled() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured_test.py index 6b0d63ecf0..9563e45da1 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured_test.py @@ -561,3 +561,51 @@ class Test_cloudwatch_changes_to_network_acls_alarm_configured: == f"arn:aws:logs:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:metric-filter/test-filter" ) assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.cloudwatch.cloudwatch_service import ( + CloudWatch, + Logs, + ) + + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_US_EAST_1, AWS_REGION_EU_WEST_1] + ) + + from prowler.providers.common.models import Audit_Metadata + + audit_info.audit_metadata = Audit_Metadata( + services_scanned=0, + # We need to set this check to call __describe_log_groups__ + expected_checks=["cloudwatch_log_group_no_secrets_in_logs"], + completed_checks=0, + audit_progress=0, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.logs_client", + new=Logs(audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_client", + new=CloudWatch(audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudtrail_client", + new=Cloudtrail(audit_info), + ) as cloudtrail_client: + # Test Check + from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured import ( + cloudwatch_changes_to_network_acls_alarm_configured, + ) + + cloudtrail_client.trails = None + check = cloudwatch_changes_to_network_acls_alarm_configured() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled_test.py index 9655786863..d769dde9f1 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled_test.py @@ -99,3 +99,39 @@ class Test_cloudwatch_cross_account_sharing_disabled: == "CloudWatch has allowed cross-account sharing." ) assert result[0].resource_id == "CloudWatch-CrossAccountSharingRole" + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1] + ) + + from prowler.providers.common.models import Audit_Metadata + + audit_info.audit_metadata = Audit_Metadata( + services_scanned=0, + # We need to set this check to call __describe_log_groups__ + expected_checks=["cloudwatch_log_group_no_secrets_in_logs"], + completed_checks=0, + audit_progress=0, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_cross_account_sharing_disabled.cloudwatch_cross_account_sharing_disabled.iam_client", + new=IAM(audit_info), + ) as iam_client: + # Test Check + from prowler.providers.aws.services.cloudwatch.cloudwatch_cross_account_sharing_disabled.cloudwatch_cross_account_sharing_disabled import ( + cloudwatch_cross_account_sharing_disabled, + ) + + iam_client.roles = None + check = cloudwatch_cross_account_sharing_disabled() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled_test.py index 106c309448..86dae0c9ef 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled_test.py @@ -138,3 +138,39 @@ class Test_cloudwatch_log_group_kms_encryption_enabled: == "Log Group test does have AWS KMS key test_kms_id associated." ) assert result[0].resource_id == "test" + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs + + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1] + ) + + from prowler.providers.common.models import Audit_Metadata + + audit_info.audit_metadata = Audit_Metadata( + services_scanned=0, + # We need to set this check to call __describe_log_groups__ + expected_checks=["cloudwatch_log_group_no_secrets_in_logs"], + completed_checks=0, + audit_progress=0, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_kms_encryption_enabled.cloudwatch_log_group_kms_encryption_enabled.logs_client", + new=Logs(audit_info), + ) as service_client: + # Test Check + from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_kms_encryption_enabled.cloudwatch_log_group_kms_encryption_enabled import ( + cloudwatch_log_group_kms_encryption_enabled, + ) + + service_client.log_groups = None + check = cloudwatch_log_group_kms_encryption_enabled() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs_test.py index eeb6720c01..29961a1311 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs_test.py @@ -154,3 +154,39 @@ class Test_cloudwatch_log_group_no_secrets_in_logs: "Potential secrets found in log group", result[0].status_extended ) assert result[0].resource_id == "test" + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs + + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1] + ) + + from prowler.providers.common.models import Audit_Metadata + + audit_info.audit_metadata = Audit_Metadata( + services_scanned=0, + # We need to set this check to call __describe_log_groups__ + expected_checks=["cloudwatch_log_group_no_secrets_in_logs"], + completed_checks=0, + audit_progress=0, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_no_secrets_in_logs.cloudwatch_log_group_no_secrets_in_logs.logs_client", + new=Logs(audit_info), + ) as logs_client: + # Test Check + from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_no_secrets_in_logs.cloudwatch_log_group_no_secrets_in_logs import ( + cloudwatch_log_group_no_secrets_in_logs, + ) + + logs_client.log_groups = None + check = cloudwatch_log_group_no_secrets_in_logs() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled_test.py index ba77b98489..c1f3d87f85 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled_test.py @@ -207,3 +207,47 @@ class Test_cloudwatch_log_group_retention_policy_specific_days_enabled: == f"arn:aws:logs:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:log-group:test" ) assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_aws + def test_access_denied(self): + # Generate Logs Client + logs_client = client("logs", region_name=AWS_REGION_US_EAST_1) + # Request Logs group + logs_client.create_log_group( + logGroupName="test", + ) + logs_client.put_retention_policy(logGroupName="test", retentionInDays=7) + from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs + + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1] + ) + audit_info._audit_config = {"log_group_retention_days": 365} + + from prowler.providers.common.models import Audit_Metadata + + audit_info.audit_metadata = Audit_Metadata( + services_scanned=0, + # We need to set this check to call __describe_log_groups__ + expected_checks=["cloudwatch_log_group_no_secrets_in_logs"], + completed_checks=0, + audit_progress=0, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled.logs_client", + new=Logs(audit_info), + ) as service_client: + # Test Check + from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled import ( + cloudwatch_log_group_retention_policy_specific_days_enabled, + ) + + service_client.log_groups = None + check = cloudwatch_log_group_retention_policy_specific_days_enabled() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled_test.py index 65c306e558..94e4d5fdfe 100644 --- a/tests/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled_test.py +++ b/tests/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled_test.py @@ -575,3 +575,53 @@ class Test_cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_c == f"arn:aws:logs:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:metric-filter/test-filter" ) assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_aws + def test_access_denied(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.cloudwatch.cloudwatch_service import ( + CloudWatch, + Logs, + ) + + audit_info = set_mocked_aws_audit_info( + [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1] + ) + + from prowler.providers.common.models import Audit_Metadata + + audit_info.audit_metadata = Audit_Metadata( + services_scanned=0, + # We need to set this check to call __describe_log_groups__ + expected_checks=["cloudwatch_log_group_no_secrets_in_logs"], + completed_checks=0, + audit_progress=0, + ) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.logs_client", + new=Logs(audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_client", + new=CloudWatch(audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudtrail_client", + new=Cloudtrail(audit_info), + ) as cloudtrail_client: + # Test Check + from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled import ( + cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled, + ) + + check = ( + cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled() + ) + cloudtrail_client.trails = None + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible_test.py b/tests/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible_test.py index 6722777949..2ea9111cde 100644 --- a/tests/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible_test.py +++ b/tests/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible_test.py @@ -1,4 +1,3 @@ -from re import search from unittest import mock from prowler.providers.aws.services.efs.efs_service import FileSystem @@ -32,6 +31,48 @@ filesystem_invalid_policy = { ], } +# https://docs.aws.amazon.com/efs/latest/ug/access-control-block-public-access.html#what-is-a-public-policy +filesystem_policy_with_source_arn_condition = { + "Version": "2012-10-17", + "Id": "efs-policy-wizard-15ad9567-2546-4bbb-8168-5541b6fc0e55", + "Statement": [ + { + "Sid": "efs-statement-14a7191c-9401-40e7-a388-6af6cfb7dd9c", + "Effect": "Allow", + "Principal": {"AWS": "*"}, + "Action": [ + "elasticfilesystem:ClientMount", + "elasticfilesystem:ClientWrite", + "elasticfilesystem:ClientRootAccess", + ], + "Condition": { + "ArnEquals": { + "aws:SourceArn": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + } + }, + } + ], +} + +# https://docs.aws.amazon.com/efs/latest/ug/access-control-block-public-access.html#what-is-a-public-policy +filesystem_policy_with_mount_target_condition = { + "Version": "2012-10-17", + "Id": "efs-policy-wizard-15ad9567-2546-4bbb-8168-5541b6fc0e55", + "Statement": [ + { + "Sid": "efs-statement-14a7191c-9401-40e7-a388-6af6cfb7dd9c", + "Effect": "Allow", + "Principal": {"AWS": "*"}, + "Action": [ + "elasticfilesystem:ClientMount", + "elasticfilesystem:ClientWrite", + "elasticfilesystem:ClientRootAccess", + ], + "Condition": {"Bool": {"elasticfilesystem:AccessedViaMountTarget": "true"}}, + } + ], +} + class Test_efs_not_publicly_accessible: def test_efs_valid_policy(self): @@ -59,12 +100,82 @@ class Test_efs_not_publicly_accessible: result = check.execute() assert len(result) == 1 assert result[0].status == "PASS" - assert search( - "has a policy which does not allow access to everyone", - result[0].status_extended, + assert ( + result[0].status_extended + == f"EFS {file_system_id} has a policy which does not allow access to any client within the VPC." ) assert result[0].resource_id == file_system_id assert result[0].resource_arn == efs_arn + assert result[0].region == AWS_REGION + assert result[0].resource_tags == [] + + def test_efs_valid_policy_with_mount_target_condition(self): + efs_client = mock.MagicMock + efs_arn = f"arn:aws:elasticfilesystem:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:file-system/{file_system_id}" + efs_client.filesystems = [ + FileSystem( + id=file_system_id, + arn=efs_arn, + region=AWS_REGION, + policy=filesystem_policy_with_mount_target_condition, + backup_policy=None, + encrypted=True, + ) + ] + with mock.patch( + "prowler.providers.aws.services.efs.efs_service.EFS", + efs_client, + ): + from prowler.providers.aws.services.efs.efs_not_publicly_accessible.efs_not_publicly_accessible import ( + efs_not_publicly_accessible, + ) + + check = efs_not_publicly_accessible() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"EFS {file_system_id} has a policy which does not allow access to any client within the VPC." + ) + assert result[0].resource_id == file_system_id + assert result[0].resource_arn == efs_arn + assert result[0].region == AWS_REGION + assert result[0].resource_tags == [] + + def test_efs_valid_policy_with_source_arn_condition(self): + efs_client = mock.MagicMock + efs_arn = f"arn:aws:elasticfilesystem:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:file-system/{file_system_id}" + efs_client.filesystems = [ + FileSystem( + id=file_system_id, + arn=efs_arn, + region=AWS_REGION, + policy=filesystem_policy_with_source_arn_condition, + backup_policy=None, + encrypted=True, + ) + ] + with mock.patch( + "prowler.providers.aws.services.efs.efs_service.EFS", + efs_client, + ): + from prowler.providers.aws.services.efs.efs_not_publicly_accessible.efs_not_publicly_accessible import ( + efs_not_publicly_accessible, + ) + + check = efs_not_publicly_accessible() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"EFS {file_system_id} has a policy which does not allow access to any client within the VPC." + ) + assert result[0].resource_id == file_system_id + assert result[0].resource_arn == efs_arn + assert result[0].region == AWS_REGION + assert result[0].resource_tags == [] def test_efs_invalid_policy(self): efs_client = mock.MagicMock @@ -92,12 +203,14 @@ class Test_efs_not_publicly_accessible: result = check.execute() assert len(result) == 1 assert result[0].status == "FAIL" - assert search( - "has a policy which allows access to everyone", - result[0].status_extended, + assert ( + result[0].status_extended + == f"EFS {file_system_id} has a policy which allows access to any client within the VPC." ) assert result[0].resource_id == file_system_id assert result[0].resource_arn == efs_arn + assert result[0].region == AWS_REGION + assert result[0].resource_tags == [] def test_efs_no_policy(self): efs_client = mock.MagicMock @@ -124,9 +237,11 @@ class Test_efs_not_publicly_accessible: result = check.execute() assert len(result) == 1 assert result[0].status == "FAIL" - assert search( - "doesn't have any policy which means it grants full access to any client", - result[0].status_extended, + assert ( + result[0].status_extended + == f"EFS {file_system_id} doesn't have any policy which means it grants full access to any client within the VPC." ) assert result[0].resource_id == file_system_id assert result[0].resource_arn == efs_arn + assert result[0].region == AWS_REGION + assert result[0].resource_tags == [] diff --git a/tests/providers/aws/services/efs/lib/lib_test.py b/tests/providers/aws/services/efs/lib/lib_test.py new file mode 100644 index 0000000000..dc486ba914 --- /dev/null +++ b/tests/providers/aws/services/efs/lib/lib_test.py @@ -0,0 +1,102 @@ +from prowler.providers.aws.services.efs.lib.lib import is_public_access_allowed + + +class Test_EFS_lib: + def test__is_public_access_allowed__(self): + statement = { + "Effect": "Allow", + "Principal": "*", + "Action": "elasticfilesystem:ClientMount", + "Resource": "*", + } + assert is_public_access_allowed(statement) + + def test__is_public_access_allowed__with_principal_dict(self): + statement = { + "Effect": "Allow", + "Principal": {"AWS": "*"}, + "Action": "elasticfilesystem:ClientMount", + "Resource": "*", + } + assert is_public_access_allowed(statement) + + def test__is_public_access_allowed__with_secure_conditions(self): + statement = { + "Effect": "Allow", + "Principal": "*", + "Action": "elasticfilesystem:ClientMount", + "Resource": "*", + "Condition": {"Bool": {"elasticfilesystem:AccessedViaMountTarget": "true"}}, + } + assert not is_public_access_allowed(statement) + + def test__is_public_access_allowed__with_secure_conditions_and_allowed_conditions( + self, + ): + statement = { + "Effect": "Allow", + "Principal": "*", + "Action": "elasticfilesystem:ClientMount", + "Resource": "*", + "Condition": { + "Bool": {"elasticfilesystem:AccessedViaMountTarget": "true"}, + "StringEquals": {"aws:SourceOwner": "123456789012"}, + }, + } + assert not is_public_access_allowed(statement) + + def test__is_public_access_allowed__with_secure_conditions_and_allowed_conditions_nested( + self, + ): + statement = { + "Effect": "Allow", + "Principal": "*", + "Action": "elasticfilesystem:ClientMount", + "Resource": "*", + "Condition": { + "Bool": {"elasticfilesystem:AccessedViaMountTarget": "true"}, + "StringEquals": {"aws:SourceOwner": "123456789012"}, + "StringEqualsIfExists": {"aws:SourceVpce": "vpce-1234567890abcdef0"}, + }, + } + assert not is_public_access_allowed(statement) + + def test__is_public_access_allowed__with_secure_conditions_and_allowed_conditions_nested_dict( + self, + ): + statement = { + "Effect": "Allow", + "Principal": "*", + "Action": "elasticfilesystem:ClientMount", + "Resource": "*", + "Condition": { + "Bool": {"elasticfilesystem:AccessedViaMountTarget": "true"}, + "StringEquals": {"aws:SourceOwner": "123456789012"}, + "StringEqualsIfExists": { + "aws:SourceVpce": { + "vpce-1234567890abcdef0": "vpce-1234567890abcdef0" + } + }, + }, + } + assert not is_public_access_allowed(statement) + + def test__is_public_access_allowed__with_secure_conditions_and_allowed_conditions_nested_dict_key( + self, + ): + statement = { + "Effect": "Allow", + "Principal": "*", + "Action": "elasticfilesystem:ClientMount", + "Resource": "*", + "Condition": { + "Bool": {"elasticfilesystem:AccessedViaMountTarget": "true"}, + "StringEquals": {"aws:SourceOwner": "123456789012"}, + "StringEqualsIfExists": { + "aws:SourceVpce": { + "vpce-1234567890abcdef0": "vpce-1234567890abcdef0" + } + }, + }, + } + assert not is_public_access_allowed(statement) diff --git a/tests/providers/aws/services/fms/fms_policy_compliant/fms_policy_compliant_test.py b/tests/providers/aws/services/fms/fms_policy_compliant/fms_policy_compliant_test.py index f56919b305..598723bab1 100644 --- a/tests/providers/aws/services/fms/fms_policy_compliant/fms_policy_compliant_test.py +++ b/tests/providers/aws/services/fms/fms_policy_compliant/fms_policy_compliant_test.py @@ -29,6 +29,24 @@ class Test_fms_policy_compliant: assert len(result) == 0 + def test_access_denied(self): + fms_client = mock.MagicMock + fms_client.region = AWS_REGION_US_EAST_1 + fms_client.fms_admin_account = None + with mock.patch( + "prowler.providers.aws.services.fms.fms_service.FMS", + new=fms_client, + ): + # Test Check + from prowler.providers.aws.services.fms.fms_policy_compliant.fms_policy_compliant import ( + fms_policy_compliant, + ) + + check = fms_policy_compliant() + result = check.execute() + + assert len(result) == 0 + def test_fms_admin_with_non_compliant_policies(self): fms_client = mock.MagicMock fms_client.audited_account = AWS_ACCOUNT_NUMBER diff --git a/tests/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_test.py b/tests/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_test.py index a4fa8d2d71..174ca710f6 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_test.py @@ -145,3 +145,25 @@ class Test_iam_password_policy_expires_passwords_within_90_days_or_less: "Password expiration is set lower than 90 days", result[0].status_extended, ) + + def test_access_denied(self): + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_password_policy_expires_passwords_within_90_days_or_less.iam_password_policy_expires_passwords_within_90_days_or_less.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_password_policy_expires_passwords_within_90_days_or_less.iam_password_policy_expires_passwords_within_90_days_or_less import ( + iam_password_policy_expires_passwords_within_90_days_or_less, + ) + + service_client.password_policy = None + check = iam_password_policy_expires_passwords_within_90_days_or_less() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_test.py b/tests/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_test.py index d5ec435496..4b5c910125 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_test.py @@ -85,3 +85,25 @@ class Test_iam_password_policy_lowercase: == f"arn:aws:iam:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:password-policy" ) assert result[0].region == AWS_REGION_US_EAST_1 + + def test_access_denied(self): + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_password_policy_lowercase.iam_password_policy_lowercase.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_password_policy_lowercase.iam_password_policy_lowercase import ( + iam_password_policy_lowercase, + ) + + service_client.password_policy = None + check = iam_password_policy_lowercase() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_test.py b/tests/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_test.py index 1815dd27d8..762fa8ac1f 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_test.py @@ -129,3 +129,25 @@ class Test_iam_password_policy_minimum_length_14: == f"arn:aws:iam:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:password-policy" ) assert result[0].region == AWS_REGION_US_EAST_1 + + def test_access_denied(self): + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14 import ( + iam_password_policy_minimum_length_14, + ) + + service_client.password_policy = None + check = iam_password_policy_minimum_length_14() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_test.py b/tests/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_test.py index 9b518e4b16..21e65d16ee 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_test.py @@ -92,3 +92,25 @@ class Test_iam_password_policy_number: == f"arn:aws:iam:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:password-policy" ) assert result[0].region == AWS_REGION_US_EAST_1 + + def test_access_denied(self): + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_password_policy_number.iam_password_policy_number.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_password_policy_number.iam_password_policy_number import ( + iam_password_policy_number, + ) + + service_client.password_policy = None + check = iam_password_policy_number() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_test.py b/tests/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_test.py index 27ad3aa82c..64999adaae 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_test.py @@ -89,3 +89,25 @@ class Test_iam_password_policy_reuse_24: == f"arn:aws:iam:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:password-policy" ) assert result[0].region == AWS_REGION_US_EAST_1 + + def test_access_denied(self): + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_password_policy_reuse_24.iam_password_policy_reuse_24.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_password_policy_reuse_24.iam_password_policy_reuse_24 import ( + iam_password_policy_reuse_24, + ) + + service_client.password_policy = None + check = iam_password_policy_reuse_24() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_test.py b/tests/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_test.py index 8285a5438f..c2ee5ef810 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_test.py @@ -92,3 +92,25 @@ class Test_iam_password_policy_symbol: == f"arn:aws:iam:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:password-policy" ) assert result[0].region == AWS_REGION_US_EAST_1 + + def test_access_denied(self): + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_password_policy_symbol.iam_password_policy_symbol.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_password_policy_symbol.iam_password_policy_symbol import ( + iam_password_policy_symbol, + ) + + service_client.password_policy = None + check = iam_password_policy_symbol() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_test.py b/tests/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_test.py index 97b7442d60..d569bf831c 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_test.py @@ -89,3 +89,25 @@ class Test_iam_password_policy_uppercase: == f"arn:aws:iam:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:password-policy" ) assert result[0].region == AWS_REGION_US_EAST_1 + + def test_access_denied(self): + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase import ( + iam_password_policy_uppercase, + ) + + service_client.password_policy = None + check = iam_password_policy_uppercase() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_role_administratoraccess_policy/iam_role_administratoraccess_policy_test.py b/tests/providers/aws/services/iam/iam_role_administratoraccess_policy/iam_role_administratoraccess_policy_test.py index 12936c0198..3d9f815e9b 100644 --- a/tests/providers/aws/services/iam/iam_role_administratoraccess_policy/iam_role_administratoraccess_policy_test.py +++ b/tests/providers/aws/services/iam/iam_role_administratoraccess_policy/iam_role_administratoraccess_policy_test.py @@ -267,3 +267,26 @@ class Test_iam_role_administratoraccess_policy: check = iam_role_administratoraccess_policy() result = check.execute() assert len(result) == 0 + + @mock_aws(config={"iam": {"load_aws_managed_policies": True}}) + def test_access_denied(self): + iam_client = mock.MagicMock + iam_client.roles = None + + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.iam.iam_role_administratoraccess_policy.iam_role_administratoraccess_policy.iam_client", + new=iam_client, + ): + # Test Check + from prowler.providers.aws.services.iam.iam_role_administratoraccess_policy.iam_role_administratoraccess_policy import ( + iam_role_administratoraccess_policy, + ) + + check = iam_role_administratoraccess_policy() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_securityaudit_role_created/iam_securityaudit_role_created_test.py b/tests/providers/aws/services/iam/iam_securityaudit_role_created/iam_securityaudit_role_created_test.py index db21e106c9..1ede46b397 100644 --- a/tests/providers/aws/services/iam/iam_securityaudit_role_created/iam_securityaudit_role_created_test.py +++ b/tests/providers/aws/services/iam/iam_securityaudit_role_created/iam_securityaudit_role_created_test.py @@ -87,3 +87,25 @@ class Test_iam_securityaudit_role_created: assert result[0].resource_id == "SecurityAudit" assert result[0].resource_arn == "arn:aws:iam::aws:policy/SecurityAudit" assert result[0].region == "us-east-1" + + @mock_aws(config={"iam": {"load_aws_managed_policies": True}}) + def test_access_denied(self): + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + 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=audit_info, + ), mock.patch( + "prowler.providers.aws.services.iam.iam_securityaudit_role_created.iam_securityaudit_role_created.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_securityaudit_role_created.iam_securityaudit_role_created import ( + iam_securityaudit_role_created, + ) + + service_client.entities_role_attached_to_securityaudit_policy = None + + check = iam_securityaudit_role_created() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/iam/iam_support_role_created/iam_support_role_created_test.py b/tests/providers/aws/services/iam/iam_support_role_created/iam_support_role_created_test.py index 1527f04fff..197aa8ba22 100644 --- a/tests/providers/aws/services/iam/iam_support_role_created/iam_support_role_created_test.py +++ b/tests/providers/aws/services/iam/iam_support_role_created/iam_support_role_created_test.py @@ -98,3 +98,25 @@ class Test_iam_support_role_created: result[0].resource_arn == "arn:aws:iam::aws:policy/aws-service-role/AWSSupportServiceRolePolicy" ) + + @mock_aws(config={"iam": {"load_aws_managed_policies": True}}) + def test_access_denied(self): + audit_info = set_mocked_aws_audit_info([AWS_REGION_US_EAST_1]) + 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=audit_info, + ), mock.patch( + "prowler.providers.aws.services.iam.iam_support_role_created.iam_support_role_created.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_support_role_created.iam_support_role_created import ( + iam_support_role_created, + ) + + service_client.entities_role_attached_to_support_policy = None + + check = iam_support_role_created() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/resourceexplorer2/resourceexplorer2_indexes_found/resourceexplorer2_indexes_found_test.py b/tests/providers/aws/services/resourceexplorer2/resourceexplorer2_indexes_found/resourceexplorer2_indexes_found_test.py index 0abd945b9d..a85020bb56 100644 --- a/tests/providers/aws/services/resourceexplorer2/resourceexplorer2_indexes_found/resourceexplorer2_indexes_found_test.py +++ b/tests/providers/aws/services/resourceexplorer2/resourceexplorer2_indexes_found/resourceexplorer2_indexes_found_test.py @@ -83,3 +83,31 @@ class Test_resourceexplorer2_indexes_found: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert result[0].resource_arn == INDEX_ARN assert result[0].region == AWS_REGION_US_EAST_1 + + def test_access_denied(self): + resourceexplorer2_client = mock.MagicMock + resourceexplorer2_client.indexes = None + resourceexplorer2_client.audited_account = AWS_ACCOUNT_NUMBER + resourceexplorer2_client.audited_account_arn = ( + f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + ) + resourceexplorer2_client.audited_partition = "aws" + resourceexplorer2_client.region = AWS_REGION_US_EAST_1 + resourceexplorer2_client.index_arn_template = f"arn:{resourceexplorer2_client.audited_partition}:resource-explorer:{resourceexplorer2_client.region}:{resourceexplorer2_client.audited_account}:index" + resourceexplorer2_client.__get_index_arn_template__ = mock.MagicMock( + return_value=resourceexplorer2_client.index_arn_template + ) + with mock.patch( + "prowler.providers.aws.services.resourceexplorer2.resourceexplorer2_service.ResourceExplorer2", + new=resourceexplorer2_client, + ): + # Test Check + from prowler.providers.aws.services.resourceexplorer2.resourceexplorer2_indexes_found.resourceexplorer2_indexes_found import ( + resourceexplorer2_indexes_found, + ) + + check = resourceexplorer2_indexes_found() + result = check.execute() + + # Assertions + assert len(result) == 0 diff --git a/tests/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans_test.py b/tests/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans_test.py index e21e159f9c..385e0a1224 100644 --- a/tests/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans_test.py +++ b/tests/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans_test.py @@ -167,3 +167,30 @@ class Test_ssmincidents_enabled_with_plans: assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert result[0].resource_arn == REPLICATION_SET_ARN assert result[0].region == AWS_REGION_US_EAST_1 + + def test_access_denied(self): + ssmincidents_client = mock.MagicMock + ssmincidents_client.audited_account = AWS_ACCOUNT_NUMBER + ssmincidents_client.audited_partition = "aws" + ssmincidents_client.audited_account_arn = ( + f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + ) + ssmincidents_client.region = AWS_REGION_US_EAST_1 + ssmincidents_client.replication_set_arn_template = f"arn:{ssmincidents_client.audited_partition}:ssm-incidents:{ssmincidents_client.region}:{ssmincidents_client.audited_account}:replication-set" + ssmincidents_client.__get_replication_set_arn_template__ = mock.MagicMock( + return_value=ssmincidents_client.replication_set_arn_template + ) + ssmincidents_client.replication_set = None + with mock.patch( + "prowler.providers.aws.services.ssmincidents.ssmincidents_service.SSMIncidents", + new=ssmincidents_client, + ): + # Test Check + from prowler.providers.aws.services.ssmincidents.ssmincidents_enabled_with_plans.ssmincidents_enabled_with_plans import ( + ssmincidents_enabled_with_plans, + ) + + check = ssmincidents_enabled_with_plans() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/trustedadvisor/trustedadvisor_errors_and_warnings/trustedadvisor_errors_and_warnings_test.py b/tests/providers/aws/services/trustedadvisor/trustedadvisor_errors_and_warnings/trustedadvisor_errors_and_warnings_test.py index f4b8bdd690..0e6a8a71a6 100644 --- a/tests/providers/aws/services/trustedadvisor/trustedadvisor_errors_and_warnings/trustedadvisor_errors_and_warnings_test.py +++ b/tests/providers/aws/services/trustedadvisor/trustedadvisor_errors_and_warnings/trustedadvisor_errors_and_warnings_test.py @@ -144,3 +144,30 @@ class Test_trustedadvisor_errors_and_warnings: check = trustedadvisor_errors_and_warnings() result = check.execute() assert len(result) == 0 + + def test_access_denied(self): + trustedadvisor_client = mock.MagicMock + trustedadvisor_client.checks = [] + trustedadvisor_client.premium_support = None + trustedadvisor_client.audited_account = AWS_ACCOUNT_NUMBER + trustedadvisor_client.audited_account_arn = AWS_ACCOUNT_ARN + trustedadvisor_client.checks.append( + Check( + id=CHECK_NAME, + name=CHECK_NAME, + arn=CHECK_ARN, + region=AWS_REGION_US_EAST_1, + status="not_available", + ) + ) + with mock.patch( + "prowler.providers.aws.services.trustedadvisor.trustedadvisor_service.TrustedAdvisor", + trustedadvisor_client, + ): + from prowler.providers.aws.services.trustedadvisor.trustedadvisor_errors_and_warnings.trustedadvisor_errors_and_warnings import ( + trustedadvisor_errors_and_warnings, + ) + + check = trustedadvisor_errors_and_warnings() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/aws/services/trustedadvisor/trustedadvisor_premium_support_plan_subscribed/trustedadvisor_premium_support_plan_subscribed_test.py b/tests/providers/aws/services/trustedadvisor/trustedadvisor_premium_support_plan_subscribed/trustedadvisor_premium_support_plan_subscribed_test.py index b7f2187f89..fb8538903a 100644 --- a/tests/providers/aws/services/trustedadvisor/trustedadvisor_premium_support_plan_subscribed/trustedadvisor_premium_support_plan_subscribed_test.py +++ b/tests/providers/aws/services/trustedadvisor/trustedadvisor_premium_support_plan_subscribed/trustedadvisor_premium_support_plan_subscribed_test.py @@ -86,3 +86,30 @@ class Test_trustedadvisor_premium_support_plan_subscribed: result[0].resource_arn == f"arn:aws:trusted-advisor:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:account" ) + + def test_access_denied(self): + trustedadvisor_client = mock.MagicMock + trustedadvisor_client.checks = [] + trustedadvisor_client.premium_support = None + trustedadvisor_client.audited_account = AWS_ACCOUNT_NUMBER + trustedadvisor_client.audited_account_arn = AWS_ACCOUNT_ARN + trustedadvisor_client.audited_partition = "aws" + trustedadvisor_client.region = AWS_REGION_US_EAST_1 + + # Set verify_premium_support_plans config + trustedadvisor_client.audit_config = {"verify_premium_support_plans": True} + trustedadvisor_client.account_arn_template = f"arn:{trustedadvisor_client.audited_partition}:trusted-advisor:{trustedadvisor_client.region}:{trustedadvisor_client.audited_account}:account" + trustedadvisor_client.__get_account_arn_template__ = mock.MagicMock( + return_value=trustedadvisor_client.account_arn_template + ) + with mock.patch( + "prowler.providers.aws.services.trustedadvisor.trustedadvisor_service.TrustedAdvisor", + trustedadvisor_client, + ): + from prowler.providers.aws.services.trustedadvisor.trustedadvisor_premium_support_plan_subscribed.trustedadvisor_premium_support_plan_subscribed import ( + trustedadvisor_premium_support_plan_subscribed, + ) + + check = trustedadvisor_premium_support_plan_subscribed() + result = check.execute() + assert len(result) == 0 diff --git a/tests/providers/gcp/gcp_fixtures.py b/tests/providers/gcp/gcp_fixtures.py new file mode 100644 index 0000000000..fab6d41949 --- /dev/null +++ b/tests/providers/gcp/gcp_fixtures.py @@ -0,0 +1,969 @@ +from uuid import uuid4 + +from google.oauth2.credentials import Credentials +from mock import MagicMock + +from prowler.providers.gcp.lib.audit_info.models import GCP_Audit_Info + +GCP_PROJECT_ID = "123456789012" + + +# Mocked Azure Audit Info +def set_mocked_gcp_audit_info( + credentials: Credentials = None, + project_ids: list = [], + audit_config: dict = None, +): + audit_info = GCP_Audit_Info( + credentials=credentials, + project_ids=project_ids, + audit_metadata=None, + audit_resources=None, + audit_config=audit_config, + ) + return audit_info + + +def mock_api_client(GCPService, service, api_version, _): + client = MagicMock() + + mock_api_projects_calls(client) + mock_api_dataset_calls(client) + mock_api_tables_calls(client) + mock_api_organizations_calls(client) + mock_api_instances_calls(client, service) + mock_api_buckets_calls(client) + mock_api_regions_calls(client) + mock_api_zones_calls(client) + mock_api_networks_calls(client) + mock_api_subnetworks_calls(client) + mock_api_addresses_calls(client) + mock_api_firewall_calls(client) + mock_api_urlMaps_calls(client) + mock_api_managedZones_calls(client) + mock_api_policies_calls(client) + mock_api_sink_calls(client) + mock_api_services_calls(client) + + return client + + +def mock_is_api_active(_, audited_project_ids): + return audited_project_ids + + +def mock_api_projects_calls(client: MagicMock): + client.projects().locations().keys().list().execute.return_value = { + "keys": [ + { + "displayName": "key1", + "uid": str(uuid4()), + "createTime": "2021-01-01T00:00:00Z", + "restrictions": {}, + }, + { + "displayName": "key2", + "uid": str(uuid4()), + "createTime": "2021-01-01T00:00:00Z", + "restrictions": {}, + }, + ] + } + # Next page is None to not enter in the while infinite loop + client.projects().locations().keys().list_next.return_value = None + # Mocking policy + client.projects().getIamPolicy().execute.return_value = { + "auditConfigs": [MagicMock()], + "bindings": [ + { + "role": "roles/resourcemanager.organizationAdmin", + "members": [ + "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com", + ], + }, + { + "role": "roles/resourcemanager.organizationViewer", + "members": ["user:eve@example.com"], + "condition": { + "title": "expirable access", + "description": "Does not grant access after Sep 2020", + "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", + }, + }, + ], + "etag": "BwWWja0YfJA=", + "version": 3, + } + # Used by compute client + client.projects().get().execute.return_value = { + "commonInstanceMetadata": { + "items": [ + { + "key": "enable-oslogin", + "value": "TRUE", + }, + { + "key": "enable-oslogin", + "value": "FALSE", + }, + { + "key": "testing-key", + "value": "TRUE", + }, + ] + } + } + client.projects().list_next.return_value = None + # Used by dataproc client + + cluster1_id = str(uuid4()) + cluster2_id = str(uuid4()) + + if client.projects().regions().clusters.__class__.__name__ == "dict": + client.projects().regions().clusters = MagicMock() + + client.projects().regions().clusters().list().execute.return_value = { + "clusters": [ + { + "clusterName": "cluster1", + "clusterUuid": cluster1_id, + "config": { + "encryptionConfig": { + "gcePdKmsKeyName": "projects/123/locations/456/keyRings/789/cryptoKeys/123" + } + }, + }, + { + "clusterName": "cluster2", + "clusterUuid": cluster2_id, + "config": {"encryptionConfig": {}}, + }, + ] + } + client.projects().regions().clusters().list_next.return_value = None + # Used by gke client + client.projects().locations().list().execute.return_value = { + "locations": [{"name": "eu-west1"}] + } + client.projects().locations().list_next.return_value = None + + if client.projects().locations().clusters.__class__.__name__ == "dict": + client.projects().locations().clusters = MagicMock() + + client.projects().locations().clusters().list().execute.return_value = { + "clusters": [ + { + "name": "cluster1", + "id": "cluster1_id", + "location": "eu-west1", + "nodeConfig": {"serviceAccount": "service_account1"}, + "nodePools": [ + { + "name": "node_pool1", + "locations": ["cluster1_location1"], + "config": {"serviceAccount": "service_account1"}, + } + ], + }, + { + "name": "cluster2", + "id": "cluster2_id", + "location": "eu-west1", + "nodeConfig": {"serviceAccount": "service_account2"}, + "nodePools": [ + { + "name": "node_pool2", + "locations": ["cluster2_location1"], + "config": {"serviceAccount": "service_account2"}, + }, + { + "name": "node_pool3", + "locations": ["cluster2_location2"], + "config": {"serviceAccount": "service_account3"}, + }, + ], + }, + ] + } + # Used by KMS + client.projects().locations().keyRings().list().execute.return_value = { + "keyRings": [ + { + "name": "projects/123/locations/eu-west1/keyRings/keyring1", + "createTime": "2021-01-01T00:00:00Z", + }, + { + "name": "projects/123/locations/eu-west1/keyRings/keyring2", + "createTime": "2021-01-01T00:00:00Z", + }, + ] + } + client.projects().locations().keyRings().list_next.return_value = None + + def mock_list_crypto_keys(parent): + return_value = MagicMock() + if parent == "projects/123/locations/eu-west1/keyRings/keyring1": + return_value.execute.return_value = { + "cryptoKeys": [ + { + "name": "projects/123/locations/eu-west1/keyRings/keyring1/cryptoKeys/key1", + "createTime": "2021-01-01T00:00:00Z", + "rotationPeriod": "7776000s", + }, + { + "name": "projects/123/locations/eu-west1/keyRings/keyring2/cryptoKeys/key2", + "createTime": "2021-01-01T00:00:00Z", + }, + ] + } + elif parent == "projects/123/locations/eu-west1/keyRings/keyring2": + return_value.execute.return_value = {"cryptoKeys": []} + return return_value + + client.projects().locations().keyRings().cryptoKeys().list = mock_list_crypto_keys + + client.projects().locations().keyRings().cryptoKeys().list_next.return_value = None + + def mock_get_crypto_keys_iam_policy(resource): + return_value = MagicMock() + if ( + resource + == "projects/123/locations/eu-west1/keyRings/keyring1/cryptoKeys/key1" + ): + return_value.execute.return_value = { + "auditConfigs": [MagicMock()], + "bindings": [ + { + "role": "roles/resourcemanager.organizationAdmin", + "members": [ + "user:mike@example.com", + "group:admins@example.com", + ], + }, + { + "role": "roles/resourcemanager.organizationViewer", + "members": [ + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com", + ], + "condition": { + "title": "expirable access", + "description": "Does not grant access after Sep 2020", + "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", + }, + }, + ], + } + elif ( + resource + == "projects/123/locations/eu-west1/keyRings/keyring2/cryptoKeys/key2" + ): + return_value.execute.return_value = { + "auditConfigs": [MagicMock()], + "bindings": [ + { + "role": "roles/resourcemanager.organizationAdmin", + "members": ["user:mike@example.com"], + }, + { + "role": "roles/resourcemanager.organizationViewer", + "members": ["group:admins@example.com"], + "condition": { + "title": "expirable access", + "description": "Does not grant access after Sep 2020", + "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", + }, + }, + ], + } + return return_value + + client.projects().locations().keyRings().cryptoKeys().getIamPolicy = ( + mock_get_crypto_keys_iam_policy + ) + # Used by logging + client.projects().metrics().list().execute.return_value = { + "metrics": [ + { + "name": "metric1", + "filter": "resource.type=gae_app AND severity>=ERROR", + "metricDescriptor": { + "name": "projects/123/metricDescriptors/custom.googleapis.com/invoice/paid/amount", + "type": "custom.googleapis.com/invoice/paid/amount", + }, + }, + { + "name": "metric2", + "metricDescriptor": { + "name": "projects/123/metricDescriptors/custom.googleapis.com/invoice/paid/amount", + "type": "external.googleapis.com/prometheus/up", + }, + "filter": "resource.type=gae_app AND severity>=ERROR", + }, + ] + } + client.projects().metrics().list_next.return_value = None + # Used by monitoring + client.projects().alertPolicies().list().execute.return_value = { + "alertPolicies": [ + { + "name": "alert_policy1", + "displayName": "Alert Policy 1", + "conditions": [ + { + "conditionThreshold": { + "filter": 'metric.type="compute.googleapis.com/instance/disk/write_bytes_count"', + "comparison": "COMPARISON_GT", + "thresholdValue": 1000, + } + } + ], + "enabled": True, + }, + { + "name": "alert_policy2", + "displayName": "Alert Policy 2", + "conditions": [ + { + "conditionThreshold": { + "filter": 'metric.type="compute.googleapis.com/instance/disk/write_bytes_count"', + "comparison": "COMPARISON_GT", + "thresholdValue": 2000, + } + } + ], + "enabled": False, + }, + ] + } + client.projects().alertPolicies().list_next.return_value = None + # Used by IAM + client.projects().serviceAccounts().list().execute.return_value = { + "accounts": [ + { + "name": f"projects/{GCP_PROJECT_ID}/serviceAccounts/service-account1@{GCP_PROJECT_ID}.iam.gserviceaccount.com", + "email": "service-account1@gmail.com", + "displayName": "Service Account 1", + }, + { + "name": f"projects/{GCP_PROJECT_ID}/serviceAccounts/service-account2@{GCP_PROJECT_ID}.iam.gserviceaccount.com", + "email": "service-account2@gmail.com", + "displayName": "Service Account 2", + }, + ] + } + client.projects().serviceAccounts().list_next.return_value = None + + def mock_list_service_accounts_keys(name): + return_value = MagicMock() + if ( + name + == f"projects/{GCP_PROJECT_ID}/serviceAccounts/service-account1@gmail.com" + ): + return_value.execute.return_value = { + "keys": [ + { + "name": "projects/{GCP_PROJECT_ID}/serviceAccounts/service-account1@{GCP_PROJECT_ID}.iam.gserviceaccount.com/keys/key1", + "validAfterTime": "2021-01-01T00:00:00Z", + "validBeforeTime": "2022-01-01T00:00:00Z", + "keyOrigin": "GOOGLE_PROVIDED", + "keyType": "SYSTEM_MANAGED", + }, + { + "name": "projects/{GCP_PROJECT_ID}/serviceAccounts/service-account1@{GCP_PROJECT_ID}.iam.gserviceaccount.com/keys/key2", + "validAfterTime": "2021-01-01T00:00:00Z", + "validBeforeTime": "2022-01-01T00:00:00Z", + "keyOrigin": "ORIGIN_UNSPECIFIED", + "keyType": "USER_MANAGED", + }, + ] + } + elif ( + name + == f"projects/{GCP_PROJECT_ID}/serviceAccounts/service-account2@gmail.com" + ): + return_value.execute.return_value = { + "keys": [ + { + "name": "projects/{GCP_PROJECT_ID}/serviceAccounts/service-account2@{GCP_PROJECT_ID}.iam.gserviceaccount.com/keys/key3", + "validAfterTime": "2021-01-01T00:00:00Z", + "validBeforeTime": "2022-01-01T00:00:00Z", + "keyOrigin": "USER_PROVIDED", + "keyType": "KEY_TYPE_UNSPECIFIED", + }, + ] + } + return return_value + + client.projects().serviceAccounts().keys().list = mock_list_service_accounts_keys + + client.projects().getAccessApprovalSettings().execute.return_value = { + "name": "projects/123/accessApprovalSettings", + "enrolledAncestor": True, + } + + +def mock_api_dataset_calls(client: MagicMock): + # Mocking datasets + dataset1_id = str(uuid4()) + dataset2_id = str(uuid4()) + + client.datasets().list().execute.return_value = { + "datasets": [ + { + "datasetReference": { + "datasetId": "unique_dataset1_name", + "projectId": GCP_PROJECT_ID, + }, + "id": dataset1_id, + "location": "US", + }, + { + "datasetReference": { + "datasetId": "unique_dataset2_name", + "projectId": GCP_PROJECT_ID, + }, + "id": dataset2_id, + "location": "EU", + }, + ] + } + + # Mock two dataset cases get funcion + def mock_get_dataset(datasetId, projectId=GCP_PROJECT_ID): + return_value = MagicMock() + + if projectId == GCP_PROJECT_ID: + if datasetId == "unique_dataset1_name": + return_value.execute.return_value = { + "access": "allAuthenticatedUsers", + "defaultEncryptionConfiguration": True, + } + elif datasetId == "unique_dataset2_name": + return_value.execute.return_value = { + "access": "nobody", + "defaultEncryptionConfiguration": False, + } + + return return_value + + client.datasets().get = mock_get_dataset + client.datasets().list_next.return_value = None + + +def mock_api_tables_calls(client: MagicMock): + # Mocking related tables to the datasets + table1_id = str(uuid4()) + table2_id = str(uuid4()) + + # Mocking two datasets cases + def mock_list_tables(datasetId, projectId=GCP_PROJECT_ID): + return_value = MagicMock() + + if projectId == GCP_PROJECT_ID: + if ( + datasetId + == client.datasets() + .list() + .execute()["datasets"][0]["datasetReference"]["datasetId"] + ): + return_value.execute.return_value = { + "tables": [ + { + "tableReference": {"tableId": "unique_table1_name"}, + "id": table1_id, + }, + { + "tableReference": {"tableId": "unique_table2_name"}, + "id": table2_id, + }, + ] + } + elif ( + datasetId + == client.datasets() + .list() + .execute()["datasets"][1]["datasetReference"]["datasetId"] + ): + return_value.execute.return_value = {"tables": []} + + return return_value + + client.tables().list = mock_list_tables + + # Mocking the encryption configuration of the tables + def mock_get_table(projectId, datasetId, tableId): + return_value = MagicMock() + + if ( + projectId == GCP_PROJECT_ID + and datasetId + == client.datasets() + .list() + .execute()["datasets"][0]["datasetReference"]["datasetId"] + ): + if tableId == "unique_table1_name": + return_value.execute.return_value = {"encryptionConfiguration": True} + elif tableId == "unique_table2_name": + return_value.execute.return_value = {"encryptionConfiguration": False} + elif ( + projectId == GCP_PROJECT_ID + and datasetId + == client.datasets() + .list() + .execute()["datasets"][1]["datasetReference"]["datasetId"] + ): + return_value.execute.return_value = None + + return return_value + + client.tables().get = mock_get_table + client.tables().list_next.return_value = None + + +def mock_api_organizations_calls(client: MagicMock): + client.organizations().search().execute.return_value = { + "organizations": [ + { + "name": "organizations/123456789", + "displayName": "Organization 1", + "state": "ACTIVE", + "createTime": "2021-01-01T00:00:00Z", + "updateTime": "2021-01-01T00:00:00Z", + "deleteTime": "2021-01-01T00:00:00Z", + "etag": "", + }, + { + "name": "organizations/987654321", + "displayName": "Organization 2", + "state": "DELETE_REQUESTED", + "createTime": "2021-01-01T00:00:00Z", + "updateTime": "2021-01-01T00:00:00Z", + "deleteTime": "2021-01-01T00:00:00Z", + "etag": "", + }, + ] + } + + def mock_contact_organization_list(parent): + return_value = MagicMock() + if parent == "organizations/123456789": + return_value.execute.return_value = { + "contacts": [ + { + "name": "contacts/1", + "email": "contact1@example.es", + }, + {"name": "contacts/2", "email": "contact2@example.es"}, + ] + } + elif parent == "organizations/987654321": + return_value.execute.return_value = {"contacts": []} + return return_value + + client.organizations().contacts().list = mock_contact_organization_list + + +def mock_api_instances_calls(client: MagicMock, service: str): + instance1_id = str(uuid4()) + instance2_id = str(uuid4()) + if service == "sqladmin": + client.instances().list().execute.return_value = { + "items": [ + { + "name": "instance1", + "databaseVersion": "MYSQL_5_7", + "region": "us-central1", + "ipAddresses": [{"type": "PRIMARY", "ipAddress": "66.66.66.66"}], + "settings": { + "ipConfiguration": { + "requireSsl": True, + "authorizedNetworks": [{"value": "test"}], + }, + "backupConfiguration": {"enabled": True}, + "databaseFlags": [], + }, + }, + { + "name": "instance2", + "databaseVersion": "POSTGRES_9_6", + "region": "us-central1", + "ipAddresses": [{"type": "PRIMARY", "ipAddress": "22.22.22.22"}], + "settings": { + "ipConfiguration": { + "requireSsl": False, + "authorizedNetworks": [{"value": "test"}], + }, + "backupConfiguration": {"enabled": False}, + "databaseFlags": [], + }, + }, + ] + } + elif service == "compute": + client.instances().list().execute.return_value = { + "items": [ + { + "name": "instance1", + "id": instance1_id, + "metadata": {}, + "networkInterfaces": [ + { + "accessConfigs": [ + { + "natIP": "nat_ip", + "type": "ONE_TO_ONE_NAT", + } + ], + } + ], + "shieldedInstanceConfig": { + "enableVtpm": True, + "enableIntegrityMonitoring": True, + }, + "confidentialInstanceConfig": {"enableConfidentialCompute": True}, + "serviceAccounts": [ + { + "email": "test@test.es", + "scopes": ["scope1", "scope2"], + } + ], + "canIpForward": True, + "disks": [ + { + "deviceName": "disk1", + "diskEncryptionKey": {"sha256": "sha256_key"}, + "diskSizeGb": 10, + "diskType": "disk_type", + } + ], + }, + { + "name": "instance2", + "id": instance2_id, + "metadata": {}, + "networkInterfaces": [], + "shieldedInstanceConfig": { + "enableVtpm": False, + "enableIntegrityMonitoring": False, + }, + "confidentialInstanceConfig": {"enableConfidentialCompute": False}, + "serviceAccounts": [ + { + "email": "test2@test.es", + "scopes": ["scope3"], + } + ], + "canIpForward": False, + "disks": [ + { + "deviceName": "disk2", + "diskEncryptionKey": {"kmsKeyName": "kms_key"}, + "diskSizeGb": 20, + "diskType": "disk_type", + } + ], + }, + ] + } + + client.instances().list_next.return_value = None + + +def mock_api_buckets_calls(client: MagicMock): + bucket1_id = str(uuid4()) + bucket2_id = str(uuid4()) + + client.buckets().list().execute.return_value = { + "items": [ + { + "name": "bucket1", + "id": bucket1_id, + "location": "US", + "iamConfiguration": {"uniformBucketLevelAccess": {"enabled": True}}, + "retentionPolicy": {"retentionPeriod": 10}, + }, + { + "name": "bucket2", + "id": bucket2_id, + "location": "EU", + "iamConfiguration": {"uniformBucketLevelAccess": {"enabled": False}}, + "retentionPolicy": None, + }, + ] + } + + def mock_get_buckets_iam_policy(bucket): + return_value = MagicMock() + if bucket == bucket1_id: + return_value.execute.return_value = {"bindings": "allAuthenticatedUsers"} + elif bucket == bucket2_id: + return_value.execute.return_value = {"bindings": "nobody"} + return return_value + + client.buckets().getIamPolicy = mock_get_buckets_iam_policy + + client.buckets().list_next.return_value = None + + +def mock_api_regions_calls(client: MagicMock): + region1_id = str(uuid4()) + + client.regions().list().execute.return_value = { + "items": [ + { + "name": "europe-west1-b", + "id": region1_id, + } + ] + } + client.regions().list_next.return_value = None + + +def mock_api_zones_calls(client: MagicMock): + zone1_id = str(uuid4()) + + client.zones().list().execute.return_value = { + "items": [ + { + "name": "zone1", + "id": zone1_id, + } + ] + } + client.zones().list_next.return_value = None + + +def mock_api_networks_calls(client: MagicMock): + network1_id = str(uuid4()) + network2_id = str(uuid4()) + network3_id = str(uuid4()) + + client.networks().list().execute.return_value = { + "items": [ + { + "name": "network1", + "id": network1_id, + "autoCreateSubnetworks": True, + }, + { + "name": "network2", + "id": network2_id, + "autoCreateSubnetworks": False, + }, + {"name": "network3", "id": network3_id}, + ] + } + client.networks().list_next.return_value = None + + +def mock_api_subnetworks_calls(client: MagicMock): + subnetwork1_id = str(uuid4()) + subnetwork2_id = str(uuid4()) + subnetwork3_id = str(uuid4()) + + client.subnetworks().list().execute.return_value = { + "items": [ + { + "name": "subnetwork1", + "id": subnetwork1_id, + "enableFlowLogs": True, + "network": "region1/network1", + }, + { + "name": "subnetwork2", + "id": subnetwork2_id, + "enableFlowLogs": False, + "network": "region1/network1", + }, + { + "name": "subnetwork3", + "id": subnetwork3_id, + "enableFlowLogs": False, + "network": "region2/network3", + }, + ] + } + client.subnetworks().list_next.return_value = None + + +def mock_api_addresses_calls(client: MagicMock): + address1_id = str(uuid4()) + address2_id = str(uuid4()) + address3_id = str(uuid4()) + + client.addresses().list().execute.return_value = { + "items": [ + { + "name": "address1", + "id": address1_id, + "address": "10.0.0.1", + "addressType": "INTERNAL", + }, + { + "name": "address2", + "id": address2_id, + "address": "10.0.0.2", + "addressType": "INTERNAL", + }, + { + "name": "address3", + "id": address3_id, + "address": "20.34.105.200", + "addressType": "EXTERNAL", + }, + ] + } + client.addresses().list_next.return_value = None + + +def mock_api_firewall_calls(client: MagicMock): + firewall1_id = str(uuid4()) + firewall2_id = str(uuid4()) + firewall3_id = str(uuid4()) + + client.firewalls().list().execute.return_value = { + "items": [ + { + "name": "firewall1", + "id": firewall1_id, + "allowed": [{"IPProtocol": "UDP"}], + "sourceRanges": ["30.0.0.0/16"], + "direction": "INGRESS", + }, + { + "name": "firewall2", + "id": firewall2_id, + "allowed": [{"IPProtocol": "TCP"}], + "sourceRanges": ["0.0.0.0/0"], + "direction": "EGRESS", + }, + { + "name": "firewall3", + "id": firewall3_id, + "allowed": [{"IPProtocol": "TCP"}], + "sourceRanges": ["10.0.15.0/24"], + "direction": "INGRESS", + }, + ] + } + client.firewalls().list_next.return_value = None + + +def mock_api_urlMaps_calls(client: MagicMock): + url_map1_id = str(uuid4()) + url_map2_id = str(uuid4()) + + client.urlMaps().list().execute.return_value = { + "items": [ + { + "name": "url_map1", + "id": url_map1_id, + "defaultService": "service1", + }, + { + "name": "url_map2", + "id": url_map2_id, + "defaultService": "service2", + }, + ] + } + client.urlMaps().list_next.return_value = None + + client.backendServices().get().execute.side_effect = [ + { + "logConfig": {"enable": True}, + }, + { + "logConfig": {"enable": False}, + }, + ] + + +def mock_api_managedZones_calls(client: MagicMock): + managed_zone1_id = str(uuid4()) + managed_zone2_id = str(uuid4()) + + client.managedZones().list().execute.return_value = { + "managedZones": [ + { + "name": "managed_zone1", + "id": managed_zone1_id, + "dnssecConfig": {"state": "on", "defaultKeySpecs": []}, + }, + { + "name": "managed_zone2", + "id": managed_zone2_id, + "dnssecConfig": {"state": "off", "defaultKeySpecs": []}, + }, + ] + } + client.managedZones().list_next.return_value = None + + +def mock_api_policies_calls(client: MagicMock): + policy1_id = str(uuid4()) + policy2_id = str(uuid4()) + + client.policies().list().execute.return_value = { + "policies": [ + { + "name": "policy1", + "id": policy1_id, + "enableLogging": True, + "networks": [ + { + "networkUrl": "https://www.googleapis.com/compute/v1/projects/project1/global/networks/network1" + } + ], + }, + { + "name": "policy2", + "id": policy2_id, + "enableLogging": False, + "networks": [], + }, + ] + } + client.policies().list_next.return_value = None + + +def mock_api_sink_calls(client: MagicMock): + client.sinks().list().execute.return_value = { + "sinks": [ + { + "name": "sink1", + "destination": "storage.googleapis.com/example-bucket", + "filter": "all", + "project_id": GCP_PROJECT_ID, + }, + { + "name": "sink2", + "destination": f"bigquery.googleapis.com/projects/{GCP_PROJECT_ID}/datasets/example_dataset", + "filter": "all", + "project_id": GCP_PROJECT_ID, + }, + ] + } + client.sinks().list_next.return_value = None + + +def mock_api_services_calls(client: MagicMock): + client.services().list().execute.return_value = { + "services": [ + { + "name": f"projects/{GCP_PROJECT_ID}/services/artifacts.googleapis.com", + "config": {"title": "artifacts.googleapis.com"}, + "state": "ENABLED", + }, + { + "name": f"projects/{GCP_PROJECT_ID}/services/bigquery.googleapis.com", + "config": {"title": "bigquery.googleapis.com"}, + "state": "ENABLED", + }, + ] + } + client.services().list_next.return_value = None diff --git a/tests/providers/gcp/services/apikeys/apikeys_service_test.py b/tests/providers/gcp/services/apikeys/apikeys_service_test.py new file mode 100644 index 0000000000..a0a738b015 --- /dev/null +++ b/tests/providers/gcp/services/apikeys/apikeys_service_test.py @@ -0,0 +1,39 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.apikeys.apikeys_service import APIKeys +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestAPIKeysService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + api_keys_client = APIKeys( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert api_keys_client.service == "apikeys" + assert api_keys_client.project_ids == [GCP_PROJECT_ID] + + assert len(api_keys_client.keys) == 2 + + assert api_keys_client.keys[0].name == "key1" + assert api_keys_client.keys[0].id.__class__.__name__ == "str" + assert api_keys_client.keys[0].creation_time == "2021-01-01T00:00:00Z" + assert api_keys_client.keys[0].restrictions.__class__.__name__ == "dict" + assert api_keys_client.keys[0].project_id == GCP_PROJECT_ID + + assert api_keys_client.keys[1].name == "key2" + assert api_keys_client.keys[1].id.__class__.__name__ == "str" + assert api_keys_client.keys[1].creation_time == "2021-01-01T00:00:00Z" + assert api_keys_client.keys[1].restrictions.__class__.__name__ == "dict" + assert api_keys_client.keys[1].project_id == GCP_PROJECT_ID diff --git a/tests/providers/gcp/services/bigquery/bigquery_service_test.py b/tests/providers/gcp/services/bigquery/bigquery_service_test.py new file mode 100644 index 0000000000..610dc95c7a --- /dev/null +++ b/tests/providers/gcp/services/bigquery/bigquery_service_test.py @@ -0,0 +1,55 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.bigquery.bigquery_service import BigQuery +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestBigQueryService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + bigquery_client = BigQuery( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert bigquery_client.service == "bigquery" + assert bigquery_client.project_ids == [GCP_PROJECT_ID] + + assert len(bigquery_client.datasets) == 2 + + assert bigquery_client.datasets[0].name == "unique_dataset1_name" + assert bigquery_client.datasets[0].id.__class__.__name__ == "str" + assert bigquery_client.datasets[0].region == "US" + assert bigquery_client.datasets[0].cmk_encryption + assert bigquery_client.datasets[0].public + assert bigquery_client.datasets[0].project_id == GCP_PROJECT_ID + + assert bigquery_client.datasets[1].name == "unique_dataset2_name" + assert bigquery_client.datasets[1].id.__class__.__name__ == "str" + assert bigquery_client.datasets[1].region == "EU" + assert not bigquery_client.datasets[1].cmk_encryption + assert not bigquery_client.datasets[1].public + assert bigquery_client.datasets[1].project_id == GCP_PROJECT_ID + + assert len(bigquery_client.tables) == 2 + + assert bigquery_client.tables[0].name == "unique_table1_name" + assert bigquery_client.tables[0].id.__class__.__name__ == "str" + assert bigquery_client.tables[0].region == "US" + assert bigquery_client.tables[0].cmk_encryption + assert bigquery_client.tables[0].project_id == GCP_PROJECT_ID + + assert bigquery_client.tables[1].name == "unique_table2_name" + assert bigquery_client.tables[1].id.__class__.__name__ == "str" + assert bigquery_client.tables[1].region == "US" + assert not bigquery_client.tables[1].cmk_encryption + assert bigquery_client.tables[1].project_id == GCP_PROJECT_ID diff --git a/tests/providers/gcp/services/cloudresourcemanager/cloudresourcemanager_service_test.py b/tests/providers/gcp/services/cloudresourcemanager/cloudresourcemanager_service_test.py new file mode 100644 index 0000000000..7d080013de --- /dev/null +++ b/tests/providers/gcp/services/cloudresourcemanager/cloudresourcemanager_service_test.py @@ -0,0 +1,59 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.cloudresourcemanager.cloudresourcemanager_service import ( + CloudResourceManager, +) +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestCloudResourceManagerService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + api_keys_client = CloudResourceManager( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert api_keys_client.service == "cloudresourcemanager" + assert api_keys_client.project_ids == [GCP_PROJECT_ID] + + assert len(api_keys_client.projects) == 1 + assert api_keys_client.projects[0].id == GCP_PROJECT_ID + assert api_keys_client.projects[0].audit_logging + + assert len(api_keys_client.bindings) == 2 + assert ( + api_keys_client.bindings[0].role + == "roles/resourcemanager.organizationAdmin" + ) + assert len(api_keys_client.bindings[0].members) == 4 + assert api_keys_client.bindings[0].members[0] == "user:mike@example.com" + assert api_keys_client.bindings[0].members[1] == "group:admins@example.com" + assert api_keys_client.bindings[0].members[2] == "domain:google.com" + assert ( + api_keys_client.bindings[0].members[3] + == "serviceAccount:my-project-id@appspot.gserviceaccount.com" + ) + assert api_keys_client.bindings[0].project_id == GCP_PROJECT_ID + assert ( + api_keys_client.bindings[1].role + == "roles/resourcemanager.organizationViewer" + ) + assert len(api_keys_client.bindings[1].members) == 1 + assert api_keys_client.bindings[1].members[0] == "user:eve@example.com" + assert api_keys_client.bindings[1].project_id == GCP_PROJECT_ID + + assert len(api_keys_client.organizations) == 2 + assert api_keys_client.organizations[0].id == "123456789" + assert api_keys_client.organizations[0].name == "Organization 1" + assert api_keys_client.organizations[1].id == "987654321" + assert api_keys_client.organizations[1].name == "Organization 2" diff --git a/tests/providers/gcp/services/cloudsql/cloudsql_service_test.py b/tests/providers/gcp/services/cloudsql/cloudsql_service_test.py new file mode 100644 index 0000000000..f23cf612cf --- /dev/null +++ b/tests/providers/gcp/services/cloudsql/cloudsql_service_test.py @@ -0,0 +1,57 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.cloudsql.cloudsql_service import CloudSQL +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestCloudSQLService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + cloudsql_client = CloudSQL( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert cloudsql_client.service == "sqladmin" + assert cloudsql_client.project_ids == [GCP_PROJECT_ID] + + assert len(cloudsql_client.instances) == 2 + + assert cloudsql_client.instances[0].name == "instance1" + assert cloudsql_client.instances[0].version == "MYSQL_5_7" + assert cloudsql_client.instances[0].region == "us-central1" + assert cloudsql_client.instances[0].ip_addresses == [ + {"type": "PRIMARY", "ipAddress": "66.66.66.66"} + ] + assert cloudsql_client.instances[0].public_ip + assert cloudsql_client.instances[0].ssl + assert cloudsql_client.instances[0].automated_backups + assert cloudsql_client.instances[0].authorized_networks == [ + {"value": "test"} + ] + assert cloudsql_client.instances[0].flags == [] + assert cloudsql_client.instances[0].project_id == GCP_PROJECT_ID + + assert cloudsql_client.instances[1].name == "instance2" + assert cloudsql_client.instances[1].version == "POSTGRES_9_6" + assert cloudsql_client.instances[1].region == "us-central1" + assert cloudsql_client.instances[1].ip_addresses == [ + {"type": "PRIMARY", "ipAddress": "22.22.22.22"} + ] + assert cloudsql_client.instances[1].public_ip + assert not cloudsql_client.instances[1].ssl + assert not cloudsql_client.instances[1].automated_backups + assert cloudsql_client.instances[1].authorized_networks == [ + {"value": "test"} + ] + assert cloudsql_client.instances[1].flags == [] + assert cloudsql_client.instances[1].project_id == GCP_PROJECT_ID diff --git a/tests/providers/gcp/services/cloudstorage/cloudstorage_service_test.py b/tests/providers/gcp/services/cloudstorage/cloudstorage_service_test.py new file mode 100644 index 0000000000..15feaa0e8b --- /dev/null +++ b/tests/providers/gcp/services/cloudstorage/cloudstorage_service_test.py @@ -0,0 +1,46 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.cloudstorage.cloudstorage_service import ( + CloudStorage, +) +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestCloudStorageService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + cloudstorage_client = CloudStorage( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert cloudstorage_client.service == "storage" + assert cloudstorage_client.project_ids == [GCP_PROJECT_ID] + + assert len(cloudstorage_client.buckets) == 2 + assert cloudstorage_client.buckets[0].name == "bucket1" + assert cloudstorage_client.buckets[0].id.__class__.__name__ == "str" + assert cloudstorage_client.buckets[0].region == "US" + assert cloudstorage_client.buckets[0].uniform_bucket_level_access + assert cloudstorage_client.buckets[0].public + assert cloudstorage_client.buckets[0].retention_policy == { + "retentionPeriod": 10 + } + assert cloudstorage_client.buckets[0].project_id == GCP_PROJECT_ID + + assert cloudstorage_client.buckets[1].name == "bucket2" + assert cloudstorage_client.buckets[1].id.__class__.__name__ == "str" + assert cloudstorage_client.buckets[1].region == "EU" + assert not cloudstorage_client.buckets[1].uniform_bucket_level_access + assert not cloudstorage_client.buckets[1].public + assert cloudstorage_client.buckets[1].retention_policy is None + assert cloudstorage_client.buckets[1].project_id == GCP_PROJECT_ID diff --git a/tests/providers/gcp/services/compute/compute_service_test.py b/tests/providers/gcp/services/compute/compute_service_test.py new file mode 100644 index 0000000000..6a08a80ba7 --- /dev/null +++ b/tests/providers/gcp/services/compute/compute_service_test.py @@ -0,0 +1,174 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.compute.compute_service import Compute +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestComputeService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + compute_client = Compute( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert compute_client.service == "compute" + assert compute_client.project_ids == [GCP_PROJECT_ID] + + assert len(compute_client.regions) == 1 + assert "europe-west1-b" in compute_client.regions + + assert len(compute_client.zones) == 1 + assert "zone1" in compute_client.zones + + assert len(compute_client.projects) == 1 + assert compute_client.projects[0].id == GCP_PROJECT_ID + assert compute_client.projects[0].enable_oslogin + + assert len(compute_client.instances) == 2 + assert compute_client.instances[0].name == "instance1" + assert compute_client.instances[0].id.__class__.__name__ == "str" + assert compute_client.instances[0].zone == "zone1" + assert compute_client.instances[0].public_ip + assert compute_client.instances[0].project_id == GCP_PROJECT_ID + assert compute_client.instances[0].metadata == {} + assert compute_client.instances[0].shielded_enabled_vtpm + assert compute_client.instances[0].shielded_enabled_integrity_monitoring + assert compute_client.instances[0].confidential_computing + assert len(compute_client.instances[0].service_accounts) == 1 + assert ( + compute_client.instances[0].service_accounts[0]["email"] + == "test@test.es" + ) + assert compute_client.instances[0].service_accounts[0]["scopes"] == [ + "scope1", + "scope2", + ] + assert compute_client.instances[0].ip_forward + assert compute_client.instances[0].disks_encryption == [("disk1", True)] + + assert compute_client.instances[1].name == "instance2" + assert compute_client.instances[1].id.__class__.__name__ == "str" + assert compute_client.instances[1].zone == "zone1" + assert not compute_client.instances[1].public_ip + assert compute_client.instances[1].project_id == GCP_PROJECT_ID + assert compute_client.instances[1].metadata == {} + assert not compute_client.instances[1].shielded_enabled_vtpm + assert not compute_client.instances[1].shielded_enabled_integrity_monitoring + assert not compute_client.instances[1].confidential_computing + assert len(compute_client.instances[1].service_accounts) == 1 + assert ( + compute_client.instances[1].service_accounts[0]["email"] + == "test2@test.es" + ) + assert compute_client.instances[1].service_accounts[0]["scopes"] == [ + "scope3" + ] + assert not compute_client.instances[1].ip_forward + assert compute_client.instances[1].disks_encryption == [("disk2", False)] + + assert len(compute_client.networks) == 3 + assert compute_client.networks[0].name == "network1" + assert compute_client.networks[0].id.__class__.__name__ == "str" + assert compute_client.networks[0].subnet_mode == "auto" + assert compute_client.networks[0].project_id == GCP_PROJECT_ID + + assert compute_client.networks[1].name == "network2" + assert compute_client.networks[1].id.__class__.__name__ == "str" + assert compute_client.networks[1].subnet_mode == "custom" + assert compute_client.networks[1].project_id == GCP_PROJECT_ID + + assert compute_client.networks[2].name == "network3" + assert compute_client.networks[2].id.__class__.__name__ == "str" + assert compute_client.networks[2].subnet_mode == "legacy" + assert compute_client.networks[2].project_id == GCP_PROJECT_ID + + assert len(compute_client.subnets) == 3 + assert compute_client.subnets[0].name == "subnetwork1" + assert compute_client.subnets[0].id.__class__.__name__ == "str" + assert compute_client.subnets[0].flow_logs + assert compute_client.subnets[0].network == "network1" + assert compute_client.subnets[0].project_id == GCP_PROJECT_ID + + assert compute_client.subnets[1].name == "subnetwork2" + assert compute_client.subnets[1].id.__class__.__name__ == "str" + assert not compute_client.subnets[1].flow_logs + assert compute_client.subnets[1].network == "network1" + assert compute_client.subnets[1].project_id == GCP_PROJECT_ID + + assert compute_client.subnets[2].name == "subnetwork3" + assert compute_client.subnets[2].id.__class__.__name__ == "str" + assert not compute_client.subnets[2].flow_logs + assert compute_client.subnets[2].network == "network3" + assert compute_client.subnets[2].project_id == GCP_PROJECT_ID + + assert len(compute_client.addresses) == 3 + + assert compute_client.addresses[0].name == "address1" + assert compute_client.addresses[0].id.__class__.__name__ == "str" + assert compute_client.addresses[0].ip == "10.0.0.1" + assert compute_client.addresses[0].type == "INTERNAL" + assert compute_client.addresses[0].region == "europe-west1-b" + assert compute_client.addresses[0].project_id == GCP_PROJECT_ID + + assert compute_client.addresses[1].name == "address2" + assert compute_client.addresses[1].id.__class__.__name__ == "str" + assert compute_client.addresses[1].ip == "10.0.0.2" + assert compute_client.addresses[1].type == "INTERNAL" + assert compute_client.addresses[1].region == "europe-west1-b" + assert compute_client.addresses[1].project_id == GCP_PROJECT_ID + + assert compute_client.addresses[2].name == "address3" + assert compute_client.addresses[2].id.__class__.__name__ == "str" + assert compute_client.addresses[2].ip == "20.34.105.200" + assert compute_client.addresses[2].type == "EXTERNAL" + assert compute_client.addresses[2].region == "europe-west1-b" + assert compute_client.addresses[2].project_id == GCP_PROJECT_ID + + assert len(compute_client.firewalls) == 3 + assert compute_client.firewalls[0].name == "firewall1" + assert compute_client.firewalls[0].id.__class__.__name__ == "str" + assert compute_client.firewalls[0].allowed_rules == [{"IPProtocol": "UDP"}] + assert compute_client.firewalls[0].source_ranges == ["30.0.0.0/16"] + assert compute_client.firewalls[0].direction == "INGRESS" + assert compute_client.firewalls[0].project_id == GCP_PROJECT_ID + + assert compute_client.firewalls[1].name == "firewall2" + assert compute_client.firewalls[1].id.__class__.__name__ == "str" + assert compute_client.firewalls[1].allowed_rules == [{"IPProtocol": "TCP"}] + assert compute_client.firewalls[1].source_ranges == ["0.0.0.0/0"] + assert compute_client.firewalls[1].direction == "EGRESS" + assert compute_client.firewalls[1].project_id == GCP_PROJECT_ID + + assert compute_client.firewalls[2].name == "firewall3" + assert compute_client.firewalls[2].id.__class__.__name__ == "str" + assert compute_client.firewalls[2].allowed_rules == [{"IPProtocol": "TCP"}] + assert compute_client.firewalls[2].source_ranges == ["10.0.15.0/24"] + assert compute_client.firewalls[2].direction == "INGRESS" + assert compute_client.firewalls[2].project_id == GCP_PROJECT_ID + + assert len(compute_client.load_balancers) == 2 + assert compute_client.load_balancers[0].name == "url_map1" + assert compute_client.load_balancers[0].id.__class__.__name__ == "str" + assert compute_client.load_balancers[0].service == "service1" + assert compute_client.load_balancers[0].project_id == GCP_PROJECT_ID + + assert compute_client.load_balancers[1].name == "url_map2" + assert compute_client.load_balancers[1].id.__class__.__name__ == "str" + assert compute_client.load_balancers[1].service == "service2" + assert compute_client.load_balancers[1].project_id == GCP_PROJECT_ID + + assert len(compute_client.load_balancers) == 2 + + assert compute_client.load_balancers[0].logging + + assert not compute_client.load_balancers[1].logging diff --git a/tests/providers/gcp/services/dataproc/dataproc_service_test.py b/tests/providers/gcp/services/dataproc/dataproc_service_test.py new file mode 100644 index 0000000000..8bfda95037 --- /dev/null +++ b/tests/providers/gcp/services/dataproc/dataproc_service_test.py @@ -0,0 +1,47 @@ +from unittest.mock import patch + +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestDataprocService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ), patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + return_value=set_mocked_gcp_audit_info(), + ), patch( + "prowler.providers.gcp.services.dataproc.dataproc_service.compute_client.regions", + new=["europe-west1-b"], + ): + from prowler.providers.gcp.services.dataproc.dataproc_service import ( + Dataproc, + ) + + dataproc_client = Dataproc( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert dataproc_client.service == "dataproc" + + assert dataproc_client.project_ids == [GCP_PROJECT_ID] + + assert len(dataproc_client.clusters) == 2 + + assert dataproc_client.clusters[0].name == "cluster1" + assert dataproc_client.clusters[0].id.__class__.__name__ == "str" + assert dataproc_client.clusters[0].encryption_config + assert dataproc_client.clusters[0].project_id == GCP_PROJECT_ID + + assert dataproc_client.clusters[1].name == "cluster2" + assert dataproc_client.clusters[1].id.__class__.__name__ == "str" + assert not dataproc_client.clusters[1].encryption_config + assert dataproc_client.clusters[1].project_id == GCP_PROJECT_ID diff --git a/tests/providers/gcp/services/dns/dns_service_test.py b/tests/providers/gcp/services/dns/dns_service_test.py new file mode 100644 index 0000000000..6e483eeb5a --- /dev/null +++ b/tests/providers/gcp/services/dns/dns_service_test.py @@ -0,0 +1,49 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.dns.dns_service import DNS +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestDNSService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + api_keys_client = DNS( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert api_keys_client.service == "dns" + assert api_keys_client.project_ids == [GCP_PROJECT_ID] + + assert len(api_keys_client.managed_zones) == 2 + assert api_keys_client.managed_zones[0].name == "managed_zone1" + assert api_keys_client.managed_zones[0].id.__class__.__name__ == "str" + assert api_keys_client.managed_zones[0].dnssec + assert len(api_keys_client.managed_zones[0].key_specs) == 0 + assert api_keys_client.managed_zones[0].project_id == GCP_PROJECT_ID + assert api_keys_client.managed_zones[1].name == "managed_zone2" + assert api_keys_client.managed_zones[1].id.__class__.__name__ == "str" + assert not api_keys_client.managed_zones[1].dnssec + assert len(api_keys_client.managed_zones[1].key_specs) == 0 + assert api_keys_client.managed_zones[1].project_id == GCP_PROJECT_ID + + assert len(api_keys_client.policies) == 2 + assert api_keys_client.policies[0].name == "policy1" + assert api_keys_client.policies[0].id.__class__.__name__ == "str" + assert api_keys_client.policies[0].logging + assert api_keys_client.policies[0].networks == ["network1"] + assert api_keys_client.policies[0].project_id == GCP_PROJECT_ID + assert api_keys_client.policies[1].name == "policy2" + assert api_keys_client.policies[1].id.__class__.__name__ == "str" + assert not api_keys_client.policies[1].logging + assert api_keys_client.policies[1].networks == [] + assert api_keys_client.policies[1].project_id == GCP_PROJECT_ID diff --git a/tests/providers/gcp/services/gke/gke_service_test.py b/tests/providers/gcp/services/gke/gke_service_test.py new file mode 100644 index 0000000000..18f6f44b07 --- /dev/null +++ b/tests/providers/gcp/services/gke/gke_service_test.py @@ -0,0 +1,69 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.gke.gke_service import GKE +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestGKEService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + gke_client = GKE(set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID])) + assert gke_client.service == "container" + assert gke_client.project_ids == [GCP_PROJECT_ID] + + assert len(gke_client.locations) == 1 + assert gke_client.locations[0].name == "eu-west1" + assert gke_client.locations[0].project_id == GCP_PROJECT_ID + + assert len(gke_client.clusters) == 2 + assert gke_client.clusters["cluster1_id"].name == "cluster1" + assert gke_client.clusters["cluster1_id"].id.__class__.__name__ == "str" + assert gke_client.clusters["cluster1_id"].project_id == GCP_PROJECT_ID + assert gke_client.clusters["cluster1_id"].location == "eu-west1" + assert ( + gke_client.clusters["cluster1_id"].service_account == "service_account1" + ) + assert len(gke_client.clusters["cluster1_id"].node_pools) == 1 + assert gke_client.clusters["cluster1_id"].node_pools[0].name == "node_pool1" + assert gke_client.clusters["cluster1_id"].node_pools[0].locations == [ + "cluster1_location1" + ] + assert ( + gke_client.clusters["cluster1_id"].node_pools[0].service_account + == "service_account1" + ) + assert gke_client.clusters["cluster2_id"].name == "cluster2" + assert gke_client.clusters["cluster2_id"].id.__class__.__name__ == "str" + assert gke_client.clusters["cluster2_id"].project_id == GCP_PROJECT_ID + assert gke_client.clusters["cluster2_id"].location == "eu-west1" + assert ( + gke_client.clusters["cluster2_id"].service_account == "service_account2" + ) + assert len(gke_client.clusters["cluster2_id"].node_pools) == 2 + assert gke_client.clusters["cluster2_id"].node_pools[0].name == "node_pool2" + assert gke_client.clusters["cluster2_id"].node_pools[0].locations == [ + "cluster2_location1" + ] + assert ( + gke_client.clusters["cluster2_id"].node_pools[0].service_account + == "service_account2" + ) + assert gke_client.clusters["cluster2_id"].node_pools[1].name == "node_pool3" + assert gke_client.clusters["cluster2_id"].node_pools[1].locations == [ + "cluster2_location2" + ] + assert ( + gke_client.clusters["cluster2_id"].node_pools[1].service_account + == "service_account3" + ) diff --git a/tests/providers/gcp/services/iam/iam_organization_essential_contacts_configured/iam_organization_essential_contacts_configured_test.py b/tests/providers/gcp/services/iam/iam_organization_essential_contacts_configured/iam_organization_essential_contacts_configured_test.py index e7c8377db5..025d63f3e1 100644 --- a/tests/providers/gcp/services/iam/iam_organization_essential_contacts_configured/iam_organization_essential_contacts_configured_test.py +++ b/tests/providers/gcp/services/iam/iam_organization_essential_contacts_configured/iam_organization_essential_contacts_configured_test.py @@ -1,7 +1,7 @@ from re import search from unittest import mock -from prowler.providers.gcp.services.iam.iam_service import Organization +from tests.providers.gcp.gcp_fixtures import set_mocked_gcp_audit_info class Test_iam_organization_essential_contacts_configured: @@ -9,8 +9,10 @@ class Test_iam_organization_essential_contacts_configured: essentialcontacts_client = mock.MagicMock essentialcontacts_client.organizations = [] essentialcontacts_client.region = "global" - with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=set_mocked_gcp_audit_info(), + ), mock.patch( "prowler.providers.gcp.services.iam.iam_organization_essential_contacts_configured.iam_organization_essential_contacts_configured.essentialcontacts_client", new=essentialcontacts_client, ): @@ -24,15 +26,20 @@ class Test_iam_organization_essential_contacts_configured: def test_iam_org_with_contacts(self): essentialcontacts_client = mock.MagicMock - essentialcontacts_client.organizations = [ - Organization(id="test_id", name="test", contacts=True) - ] essentialcontacts_client.region = "global" - + essentialcontacts_client.organizations = [] with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=set_mocked_gcp_audit_info(), + ), mock.patch( "prowler.providers.gcp.services.iam.iam_organization_essential_contacts_configured.iam_organization_essential_contacts_configured.essentialcontacts_client", new=essentialcontacts_client, ): + from prowler.providers.gcp.services.iam.iam_service import Organization + + essentialcontacts_client.organizations = [ + Organization(id="test_id", name="test", contacts=True) + ] from prowler.providers.gcp.services.iam.iam_organization_essential_contacts_configured.iam_organization_essential_contacts_configured import ( iam_organization_essential_contacts_configured, ) @@ -52,19 +59,23 @@ class Test_iam_organization_essential_contacts_configured: def test_iam_org_without_contacts(self): essentialcontacts_client = mock.MagicMock - essentialcontacts_client.organizations = [ - Organization(id="test_id", name="test", contacts=False) - ] essentialcontacts_client.region = "global" - + essentialcontacts_client.organizations = [] with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=set_mocked_gcp_audit_info(), + ), mock.patch( "prowler.providers.gcp.services.iam.iam_organization_essential_contacts_configured.iam_organization_essential_contacts_configured.essentialcontacts_client", new=essentialcontacts_client, ): from prowler.providers.gcp.services.iam.iam_organization_essential_contacts_configured.iam_organization_essential_contacts_configured import ( iam_organization_essential_contacts_configured, ) + from prowler.providers.gcp.services.iam.iam_service import Organization + essentialcontacts_client.organizations = [ + Organization(id="test_id", name="test", contacts=False) + ] check = iam_organization_essential_contacts_configured() result = check.execute() assert len(result) == 1 diff --git a/tests/providers/gcp/services/iam/iamgcp_service_test.py b/tests/providers/gcp/services/iam/iamgcp_service_test.py new file mode 100644 index 0000000000..dcee0a257f --- /dev/null +++ b/tests/providers/gcp/services/iam/iamgcp_service_test.py @@ -0,0 +1,142 @@ +from datetime import datetime +from unittest.mock import patch + +from prowler.providers.gcp.services.cloudresourcemanager.cloudresourcemanager_service import ( + CloudResourceManager, +) +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestIAMService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ), patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + return_value=set_mocked_gcp_audit_info(), + ): + from prowler.providers.gcp.services.iam.iam_service import IAM + + iam_client = IAM(set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID])) + assert iam_client.service == "iam" + assert iam_client.project_ids == [GCP_PROJECT_ID] + + assert len(iam_client.service_accounts) == 2 + assert ( + iam_client.service_accounts[0].name + == f"projects/{GCP_PROJECT_ID}/serviceAccounts/service-account1@{GCP_PROJECT_ID}.iam.gserviceaccount.com" + ) + assert iam_client.service_accounts[0].email == "service-account1@gmail.com" + assert iam_client.service_accounts[0].display_name == "Service Account 1" + assert len(iam_client.service_accounts[0].keys) == 2 + assert iam_client.service_accounts[0].keys[0].name == "key1" + assert iam_client.service_accounts[0].keys[0].valid_after == datetime( + 2021, 1, 1, 0, 0, 0 + ) + assert iam_client.service_accounts[0].keys[0].valid_before == datetime( + 2022, 1, 1, 0, 0, 0 + ) + assert iam_client.service_accounts[0].keys[0].origin == "GOOGLE_PROVIDED" + assert iam_client.service_accounts[0].keys[0].type == "SYSTEM_MANAGED" + assert iam_client.service_accounts[0].keys[1].name == "key2" + assert iam_client.service_accounts[0].keys[1].valid_after == datetime( + 2021, 1, 1, 0, 0, 0 + ) + assert iam_client.service_accounts[0].keys[1].valid_before == datetime( + 2022, 1, 1, 0, 0, 0 + ) + assert iam_client.service_accounts[0].keys[1].origin == "ORIGIN_UNSPECIFIED" + assert iam_client.service_accounts[0].keys[1].type == "USER_MANAGED" + assert ( + iam_client.service_accounts[1].name + == f"projects/{GCP_PROJECT_ID}/serviceAccounts/service-account2@{GCP_PROJECT_ID}.iam.gserviceaccount.com" + ) + assert iam_client.service_accounts[1].email == "service-account2@gmail.com" + assert iam_client.service_accounts[1].display_name == "Service Account 2" + assert len(iam_client.service_accounts[1].keys) == 1 + assert iam_client.service_accounts[1].keys[0].name == "key3" + assert iam_client.service_accounts[1].keys[0].valid_after == datetime( + 2021, 1, 1, 0, 0, 0 + ) + assert iam_client.service_accounts[1].keys[0].valid_before == datetime( + 2022, 1, 1, 0, 0, 0 + ) + assert iam_client.service_accounts[1].keys[0].origin == "USER_PROVIDED" + assert iam_client.service_accounts[1].keys[0].type == "KEY_TYPE_UNSPECIFIED" + + +class TestAccessApproval: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ), patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + return_value=set_mocked_gcp_audit_info(), + ): + from prowler.providers.gcp.services.iam.iam_service import AccessApproval + + access_approval_client = AccessApproval( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + + assert access_approval_client.service == "accessapproval" + assert access_approval_client.project_ids == [GCP_PROJECT_ID] + + assert ( + access_approval_client.settings[GCP_PROJECT_ID].name + == "projects/123/accessApprovalSettings" + ) + assert ( + access_approval_client.settings[GCP_PROJECT_ID].project_id + == GCP_PROJECT_ID + ) + + +class TestEssentialContacts: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ), patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + return_value=set_mocked_gcp_audit_info(), + ), patch( # Reinstancing the CloudResourceManager client to secure that is not instancied first by a test + "prowler.providers.gcp.services.iam.iam_service.cloudresourcemanager_client", + new=CloudResourceManager( + set_mocked_gcp_audit_info(), + ), + ): + from prowler.providers.gcp.services.iam.iam_service import EssentialContacts + + essential_contacts_client = EssentialContacts( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + + assert essential_contacts_client.service == "essentialcontacts" + assert essential_contacts_client.project_ids == [GCP_PROJECT_ID] + + assert len(essential_contacts_client.organizations) == 2 + + assert essential_contacts_client.organizations[0].name == "Organization 1" + assert essential_contacts_client.organizations[0].id == "123456789" + assert essential_contacts_client.organizations[0].contacts + + assert essential_contacts_client.organizations[1].name == "Organization 2" + assert essential_contacts_client.organizations[1].id == "987654321" + assert not essential_contacts_client.organizations[1].contacts diff --git a/tests/providers/gcp/services/kms/kmsgcp_service_test.py b/tests/providers/gcp/services/kms/kmsgcp_service_test.py new file mode 100644 index 0000000000..3e4195beb1 --- /dev/null +++ b/tests/providers/gcp/services/kms/kmsgcp_service_test.py @@ -0,0 +1,63 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.kms.kms_service import KMS +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestKMSService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + kms_client = KMS(set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID])) + assert kms_client.service == "cloudkms" + assert kms_client.project_ids == [GCP_PROJECT_ID] + + assert len(kms_client.locations) == 1 + assert kms_client.locations[0].name == "eu-west1" + assert kms_client.locations[0].project_id == GCP_PROJECT_ID + + assert len(kms_client.key_rings) == 2 + assert ( + kms_client.key_rings[0].name + == "projects/123/locations/eu-west1/keyRings/keyring1" + ) + assert kms_client.key_rings[0].project_id == GCP_PROJECT_ID + assert ( + kms_client.key_rings[1].name + == "projects/123/locations/eu-west1/keyRings/keyring2" + ) + assert kms_client.key_rings[1].project_id == GCP_PROJECT_ID + + assert len(kms_client.crypto_keys) == 2 + assert kms_client.crypto_keys[0].name == "key1" + assert kms_client.crypto_keys[0].location == "eu-west1" + assert ( + kms_client.crypto_keys[0].key_ring + == "projects/123/locations/eu-west1/keyRings/keyring1" + ) + assert kms_client.crypto_keys[0].rotation_period == "7776000s" + assert kms_client.crypto_keys[0].members == [ + "user:mike@example.com", + "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com", + ] + assert kms_client.crypto_keys[0].project_id == GCP_PROJECT_ID + assert kms_client.crypto_keys[1].name == "key2" + assert kms_client.crypto_keys[1].location == "eu-west1" + assert ( + kms_client.crypto_keys[1].key_ring + == "projects/123/locations/eu-west1/keyRings/keyring1" + ) + assert kms_client.crypto_keys[1].members == [] + assert kms_client.crypto_keys[1].project_id == GCP_PROJECT_ID diff --git a/tests/providers/gcp/services/logging/logging_service_test.py b/tests/providers/gcp/services/logging/logging_service_test.py new file mode 100644 index 0000000000..f88825042d --- /dev/null +++ b/tests/providers/gcp/services/logging/logging_service_test.py @@ -0,0 +1,65 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.logging.logging_service import Logging +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestLoggingService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + logging_client = Logging( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert logging_client.service == "logging" + assert logging_client.project_ids == [GCP_PROJECT_ID] + + assert len(logging_client.sinks) == 2 + + assert logging_client.sinks[0].name == "sink1" + assert ( + logging_client.sinks[0].destination + == "storage.googleapis.com/example-bucket" + ) + assert logging_client.sinks[0].filter == "all" + assert logging_client.sinks[0].project_id == GCP_PROJECT_ID + assert logging_client.sinks[1].name == "sink2" + assert ( + logging_client.sinks[1].destination + == f"bigquery.googleapis.com/projects/{GCP_PROJECT_ID}/datasets/example_dataset" + ) + assert logging_client.sinks[1].filter == "all" + assert logging_client.sinks[1].project_id == GCP_PROJECT_ID + + assert len(logging_client.metrics) == 2 + + assert logging_client.metrics[0].name == "metric1" + assert ( + logging_client.metrics[0].type + == "custom.googleapis.com/invoice/paid/amount" + ) + assert ( + logging_client.metrics[0].filter + == "resource.type=gae_app AND severity>=ERROR" + ) + assert logging_client.metrics[0].project_id == GCP_PROJECT_ID + assert logging_client.metrics[1].name == "metric2" + assert ( + logging_client.metrics[1].type + == "external.googleapis.com/prometheus/up" + ) + assert ( + logging_client.metrics[1].filter + == "resource.type=gae_app AND severity>=ERROR" + ) + assert logging_client.metrics[1].project_id == GCP_PROJECT_ID diff --git a/tests/providers/gcp/services/monitoring/monitoring_service_test.py b/tests/providers/gcp/services/monitoring/monitoring_service_test.py new file mode 100644 index 0000000000..81cf4d6a20 --- /dev/null +++ b/tests/providers/gcp/services/monitoring/monitoring_service_test.py @@ -0,0 +1,40 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.monitoring.monitoring_service import Monitoring +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestMonitoringService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + monitoring_client = Monitoring( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert monitoring_client.service == "monitoring" + assert monitoring_client.project_ids == [GCP_PROJECT_ID] + + assert len(monitoring_client.alert_policies) == 2 + assert monitoring_client.alert_policies[0].name == "alert_policy1" + assert monitoring_client.alert_policies[0].display_name == "Alert Policy 1" + assert monitoring_client.alert_policies[0].enabled + assert monitoring_client.alert_policies[0].filters == [ + 'metric.type="compute.googleapis.com/instance/disk/write_bytes_count"' + ] + assert monitoring_client.alert_policies[0].project_id == GCP_PROJECT_ID + assert monitoring_client.alert_policies[1].name == "alert_policy2" + assert monitoring_client.alert_policies[1].display_name == "Alert Policy 2" + assert not monitoring_client.alert_policies[1].enabled + assert monitoring_client.alert_policies[1].filters == [ + 'metric.type="compute.googleapis.com/instance/disk/write_bytes_count"' + ] diff --git a/tests/providers/gcp/services/serviceusage/serviceusage_test.py b/tests/providers/gcp/services/serviceusage/serviceusage_test.py new file mode 100644 index 0000000000..7a47459088 --- /dev/null +++ b/tests/providers/gcp/services/serviceusage/serviceusage_test.py @@ -0,0 +1,54 @@ +from unittest.mock import patch + +from prowler.providers.gcp.services.serviceusage.serviceusage_service import ( + ServiceUsage, +) +from tests.providers.gcp.gcp_fixtures import ( + GCP_PROJECT_ID, + mock_api_client, + mock_is_api_active, + set_mocked_gcp_audit_info, +) + + +class TestServiceUsageService: + def test_service(self): + with patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + new=mock_api_client, + ): + serviceusage_client = ServiceUsage( + set_mocked_gcp_audit_info(project_ids=[GCP_PROJECT_ID]) + ) + assert serviceusage_client.service == "serviceusage" + assert serviceusage_client.project_ids == [GCP_PROJECT_ID] + + assert len(serviceusage_client.active_services[GCP_PROJECT_ID]) == 2 + + assert ( + serviceusage_client.active_services[GCP_PROJECT_ID][0].name + == "artifacts.googleapis.com" + ) + assert ( + serviceusage_client.active_services[GCP_PROJECT_ID][0].title + == "artifacts.googleapis.com" + ) + assert ( + serviceusage_client.active_services[GCP_PROJECT_ID][0].project_id + == GCP_PROJECT_ID + ) + assert ( + serviceusage_client.active_services[GCP_PROJECT_ID][1].name + == "bigquery.googleapis.com" + ) + assert ( + serviceusage_client.active_services[GCP_PROJECT_ID][1].title + == "bigquery.googleapis.com" + ) + assert ( + serviceusage_client.active_services[GCP_PROJECT_ID][1].project_id + == GCP_PROJECT_ID + )