mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
feat(azure): Defender checks related to security contacts and notifications (#3344)
This commit is contained in:
committed by
GitHub
parent
c6e8a0b6d3
commit
c795d76fe9
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "defender_additional_email_configured_with_a_security_contact",
|
||||
"CheckTitle": "Ensure 'Additional email addresses' is Configured with a Security Contact Email",
|
||||
"CheckType": [],
|
||||
"ServiceName": "defender",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AzureEmailNotifications",
|
||||
"Description": "Microsoft Defender for Cloud emails the subscription owners whenever a high-severity alert is triggered for their subscription. You should provide a security contact email address as an additional email address.",
|
||||
"Risk": "Microsoft Defender for Cloud emails the Subscription Owner to notify them about security alerts. Adding your Security Contact's email address to the 'Additional email addresses' field ensures that your organization's Security Team is included in these alerts. This ensures that the proper people are aware of any potential compromise in order to mitigate the risk in a timely fashion.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/security-center/security-center-provide-security-contact-details",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/security-contact-email.html",
|
||||
"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",
|
||||
"Url": "https://learn.microsoft.com/en-us/rest/api/defenderforcloud/security-contacts/list?view=rest-defenderforcloud-2020-01-01-preview&tabs=HTTP"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import re
|
||||
|
||||
from prowler.lib.check.models import Check, Check_Report_Azure
|
||||
from prowler.providers.azure.services.defender.defender_client import defender_client
|
||||
|
||||
|
||||
class defender_additional_email_configured_with_a_security_contact(Check):
|
||||
def execute(self) -> Check_Report_Azure:
|
||||
findings = []
|
||||
|
||||
for (
|
||||
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"
|
||||
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 susbscription {subscription_name}."
|
||||
|
||||
emails = contact_info.emails.split(";")
|
||||
|
||||
for email in emails:
|
||||
if re.fullmatch(
|
||||
r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b", email
|
||||
):
|
||||
break
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"There is not another correct email configured for susbscription {subscription_name}."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "defender_ensure_notify_alerts_severity_is_high",
|
||||
"CheckTitle": "Ensure That 'Notify about alerts with the following severity' is Set to 'High'",
|
||||
"CheckType": [],
|
||||
"ServiceName": "defender",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "high",
|
||||
"ResourceType": "AzureEmailNotifications",
|
||||
"Description": "Microsoft Defender for Cloud emails the subscription owners whenever a high-severity alert is triggered for their subscription. You should provide a security contact email address as an additional email address.",
|
||||
"Risk": "Microsoft Defender for Cloud emails the Subscription Owner to notify them about security alerts. Adding your Security Contact's email address to the 'Additional email addresses' field ensures that your organization's Security Team is included in these alerts. This ensures that the proper people are aware of any potential compromise in order to mitigate the risk in a timely fashion.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/security-center/security-center-provide-security-contact-details",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/enable-high-severity-email-notifications.html",
|
||||
"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",
|
||||
"Url": "https://docs.microsoft.com/en-us/rest/api/securitycenter/securitycontacts/list"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
from prowler.lib.check.models import Check, Check_Report_Azure
|
||||
from prowler.providers.azure.services.defender.defender_client import defender_client
|
||||
|
||||
|
||||
class defender_ensure_notify_alerts_severity_is_high(Check):
|
||||
def execute(self) -> Check_Report_Azure:
|
||||
findings = []
|
||||
|
||||
for (
|
||||
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"
|
||||
report.subscription = subscription_name
|
||||
report.resource_name = contact_name
|
||||
report.resource_id = contact_info.resource_id
|
||||
report.status_extended = f"Notifiy alerts are enabled for severity high in susbscription {subscription_name}."
|
||||
|
||||
if contact_info.alert_notifications_minimal_severity != "High":
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"Notifiy alerts are not enabled for severity high in susbscription {subscription_name}."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "defender_ensure_notify_emails_to_owners",
|
||||
"CheckTitle": "Ensure That 'All users with the following roles' is set to 'Owner'",
|
||||
"CheckType": [],
|
||||
"ServiceName": "defender",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AzureEmailNotifications",
|
||||
"Description": "Enable security alert emails to subscription owners.",
|
||||
"Risk": "Enabling security alert emails to subscription owners ensures that they receive security alert emails from Microsoft. This ensures that they are aware of any potential security issues and can mitigate the risk in a timely fashion.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/security-center/security-center-provide-security-contact-details",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/SecurityCenter/email-to-subscription-owners.html",
|
||||
"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. In the drop down of the All users with the following roles field select Owner 7. Click Save",
|
||||
"Url": "https://docs.microsoft.com/en-us/rest/api/securitycenter/securitycontacts/list"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
from prowler.lib.check.models import Check, Check_Report_Azure
|
||||
from prowler.providers.azure.services.defender.defender_client import defender_client
|
||||
|
||||
|
||||
class defender_ensure_notify_emails_to_owners(Check):
|
||||
def execute(self) -> Check_Report_Azure:
|
||||
findings = []
|
||||
|
||||
for (
|
||||
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"
|
||||
report.subscription = subscription_name
|
||||
report.resource_name = contact_name
|
||||
report.resource_id = contact_info.resource_id
|
||||
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
|
||||
):
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"The Owner role is not notified for subscription {subscription_name}."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -15,6 +15,7 @@ class Defender(AzureService):
|
||||
self.pricings = self.__get_pricings__()
|
||||
self.auto_provisioning_settings = self.__get_auto_provisioning_settings__()
|
||||
self.assessments = self.__get_assessments__()
|
||||
self.security_contacts = self.__get_security_contacts__()
|
||||
|
||||
def __get_pricings__(self):
|
||||
logger.info("Defender - Getting pricings...")
|
||||
@@ -89,6 +90,33 @@ class Defender(AzureService):
|
||||
)
|
||||
return assessments
|
||||
|
||||
def __get_security_contacts__(self):
|
||||
logger.info("Defender - Getting security contacts...")
|
||||
security_contacts = {}
|
||||
for subscription_name, client in self.clients.items():
|
||||
try:
|
||||
# TODO: List all security contacts. For now, the list method is not working.
|
||||
security_contact_default = client.security_contacts.get("default")
|
||||
security_contacts.update({subscription_name: {}})
|
||||
security_contacts[subscription_name].update(
|
||||
{
|
||||
security_contact_default.name: Defender_Security_Contacts(
|
||||
resource_id=security_contact_default.id,
|
||||
emails=security_contact_default.emails,
|
||||
phone=security_contact_default.phone,
|
||||
alert_notifications_minimal_severity=security_contact_default.alert_notifications.minimal_severity,
|
||||
alert_notifications_state=security_contact_default.alert_notifications.state,
|
||||
notified_roles=security_contact_default.notifications_by_role.roles,
|
||||
notified_roles_state=security_contact_default.notifications_by_role.state,
|
||||
)
|
||||
}
|
||||
)
|
||||
except Exception as error:
|
||||
logger.error(
|
||||
f"Subscription name: {subscription_name} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
return security_contacts
|
||||
|
||||
|
||||
class Defender_Pricing(BaseModel):
|
||||
resource_id: str
|
||||
@@ -107,3 +135,13 @@ class Defender_Assessments(BaseModel):
|
||||
resource_id: str
|
||||
resource_name: str
|
||||
status: str
|
||||
|
||||
|
||||
class Defender_Security_Contacts(BaseModel):
|
||||
resource_id: str
|
||||
emails: str
|
||||
phone: str
|
||||
alert_notifications_minimal_severity: str
|
||||
alert_notifications_state: str
|
||||
notified_roles: list[str]
|
||||
notified_roles_state: str
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import (
|
||||
Defender_Security_Contacts,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import AZURE_SUSCRIPTION
|
||||
|
||||
|
||||
class Test_defender_additional_email_configured_with_a_security_contact:
|
||||
def test_defender_no_notify_emails(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact import (
|
||||
defender_additional_email_configured_with_a_security_contact,
|
||||
)
|
||||
|
||||
check = defender_additional_email_configured_with_a_security_contact()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_defender_no_additional_emails(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact import (
|
||||
defender_additional_email_configured_with_a_security_contact,
|
||||
)
|
||||
|
||||
check = defender_additional_email_configured_with_a_security_contact()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There is not another correct email configured for susbscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
def test_defender_additional_email_bad_format(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="bad_email",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact import (
|
||||
defender_additional_email_configured_with_a_security_contact,
|
||||
)
|
||||
|
||||
check = defender_additional_email_configured_with_a_security_contact()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There is not another correct email configured for susbscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
def test_defender_additional_email_bad_separator(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="test@test.es, test@test.email.com",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact import (
|
||||
defender_additional_email_configured_with_a_security_contact,
|
||||
)
|
||||
|
||||
check = defender_additional_email_configured_with_a_security_contact()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There is not another correct email configured for susbscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
def test_defender_additional_email_good_format(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="test@test.com",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact import (
|
||||
defender_additional_email_configured_with_a_security_contact,
|
||||
)
|
||||
|
||||
check = defender_additional_email_configured_with_a_security_contact()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There is another correct email configured for susbscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
def test_defender_additional_email_good_format_multiple_subdomains(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="test@test.mail.es; bad_mail",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_additional_email_configured_with_a_security_contact.defender_additional_email_configured_with_a_security_contact import (
|
||||
defender_additional_email_configured_with_a_security_contact,
|
||||
)
|
||||
|
||||
check = defender_additional_email_configured_with_a_security_contact()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There is another correct email configured for susbscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
@@ -0,0 +1,99 @@
|
||||
from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import (
|
||||
Defender_Security_Contacts,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import AZURE_SUSCRIPTION
|
||||
|
||||
|
||||
class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
def test_defender_no_severity_alerts(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {}
|
||||
|
||||
with 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,
|
||||
)
|
||||
|
||||
check = defender_ensure_notify_alerts_severity_is_high()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_defender_severity_alerts_low(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="Low",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with 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,
|
||||
)
|
||||
|
||||
check = defender_ensure_notify_alerts_severity_is_high()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Notifiy alerts are not enabled for severity high in susbscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
def test_defender_severity_alerts_high(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with 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,
|
||||
)
|
||||
|
||||
check = defender_ensure_notify_alerts_severity_is_high()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Notifiy alerts are enabled for severity high in susbscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
@@ -0,0 +1,136 @@
|
||||
from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import (
|
||||
Defender_Security_Contacts,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import AZURE_SUSCRIPTION
|
||||
|
||||
|
||||
class Test_defender_ensure_notify_emails_to_owners:
|
||||
def test_defender_no_notify_emails(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_ensure_notify_emails_to_owners.defender_ensure_notify_emails_to_owners.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_ensure_notify_emails_to_owners.defender_ensure_notify_emails_to_owners import (
|
||||
defender_ensure_notify_emails_to_owners,
|
||||
)
|
||||
|
||||
check = defender_ensure_notify_emails_to_owners()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_defender_no_notify_emails_to_owners(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_ensure_notify_emails_to_owners.defender_ensure_notify_emails_to_owners.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_ensure_notify_emails_to_owners.defender_ensure_notify_emails_to_owners import (
|
||||
defender_ensure_notify_emails_to_owners,
|
||||
)
|
||||
|
||||
check = defender_ensure_notify_emails_to_owners()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"The Owner role is not notified for subscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
def test_defender_notify_emails_to_owners_off(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Owner", "Contributor"],
|
||||
notified_roles_state="Off",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_ensure_notify_emails_to_owners.defender_ensure_notify_emails_to_owners.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_ensure_notify_emails_to_owners.defender_ensure_notify_emails_to_owners import (
|
||||
defender_ensure_notify_emails_to_owners,
|
||||
)
|
||||
|
||||
check = defender_ensure_notify_emails_to_owners()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"The Owner role is not notified for subscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
def test_defender_notify_emails_to_owners(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.security_contacts = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id=resource_id,
|
||||
emails="test@test.es",
|
||||
phone="",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Owner", "Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_ensure_notify_emails_to_owners.defender_ensure_notify_emails_to_owners.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
from prowler.providers.azure.services.defender.defender_ensure_notify_emails_to_owners.defender_ensure_notify_emails_to_owners import (
|
||||
defender_ensure_notify_emails_to_owners,
|
||||
)
|
||||
|
||||
check = defender_ensure_notify_emails_to_owners()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"The Owner role is notified for subscription {AZURE_SUSCRIPTION}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "default"
|
||||
assert result[0].resource_id == resource_id
|
||||
@@ -6,6 +6,7 @@ from prowler.providers.azure.services.defender.defender_service import (
|
||||
Defender,
|
||||
Defender_Assessments,
|
||||
Defender_Pricing,
|
||||
Defender_Security_Contacts,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUSCRIPTION,
|
||||
@@ -50,6 +51,22 @@ def mock_defender_get_assessments(_):
|
||||
}
|
||||
|
||||
|
||||
def mock_defender_get_security_contacts(_):
|
||||
return {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"default": Defender_Security_Contacts(
|
||||
resource_id="/subscriptions/resource_id",
|
||||
emails="user@user.com, test@test.es",
|
||||
phone="666666666",
|
||||
alert_notifications_minimal_severity="High",
|
||||
alert_notifications_state="On",
|
||||
notified_roles=["Owner", "Contributor"],
|
||||
notified_roles_state="On",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@patch(
|
||||
"prowler.providers.azure.services.defender.defender_service.Defender.__get_pricings__",
|
||||
new=mock_defender_get_pricings,
|
||||
@@ -62,6 +79,10 @@ def mock_defender_get_assessments(_):
|
||||
"prowler.providers.azure.services.defender.defender_service.Defender.__get_assessments__",
|
||||
new=mock_defender_get_assessments,
|
||||
)
|
||||
@patch(
|
||||
"prowler.providers.azure.services.defender.defender_service.Defender.__get_security_contacts__",
|
||||
new=mock_defender_get_security_contacts,
|
||||
)
|
||||
class Test_Defender_Service:
|
||||
def test__get_client__(self):
|
||||
defender = Defender(set_mocked_azure_audit_info())
|
||||
@@ -129,3 +150,40 @@ class Test_Defender_Service:
|
||||
== "default"
|
||||
)
|
||||
assert defender.assessments[AZURE_SUSCRIPTION]["default"].status == "Healthy"
|
||||
|
||||
def test__get_security_contacts__(self):
|
||||
defender = Defender(set_mocked_azure_audit_info())
|
||||
assert len(defender.security_contacts) == 1
|
||||
assert (
|
||||
defender.security_contacts[AZURE_SUSCRIPTION]["default"].resource_id
|
||||
== "/subscriptions/resource_id"
|
||||
)
|
||||
assert (
|
||||
defender.security_contacts[AZURE_SUSCRIPTION]["default"].emails
|
||||
== "user@user.com, test@test.es"
|
||||
)
|
||||
assert (
|
||||
defender.security_contacts[AZURE_SUSCRIPTION]["default"].phone
|
||||
== "666666666"
|
||||
)
|
||||
assert (
|
||||
defender.security_contacts[AZURE_SUSCRIPTION][
|
||||
"default"
|
||||
].alert_notifications_minimal_severity
|
||||
== "High"
|
||||
)
|
||||
assert (
|
||||
defender.security_contacts[AZURE_SUSCRIPTION][
|
||||
"default"
|
||||
].alert_notifications_state
|
||||
== "On"
|
||||
)
|
||||
assert defender.security_contacts[AZURE_SUSCRIPTION][
|
||||
"default"
|
||||
].notified_roles == ["Owner", "Contributor"]
|
||||
assert (
|
||||
defender.security_contacts[AZURE_SUSCRIPTION][
|
||||
"default"
|
||||
].notified_roles_state
|
||||
== "On"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user