From 9e7104fb7f719cacb64bd97cdd399026d262e950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20De=20la=20Torre=20Vico?= Date: Wed, 15 Jan 2025 18:14:24 +0100 Subject: [PATCH] feat(defender): extract Defender resource metadata in automated way (#6538) --- ...mail_configured_with_a_security_contact.py | 10 +- ...sments_vm_endpoint_protection_installed.py | 16 ++-- ...provisioning_log_analytics_agent_vms_on.py | 11 +-- ...ng_vulnerabilty_assessments_machines_on.py | 15 ++- ...ntainer_images_resolved_vulnerabilities.py | 16 ++-- .../defender_container_images_scan_enabled.py | 7 +- ..._ensure_defender_for_app_services_is_on.py | 7 +- .../defender_ensure_defender_for_arm_is_on.py | 7 +- ..._defender_for_azure_sql_databases_is_on.py | 7 +- ...er_ensure_defender_for_containers_is_on.py | 7 +- ...nder_ensure_defender_for_cosmosdb_is_on.py | 7 +- ...der_ensure_defender_for_databases_is_on.py | 7 +- .../defender_ensure_defender_for_dns_is_on.py | 7 +- ...nder_ensure_defender_for_keyvault_is_on.py | 7 +- ...ender_for_os_relational_databases_is_on.py | 10 +- ...fender_ensure_defender_for_server_is_on.py | 10 +- ...r_ensure_defender_for_sql_servers_is_on.py | 8 +- ...ender_ensure_defender_for_storage_is_on.py | 8 +- .../defender_ensure_iot_hub_defender_is_on.py | 34 ++++--- .../defender_ensure_mcas_is_enabled.py | 27 ++++-- ...r_ensure_notify_alerts_severity_is_high.py | 12 +-- ...defender_ensure_notify_emails_to_owners.py | 17 ++-- ...ender_ensure_system_updates_are_applied.py | 15 ++- .../defender_ensure_wdatp_is_enabled.py | 27 ++++-- .../services/defender/defender_service.py | 7 +- ...configured_with_a_security_contact_test.py | 18 ++-- ...nder_ensure_iot_hub_defender_is_on_test.py | 95 +++++++++++-------- .../defender_ensure_mcas_is_enabled_test.py | 2 +- ...ure_notify_alerts_severity_is_high_test.py | 69 ++++++++------ ...der_ensure_notify_emails_to_owners_test.py | 12 ++- .../defender_ensure_wdatp_is_enabled_test.py | 2 +- .../defender/defender_service_test.py | 42 +++++--- 32 files changed, 317 insertions(+), 229 deletions(-) diff --git a/prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.py b/prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.py index a6d2384781..3020b395b5 100644 --- a/prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.py +++ b/prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.py @@ -12,15 +12,15 @@ class defender_additional_email_configured_with_a_security_contact(Check): subscription_name, security_contacts, ) in defender_client.security_contacts.items(): - for contact_name, contact_info in security_contacts.items(): - report = Check_Report_Azure(self.metadata()) + for contact in security_contacts.values(): + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=contact + ) report.status = "PASS" report.subscription = subscription_name - report.resource_name = contact_name - report.resource_id = contact_info.resource_id report.status_extended = f"There is another correct email configured for subscription {subscription_name}." - emails = contact_info.emails.split(";") + emails = contact.emails.split(";") for email in emails: if re.fullmatch( diff --git a/prowler/providers/azure/services/defender/defender_assessments_vm_endpoint_protection_installed/defender_assessments_vm_endpoint_protection_installed.py b/prowler/providers/azure/services/defender/defender_assessments_vm_endpoint_protection_installed/defender_assessments_vm_endpoint_protection_installed.py index 7d144e03ac..30ad4ee47d 100644 --- a/prowler/providers/azure/services/defender/defender_assessments_vm_endpoint_protection_installed/defender_assessments_vm_endpoint_protection_installed.py +++ b/prowler/providers/azure/services/defender/defender_assessments_vm_endpoint_protection_installed/defender_assessments_vm_endpoint_protection_installed.py @@ -10,20 +10,18 @@ class defender_assessments_vm_endpoint_protection_installed(Check): subscription_name, assessments, ) in defender_client.assessments.items(): - if ( "Install endpoint protection solution on virtual machines" in assessments ): - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=assessments[ + "Install endpoint protection solution on virtual machines" + ], + ) report.subscription = subscription_name - report.resource_name = assessments[ - "Install endpoint protection solution on virtual machines" - ].resource_name - report.resource_id = assessments[ - "Install endpoint protection solution on virtual machines" - ].resource_id + report.status = "PASS" report.status_extended = f"Endpoint protection is set up in all VMs in subscription {subscription_name}." if ( diff --git a/prowler/providers/azure/services/defender/defender_auto_provisioning_log_analytics_agent_vms_on/defender_auto_provisioning_log_analytics_agent_vms_on.py b/prowler/providers/azure/services/defender/defender_auto_provisioning_log_analytics_agent_vms_on/defender_auto_provisioning_log_analytics_agent_vms_on.py index ff14bd51e1..4713e0c138 100644 --- a/prowler/providers/azure/services/defender/defender_auto_provisioning_log_analytics_agent_vms_on/defender_auto_provisioning_log_analytics_agent_vms_on.py +++ b/prowler/providers/azure/services/defender/defender_auto_provisioning_log_analytics_agent_vms_on/defender_auto_provisioning_log_analytics_agent_vms_on.py @@ -10,14 +10,13 @@ class defender_auto_provisioning_log_analytics_agent_vms_on(Check): subscription_name, auto_provisioning_settings, ) in defender_client.auto_provisioning_settings.items(): - for auto_provisioning_setting in auto_provisioning_settings.values(): - - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=auto_provisioning_setting, + ) report.subscription = subscription_name - report.resource_name = auto_provisioning_setting.resource_name - report.resource_id = auto_provisioning_setting.resource_id + report.status = "PASS" report.status_extended = f"Defender Auto Provisioning Log Analytics Agents from subscription {subscription_name} is set to ON." if auto_provisioning_setting.auto_provision != "On": diff --git a/prowler/providers/azure/services/defender/defender_auto_provisioning_vulnerabilty_assessments_machines_on/defender_auto_provisioning_vulnerabilty_assessments_machines_on.py b/prowler/providers/azure/services/defender/defender_auto_provisioning_vulnerabilty_assessments_machines_on/defender_auto_provisioning_vulnerabilty_assessments_machines_on.py index 5c9b701ee7..5b407edbec 100644 --- a/prowler/providers/azure/services/defender/defender_auto_provisioning_vulnerabilty_assessments_machines_on/defender_auto_provisioning_vulnerabilty_assessments_machines_on.py +++ b/prowler/providers/azure/services/defender/defender_auto_provisioning_vulnerabilty_assessments_machines_on/defender_auto_provisioning_vulnerabilty_assessments_machines_on.py @@ -14,15 +14,14 @@ class defender_auto_provisioning_vulnerabilty_assessments_machines_on(Check): "Machines should have a vulnerability assessment solution" in assessments ): - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=assessments[ + "Machines should have a vulnerability assessment solution" + ], + ) report.subscription = subscription_name - report.resource_name = assessments[ - "Machines should have a vulnerability assessment solution" - ].resource_name - report.resource_id = assessments[ - "Machines should have a vulnerability assessment solution" - ].resource_id + report.status = "PASS" report.status_extended = f"Vulnerability assessment is set up in all VMs in subscription {subscription_name}." if ( diff --git a/prowler/providers/azure/services/defender/defender_container_images_resolved_vulnerabilities/defender_container_images_resolved_vulnerabilities.py b/prowler/providers/azure/services/defender/defender_container_images_resolved_vulnerabilities/defender_container_images_resolved_vulnerabilities.py index 090f306724..0f6962cd17 100644 --- a/prowler/providers/azure/services/defender/defender_container_images_resolved_vulnerabilities/defender_container_images_resolved_vulnerabilities.py +++ b/prowler/providers/azure/services/defender/defender_container_images_resolved_vulnerabilities/defender_container_images_resolved_vulnerabilities.py @@ -22,17 +22,15 @@ class defender_container_images_resolved_vulnerabilities(Check): ) != "NotApplicable" ): - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=assessments[ + "Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)" + ], + ) report.subscription = subscription_name - report.resource_name = assessments[ - "Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)" - ].resource_name - report.resource_id = assessments[ - "Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)" - ].resource_id + report.status = "PASS" report.status_extended = f"Azure running container images do not have unresolved vulnerabilities in subscription '{subscription_name}'." - if ( assessments[ "Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)" diff --git a/prowler/providers/azure/services/defender/defender_container_images_scan_enabled/defender_container_images_scan_enabled.py b/prowler/providers/azure/services/defender/defender_container_images_scan_enabled/defender_container_images_scan_enabled.py index 26c654cc82..aa9f1a9a14 100644 --- a/prowler/providers/azure/services/defender/defender_container_images_scan_enabled/defender_container_images_scan_enabled.py +++ b/prowler/providers/azure/services/defender/defender_container_images_scan_enabled/defender_container_images_scan_enabled.py @@ -7,11 +7,12 @@ class defender_container_images_scan_enabled(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "Containers" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["Containers"] + ) report.subscription = subscription - report.resource_id = pricings["Containers"].resource_id report.resource_name = "Dender plan for Containers" + report.status = "PASS" report.status_extended = ( f"Container image scan is enabled in subscription {subscription}." ) diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.py index 5869211367..f65d42a62e 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.py @@ -7,11 +7,12 @@ class defender_ensure_defender_for_app_services_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "AppServices" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["AppServices"] + ) report.subscription = subscription report.resource_name = "Defender plan App Services" - report.resource_id = pricings["AppServices"].resource_id + report.status = "PASS" report.status_extended = f"Defender plan Defender for App Services from subscription {subscription} is set to ON (pricing tier standard)." if pricings["AppServices"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_arm_is_on/defender_ensure_defender_for_arm_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_arm_is_on/defender_ensure_defender_for_arm_is_on.py index 4483e98100..03915a409e 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_arm_is_on/defender_ensure_defender_for_arm_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_arm_is_on/defender_ensure_defender_for_arm_is_on.py @@ -7,11 +7,12 @@ class defender_ensure_defender_for_arm_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "Arm" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["Arm"] + ) report.subscription = subscription - report.resource_id = pricings["Arm"].resource_id report.resource_name = "Defender plan ARM" + report.status = "PASS" report.status_extended = f"Defender plan Defender for ARM from subscription {subscription} is set to ON (pricing tier standard)." if pricings["Arm"].pricing_tier != "Standard": report.status = "FAIL" 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.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_azure_sql_databases_is_on/defender_ensure_defender_for_azure_sql_databases_is_on.py index 451e947dc6..c195715f0a 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.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_azure_sql_databases_is_on/defender_ensure_defender_for_azure_sql_databases_is_on.py @@ -7,11 +7,12 @@ class defender_ensure_defender_for_azure_sql_databases_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "SqlServers" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["SqlServers"] + ) report.subscription = subscription - report.resource_id = pricings["SqlServers"].resource_id report.resource_name = "Defender plan Azure SQL DB Servers" + report.status = "PASS" report.status_extended = f"Defender plan Defender for Azure SQL DB Servers from subscription {subscription} is set to ON (pricing tier standard)." if pricings["SqlServers"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.py index 365f7ff951..aa055e1471 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.py @@ -7,11 +7,12 @@ class defender_ensure_defender_for_containers_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "Containers" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["Containers"] + ) report.subscription = subscription - report.resource_id = pricings["Containers"].resource_id report.resource_name = "Defender plan Container Registries" + report.status = "PASS" report.status_extended = f"Defender plan Defender for Containers from subscription {subscription} is set to ON (pricing tier standard)." if pricings["Containers"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_cosmosdb_is_on/defender_ensure_defender_for_cosmosdb_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_cosmosdb_is_on/defender_ensure_defender_for_cosmosdb_is_on.py index eecaf6d7ca..924d772dc7 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_cosmosdb_is_on/defender_ensure_defender_for_cosmosdb_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_cosmosdb_is_on/defender_ensure_defender_for_cosmosdb_is_on.py @@ -7,11 +7,12 @@ class defender_ensure_defender_for_cosmosdb_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "CosmosDbs" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["CosmosDbs"] + ) report.subscription = subscription - report.resource_id = pricings["CosmosDbs"].resource_id report.resource_name = "Defender plan Cosmos DB" + report.status = "PASS" report.status_extended = f"Defender plan Defender for Cosmos DB from subscription {subscription} is set to ON (pricing tier standard)." if pricings["CosmosDbs"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_databases_is_on/defender_ensure_defender_for_databases_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_databases_is_on/defender_ensure_defender_for_databases_is_on.py index f2b61f8729..558179e2cd 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_databases_is_on/defender_ensure_defender_for_databases_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_databases_is_on/defender_ensure_defender_for_databases_is_on.py @@ -12,10 +12,11 @@ class defender_ensure_defender_for_databases_is_on(Check): and "OpenSourceRelationalDatabases" in pricings and "CosmosDbs" in pricings ): - report = Check_Report_Azure(self.metadata()) - report.resource_name = "Defender plan Databases" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["SqlServers"] + ) report.subscription = subscription - report.resource_id = pricings["SqlServers"].resource_id + report.resource_name = "Defender plan Databases" report.status = "PASS" report.status_extended = f"Defender plan Defender for Databases from subscription {subscription} is set to ON (pricing tier standard)." if ( diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_dns_is_on/defender_ensure_defender_for_dns_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_dns_is_on/defender_ensure_defender_for_dns_is_on.py index 89f12eff62..96bbca1bd3 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_dns_is_on/defender_ensure_defender_for_dns_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_dns_is_on/defender_ensure_defender_for_dns_is_on.py @@ -7,11 +7,12 @@ class defender_ensure_defender_for_dns_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "Dns" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["Dns"] + ) report.subscription = subscription report.resource_name = "Defender plan DNS" - report.resource_id = pricings["Dns"].resource_id + report.status = "PASS" report.status_extended = f"Defender plan Defender for DNS from subscription {subscription} is set to ON (pricing tier standard)." if pricings["Dns"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.py index 52f05a96a4..7ed2e0a6ec 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.py @@ -7,11 +7,12 @@ class defender_ensure_defender_for_keyvault_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "KeyVaults" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=pricings["KeyVaults"] + ) report.subscription = subscription report.resource_name = "Defender plan KeyVaults" - report.resource_id = pricings["KeyVaults"].resource_id + report.status = "PASS" report.status_extended = f"Defender plan Defender for KeyVaults from subscription {subscription} is set to ON (pricing tier standard)." if pricings["KeyVaults"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_os_relational_databases_is_on/defender_ensure_defender_for_os_relational_databases_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_os_relational_databases_is_on/defender_ensure_defender_for_os_relational_databases_is_on.py index f4bbee643c..cc114ac4f1 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_os_relational_databases_is_on/defender_ensure_defender_for_os_relational_databases_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_os_relational_databases_is_on/defender_ensure_defender_for_os_relational_databases_is_on.py @@ -7,13 +7,13 @@ class defender_ensure_defender_for_os_relational_databases_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "OpenSourceRelationalDatabases" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=pricings["OpenSourceRelationalDatabases"], + ) report.subscription = subscription report.resource_name = "Defender plan Open-Source Relational Databases" - report.resource_id = pricings[ - "OpenSourceRelationalDatabases" - ].resource_id + report.status = "PASS" report.status_extended = f"Defender plan Defender for Open-Source Relational Databases from subscription {subscription} is set to ON (pricing tier standard)." if pricings["OpenSourceRelationalDatabases"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.py index dba393bd10..0ce39b3692 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.py @@ -7,15 +7,17 @@ class defender_ensure_defender_for_server_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "VirtualMachines" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=pricings["VirtualMachines"], + ) report.subscription = subscription report.resource_name = "Defender plan Servers" - report.resource_id = pricings["VirtualMachines"].resource_id + report.status = "PASS" report.status_extended = f"Defender plan Defender for Servers from subscription {subscription} is set to ON (pricing tier standard)." if pricings["VirtualMachines"].pricing_tier != "Standard": report.status = "FAIL" report.status_extended = f"Defender plan Defender for Servers from subscription {subscription} is set to OFF (pricing tier not standard)." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.py index 83c02d9662..7b8349e2ee 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.py @@ -7,11 +7,13 @@ class defender_ensure_defender_for_sql_servers_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "SqlServerVirtualMachines" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=pricings["SqlServerVirtualMachines"], + ) report.subscription = subscription report.resource_name = "Defender plan SQL Server VMs" - report.resource_id = pricings["SqlServerVirtualMachines"].resource_id + report.status = "PASS" report.status_extended = f"Defender plan Defender for SQL Server VMs from subscription {subscription} is set to ON (pricing tier standard)." if pricings["SqlServerVirtualMachines"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.py index ff02823570..d5cccbc397 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.py @@ -7,11 +7,13 @@ class defender_ensure_defender_for_storage_is_on(Check): findings = [] for subscription, pricings in defender_client.pricings.items(): if "StorageAccounts" in pricings: - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=pricings["StorageAccounts"], + ) report.subscription = subscription report.resource_name = "Defender plan Storage Accounts" - report.resource_id = pricings["StorageAccounts"].resource_id + report.status = "PASS" report.status_extended = f"Defender plan Defender for Storage Accounts from subscription {subscription} is set to ON (pricing tier standard)." if pricings["StorageAccounts"].pricing_tier != "Standard": report.status = "FAIL" diff --git a/prowler/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on.py b/prowler/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on.py index 3a69a615fd..4d834b39ff 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on.py +++ b/prowler/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on.py @@ -10,32 +10,30 @@ class defender_ensure_iot_hub_defender_is_on(Check): subscription_name, iot_security_solutions, ) in defender_client.iot_security_solutions.items(): - if not iot_security_solutions: - report = Check_Report_Azure(self.metadata()) + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata={} + ) report.status = "FAIL" report.subscription = subscription_name report.resource_name = "IoT Hub Defender" report.resource_id = "IoT Hub Defender" report.status_extended = f"No IoT Security Solutions found in the subscription {subscription_name}." findings.append(report) - continue + else: + for iot_security_solution in iot_security_solutions.values(): + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=iot_security_solution, + ) + report.subscription = subscription_name + report.status = "PASS" + report.status_extended = f"The security solution {iot_security_solution.name} is enabled in subscription {subscription_name}." - for ( - iot_security_solution_name, - iot_security_solution, - ) in iot_security_solutions.items(): - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" - report.subscription = subscription_name - report.resource_name = iot_security_solution_name - report.resource_id = iot_security_solution.resource_id - report.status_extended = f"The security solution {iot_security_solution_name} is enabled in subscription {subscription_name}." + if iot_security_solution.status != "Enabled": + report.status = "FAIL" + report.status_extended = f"The security solution {iot_security_solution.name} is disabled in subscription {subscription_name}" - if iot_security_solution.status != "Enabled": - report.status = "FAIL" - report.status_extended = f"The security solution {iot_security_solution_name} is disabled in subscription {subscription_name}" - - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled.py b/prowler/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled.py index aa1ca35bdb..9061a9b0fc 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled.py +++ b/prowler/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled.py @@ -10,18 +10,27 @@ class defender_ensure_mcas_is_enabled(Check): subscription_name, settings, ) in defender_client.settings.items(): - report = Check_Report_Azure(self.metadata()) - report.status = "FAIL" - report.subscription = subscription_name - report.resource_name = "MCAS" - report.resource_id = "MCAS" - report.status_extended = f"Microsoft Defender for Cloud Apps not exists for subscription {subscription_name}." - if "MCAS" in settings: - report.resource_id = settings["MCAS"].resource_id - report.status_extended = f"Microsoft Defender for Cloud Apps is disabeld for subscription {subscription_name}." + if "MCAS" not in settings: + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata={} + ) + report.subscription = subscription_name + report.resource_name = "MCAS" + report.resource_id = "MCAS" + report.status = "FAIL" + report.status_extended = f"Microsoft Defender for Cloud Apps not exists for subscription {subscription_name}." + else: + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=settings["MCAS"] + ) + report.subscription = subscription_name + report.resource_name = "MCAS" if settings["MCAS"].enabled: report.status = "PASS" report.status_extended = f"Microsoft Defender for Cloud Apps is enabled for subscription {subscription_name}." + else: + report.status = "FAIL" + report.status_extended = f"Microsoft Defender for Cloud Apps is disabled for subscription {subscription_name}." findings.append(report) diff --git a/prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.py b/prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.py index bee0a44d8c..ad01fbc978 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.py +++ b/prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.py @@ -10,15 +10,15 @@ class defender_ensure_notify_alerts_severity_is_high(Check): subscription_name, security_contacts, ) in defender_client.security_contacts.items(): - for contact_name, contact_info in security_contacts.items(): - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + for contact in security_contacts.values(): + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=contact + ) report.subscription = subscription_name - report.resource_name = contact_name - report.resource_id = contact_info.resource_id + report.status = "PASS" report.status_extended = f"Notifiy alerts are enabled for severity high in subscription {subscription_name}." - if contact_info.alert_notifications_minimal_severity != "High": + if contact.alert_notifications_minimal_severity != "High": report.status = "FAIL" report.status_extended = f"Notifiy alerts are not enabled for severity high in subscription {subscription_name}." diff --git a/prowler/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners.py b/prowler/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners.py index c689b652d1..c6b8c0fcc8 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners.py +++ b/prowler/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners.py @@ -10,21 +10,18 @@ class defender_ensure_notify_emails_to_owners(Check): subscription_name, security_contacts, ) in defender_client.security_contacts.items(): - - for contact_name, contact_info in security_contacts.items(): - - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + for contact in security_contacts.values(): + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=contact + ) report.subscription = subscription_name - report.resource_name = contact_name - report.resource_id = contact_info.resource_id + report.status = "PASS" report.status_extended = ( f"The Owner role is notified for subscription {subscription_name}." ) - if ( - contact_info.notified_roles_state != "On" - or "Owner" not in contact_info.notified_roles + contact.notified_roles_state != "On" + or "Owner" not in contact.notified_roles ): report.status = "FAIL" report.status_extended = f"The Owner role is not notified for subscription {subscription_name}." diff --git a/prowler/providers/azure/services/defender/defender_ensure_system_updates_are_applied/defender_ensure_system_updates_are_applied.py b/prowler/providers/azure/services/defender/defender_ensure_system_updates_are_applied/defender_ensure_system_updates_are_applied.py index 9155c107b7..431ec38792 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_system_updates_are_applied/defender_ensure_system_updates_are_applied.py +++ b/prowler/providers/azure/services/defender/defender_ensure_system_updates_are_applied/defender_ensure_system_updates_are_applied.py @@ -17,15 +17,14 @@ class defender_ensure_system_updates_are_applied(Check): in assessments and "System updates should be installed on your machines" in assessments ): - report = Check_Report_Azure(self.metadata()) - report.status = "PASS" + report = Check_Report_Azure( + metadata=self.metadata(), + resource_metadata=assessments[ + "System updates should be installed on your machines" + ], + ) report.subscription = subscription_name - report.resource_name = assessments[ - "System updates should be installed on your machines" - ].resource_name - report.resource_id = assessments[ - "System updates should be installed on your machines" - ].resource_id + report.status = "PASS" report.status_extended = f"System updates are applied for all the VMs in the subscription {subscription_name}." if ( diff --git a/prowler/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled.py b/prowler/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled.py index 2a121211ed..90a16c4f4a 100644 --- a/prowler/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled.py +++ b/prowler/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled.py @@ -10,18 +10,27 @@ class defender_ensure_wdatp_is_enabled(Check): subscription_name, settings, ) in defender_client.settings.items(): - report = Check_Report_Azure(self.metadata()) - report.status = "FAIL" - report.subscription = subscription_name - report.resource_name = "WDATP" - report.resource_id = "WDATP" - report.status_extended = f"Microsoft Defender for Endpoint integration not exists for subscription {subscription_name}." - if "WDATP" in settings: - report.status_extended = f"Microsoft Defender for Endpoint integration is disabeld for subscription {subscription_name}." - report.resource_id = settings["WDATP"].resource_id + if "WDATP" not in settings: + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata={} + ) + report.subscription = subscription_name + report.resource_name = "WDATP" + report.resource_id = "WDATP" + report.status = "FAIL" + report.status_extended = f"Microsoft Defender for Endpoint integration not exists for subscription {subscription_name}." + else: + report = Check_Report_Azure( + metadata=self.metadata(), resource_metadata=settings["WDATP"] + ) + report.subscription = subscription_name + report.resource_name = "WDATP" if settings["WDATP"].enabled: report.status = "PASS" report.status_extended = f"Microsoft Defender for Endpoint integration is enabled for subscription {subscription_name}." + else: + report.status = "FAIL" + report.status_extended = f"Microsoft Defender for Endpoint integration is disabled for subscription {subscription_name}." findings.append(report) diff --git a/prowler/providers/azure/services/defender/defender_service.py b/prowler/providers/azure/services/defender/defender_service.py index c91d0cd4ce..25a0e4f34d 100644 --- a/prowler/providers/azure/services/defender/defender_service.py +++ b/prowler/providers/azure/services/defender/defender_service.py @@ -14,7 +14,6 @@ from prowler.providers.azure.azure_provider import AzureProvider from prowler.providers.azure.lib.service.service import AzureService -########################## Defender class Defender(AzureService): def __init__(self, provider: AzureProvider): super().__init__(SecurityCenter, provider) @@ -161,6 +160,7 @@ class Defender(AzureService): { security_contact_default.name: SecurityContacts( resource_id=security_contact_default.id, + name=security_contact_default.name, emails=security_contact_default.emails, phone=security_contact_default.phone, alert_notifications_minimal_severity=security_contact_default.alert_notifications.minimal_severity, @@ -207,8 +207,9 @@ class Defender(AzureService): for iot_security_solution in iot_security_solutions_list: iot_security_solutions[subscription_name].update( { - iot_security_solution.name: IoTSecuritySolution( + iot_security_solution.id: IoTSecuritySolution( resource_id=iot_security_solution.id, + name=iot_security_solution.name, status=iot_security_solution.status, ) } @@ -249,6 +250,7 @@ class Setting(BaseModel): class SecurityContacts(BaseModel): resource_id: str + name: str emails: str phone: str alert_notifications_minimal_severity: str @@ -259,4 +261,5 @@ class SecurityContacts(BaseModel): class IoTSecuritySolution(BaseModel): resource_id: str + name: str status: str diff --git a/tests/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact_test.py b/tests/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact_test.py index 31cfa7753a..8bb0eacfed 100644 --- a/tests/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact_test.py +++ b/tests/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact_test.py @@ -33,8 +33,9 @@ class Test_defender_additional_email_configured_with_a_security_contact: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="", phone="", alert_notifications_minimal_severity="High", @@ -73,8 +74,9 @@ class Test_defender_additional_email_configured_with_a_security_contact: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="bad_email", phone="", alert_notifications_minimal_severity="High", @@ -113,8 +115,9 @@ class Test_defender_additional_email_configured_with_a_security_contact: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="test@test.es, test@test.email.com", phone="", alert_notifications_minimal_severity="High", @@ -153,8 +156,9 @@ class Test_defender_additional_email_configured_with_a_security_contact: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="test@test.com", phone="", alert_notifications_minimal_severity="High", @@ -193,8 +197,9 @@ class Test_defender_additional_email_configured_with_a_security_contact: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="test@test.mail.es; bad_mail", phone="", alert_notifications_minimal_severity="High", @@ -232,8 +237,9 @@ class Test_defender_additional_email_configured_with_a_security_contact: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Security/securityContacts/default": SecurityContacts( resource_id=f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Security/securityContacts/default", + name="default", emails="", phone="", alert_notifications_minimal_severity="", diff --git a/tests/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on_test.py b/tests/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on_test.py index 5d53bcdf1d..0f895117f8 100644 --- a/tests/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on_test.py +++ b/tests/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on_test.py @@ -15,12 +15,15 @@ class Test_defender_ensure_iot_hub_defender_is_on: defender_client = mock.MagicMock defender_client.iot_security_solutions = {} - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on import ( defender_ensure_iot_hub_defender_is_on, @@ -34,12 +37,15 @@ class Test_defender_ensure_iot_hub_defender_is_on: defender_client = mock.MagicMock defender_client.iot_security_solutions = {AZURE_SUBSCRIPTION_ID: {}} - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on import ( defender_ensure_iot_hub_defender_is_on, @@ -61,18 +67,21 @@ class Test_defender_ensure_iot_hub_defender_is_on: defender_client = mock.MagicMock defender_client.iot_security_solutions = { AZURE_SUBSCRIPTION_ID: { - "iot_sec_solution": IoTSecuritySolution( - resource_id=resource_id, status="Disabled" + resource_id: IoTSecuritySolution( + resource_id=resource_id, name="iot_sec_solution", status="Disabled" ) } } - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on import ( defender_ensure_iot_hub_defender_is_on, @@ -94,18 +103,21 @@ class Test_defender_ensure_iot_hub_defender_is_on: defender_client = mock.MagicMock defender_client.iot_security_solutions = { AZURE_SUBSCRIPTION_ID: { - "iot_sec_solution": IoTSecuritySolution( - resource_id=resource_id, status="Enabled" + resource_id: IoTSecuritySolution( + resource_id=resource_id, name="iot_sec_solution", status="Enabled" ) } } - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on import ( defender_ensure_iot_hub_defender_is_on, @@ -129,21 +141,28 @@ class Test_defender_ensure_iot_hub_defender_is_on: defender_client = mock.MagicMock defender_client.iot_security_solutions = { AZURE_SUBSCRIPTION_ID: { - "iot_sec_solution_enabled": IoTSecuritySolution( - resource_id=resource_id_enabled, status="Enabled" + resource_id_enabled: IoTSecuritySolution( + resource_id=resource_id_enabled, + name="iot_sec_solution_enabled", + status="Enabled", ), - "iot_sec_solution_disabled": IoTSecuritySolution( - resource_id=resource_id_disabled, status="Disabled" + resource_id_disabled: IoTSecuritySolution( + resource_id=resource_id_disabled, + name="iot_sec_solution_disabled", + status="Disabled", ), } } - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_iot_hub_defender_is_on.defender_ensure_iot_hub_defender_is_on import ( defender_ensure_iot_hub_defender_is_on, diff --git a/tests/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled_test.py b/tests/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled_test.py index 741f43315d..aba618d0eb 100644 --- a/tests/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled_test.py +++ b/tests/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled_test.py @@ -59,7 +59,7 @@ class Test_defender_ensure_mcas_is_enabled: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Microsoft Defender for Cloud Apps is disabeld for subscription {AZURE_SUBSCRIPTION_ID}." + == f"Microsoft Defender for Cloud Apps is disabled for subscription {AZURE_SUBSCRIPTION_ID}." ) assert result[0].subscription == AZURE_SUBSCRIPTION_ID assert result[0].resource_name == "MCAS" diff --git a/tests/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high_test.py b/tests/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high_test.py index f88e473cd5..a2764139c6 100644 --- a/tests/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high_test.py +++ b/tests/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high_test.py @@ -13,12 +13,15 @@ class Test_defender_ensure_notify_alerts_severity_is_high: defender_client = mock.MagicMock defender_client.security_contacts = {} - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high import ( defender_ensure_notify_alerts_severity_is_high, @@ -33,8 +36,9 @@ class Test_defender_ensure_notify_alerts_severity_is_high: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="", phone="", alert_notifications_minimal_severity="Low", @@ -45,12 +49,15 @@ class Test_defender_ensure_notify_alerts_severity_is_high: } } - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high import ( defender_ensure_notify_alerts_severity_is_high, @@ -73,8 +80,9 @@ class Test_defender_ensure_notify_alerts_severity_is_high: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="", phone="", alert_notifications_minimal_severity="High", @@ -85,12 +93,15 @@ class Test_defender_ensure_notify_alerts_severity_is_high: } } - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high import ( defender_ensure_notify_alerts_severity_is_high, @@ -112,8 +123,9 @@ class Test_defender_ensure_notify_alerts_severity_is_high: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Security/securityContacts/default": SecurityContacts( resource_id=f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Security/securityContacts/default", + name="default", emails="", phone="", alert_notifications_minimal_severity="", @@ -124,12 +136,15 @@ class Test_defender_ensure_notify_alerts_severity_is_high: } } - with mock.patch( - "prowler.providers.common.provider.Provider.get_global_provider", - return_value=set_mocked_azure_provider(), - ), mock.patch( - "prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high.defender_client", - new=defender_client, + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high.defender_client", + new=defender_client, + ), ): from prowler.providers.azure.services.defender.defender_ensure_notify_alerts_severity_is_high.defender_ensure_notify_alerts_severity_is_high import ( defender_ensure_notify_alerts_severity_is_high, diff --git a/tests/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners_test.py b/tests/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners_test.py index 3e8da46d8c..c33dab2788 100644 --- a/tests/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners_test.py +++ b/tests/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners_test.py @@ -33,8 +33,9 @@ class Test_defender_ensure_notify_emails_to_owners: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="", phone="", alert_notifications_minimal_severity="High", @@ -73,8 +74,9 @@ class Test_defender_ensure_notify_emails_to_owners: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="", phone="", alert_notifications_minimal_severity="High", @@ -113,8 +115,9 @@ class Test_defender_ensure_notify_emails_to_owners: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + resource_id: SecurityContacts( resource_id=resource_id, + name="default", emails="test@test.es", phone="", alert_notifications_minimal_severity="High", @@ -152,8 +155,9 @@ class Test_defender_ensure_notify_emails_to_owners: defender_client = mock.MagicMock defender_client.security_contacts = { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Security/securityContacts/default": SecurityContacts( resource_id=f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Security/securityContacts/default", + name="default", emails="", phone="", alert_notifications_minimal_severity="", diff --git a/tests/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled_test.py b/tests/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled_test.py index 4df1f366d1..d548095d8e 100644 --- a/tests/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled_test.py +++ b/tests/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled_test.py @@ -59,7 +59,7 @@ class Test_defender_ensure_wdatp_is_enabled: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Microsoft Defender for Endpoint integration is disabeld for subscription {AZURE_SUBSCRIPTION_ID}." + == f"Microsoft Defender for Endpoint integration is disabled for subscription {AZURE_SUBSCRIPTION_ID}." ) assert result[0].subscription == AZURE_SUBSCRIPTION_ID assert result[0].resource_name == "WDATP" diff --git a/tests/providers/azure/services/defender/defender_service_test.py b/tests/providers/azure/services/defender/defender_service_test.py index 82c40e3c85..8fb0437338 100644 --- a/tests/providers/azure/services/defender/defender_service_test.py +++ b/tests/providers/azure/services/defender/defender_service_test.py @@ -57,8 +57,9 @@ def mock_defender_get_assessments(_): def mock_defender_get_security_contacts(_): return { AZURE_SUBSCRIPTION_ID: { - "default": SecurityContacts( + "/subscriptions/resource_id": SecurityContacts( resource_id="/subscriptions/resource_id", + name="default", emails="user@user.com, test@test.es", phone="666666666", alert_notifications_minimal_severity="High", @@ -86,8 +87,9 @@ def mock_defender_get_settings(_): def mock_defender_get_iot_security_solutions(_): return { AZURE_SUBSCRIPTION_ID: { - "iot_sec_solution": IoTSecuritySolution( + "/subscriptions/resource_id": IoTSecuritySolution( resource_id="/subscriptions/resource_id", + name="iot_sec_solution", status="Enabled", ) } @@ -211,35 +213,47 @@ class Test_Defender_Service: defender = Defender(set_mocked_azure_provider()) assert len(defender.security_contacts) == 1 assert ( - defender.security_contacts[AZURE_SUBSCRIPTION_ID]["default"].resource_id + defender.security_contacts[AZURE_SUBSCRIPTION_ID][ + "/subscriptions/resource_id" + ].resource_id == "/subscriptions/resource_id" ) assert ( - defender.security_contacts[AZURE_SUBSCRIPTION_ID]["default"].emails + defender.security_contacts[AZURE_SUBSCRIPTION_ID][ + "/subscriptions/resource_id" + ].name + == "default" + ) + assert ( + defender.security_contacts[AZURE_SUBSCRIPTION_ID][ + "/subscriptions/resource_id" + ].emails == "user@user.com, test@test.es" ) assert ( - defender.security_contacts[AZURE_SUBSCRIPTION_ID]["default"].phone + defender.security_contacts[AZURE_SUBSCRIPTION_ID][ + "/subscriptions/resource_id" + ].phone == "666666666" ) assert ( defender.security_contacts[AZURE_SUBSCRIPTION_ID][ - "default" + "/subscriptions/resource_id" ].alert_notifications_minimal_severity == "High" ) assert ( defender.security_contacts[AZURE_SUBSCRIPTION_ID][ - "default" + "/subscriptions/resource_id" ].alert_notifications_state == "On" ) assert defender.security_contacts[AZURE_SUBSCRIPTION_ID][ - "default" + "/subscriptions/resource_id" ].notified_roles == ["Owner", "Contributor"] assert ( defender.security_contacts[AZURE_SUBSCRIPTION_ID][ - "default" + "/subscriptions/resource_id" ].notified_roles_state == "On" ) @@ -249,13 +263,19 @@ class Test_Defender_Service: assert len(defender.iot_security_solutions) == 1 assert ( defender.iot_security_solutions[AZURE_SUBSCRIPTION_ID][ - "iot_sec_solution" + "/subscriptions/resource_id" ].resource_id == "/subscriptions/resource_id" ) assert ( defender.iot_security_solutions[AZURE_SUBSCRIPTION_ID][ - "iot_sec_solution" + "/subscriptions/resource_id" + ].name + == "iot_sec_solution" + ) + assert ( + defender.iot_security_solutions[AZURE_SUBSCRIPTION_ID][ + "/subscriptions/resource_id" ].status == "Enabled" )