fix(defender): Manage 404 exception for "default" security contacts (#3373)

This commit is contained in:
Rubén De la Torre Vico
2024-02-07 13:38:20 +01:00
committed by GitHub
parent 740e829e4f
commit a50d093679
4 changed files with 141 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
from datetime import timedelta
from azure.core.exceptions import HttpResponseError
from azure.mgmt.security import SecurityCenter
from pydantic import BaseModel
@@ -121,9 +122,9 @@ class Defender(AzureService):
security_contacts = {}
for subscription_name, client in self.clients.items():
try:
security_contacts.update({subscription_name: {}})
# 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: SecurityContacts(
@@ -137,6 +138,25 @@ class Defender(AzureService):
)
}
)
except HttpResponseError as error:
if error.status_code == 404:
security_contacts[subscription_name].update(
{
"default": SecurityContacts(
resource_id=f"/subscriptions/{self.subscriptions[subscription_name]}/providers/Microsoft.Security/securityContacts/default",
emails="",
phone="",
alert_notifications_minimal_severity="",
alert_notifications_state="",
notified_roles=[""],
notified_roles_state="",
)
}
)
else:
logger.error(
f"Subscription name: {subscription_name} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
logger.error(
f"Subscription name: {subscription_name} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"

View File

@@ -6,7 +6,7 @@ from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_additional_email_configured_with_a_security_contact:
def test_defender_no_notify_emails(self):
def test_defender_no_subscriptions(self):
defender_client = mock.MagicMock
defender_client.security_contacts = {}
@@ -206,3 +206,42 @@ class Test_defender_additional_email_configured_with_a_security_contact:
assert result[0].subscription == AZURE_SUBSCRIPTION
assert result[0].resource_name == "default"
assert result[0].resource_id == resource_id
def test_defender_default_security_contact_not_found(self):
defender_client = mock.MagicMock
defender_client.security_contacts = {
AZURE_SUBSCRIPTION: {
"default": SecurityContacts(
resource_id=f"/subscriptions/{AZURE_SUBSCRIPTION}/providers/Microsoft.Security/securityContacts/default",
emails="",
phone="",
alert_notifications_minimal_severity="",
alert_notifications_state="",
notified_roles=[""],
notified_roles_state="",
)
}
}
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_SUBSCRIPTION}."
)
assert result[0].subscription == AZURE_SUBSCRIPTION
assert result[0].resource_name == "default"
assert (
result[0].resource_id
== f"/subscriptions/{AZURE_SUBSCRIPTION}/providers/Microsoft.Security/securityContacts/default"
)

View File

@@ -6,7 +6,7 @@ from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_notify_alerts_severity_is_high:
def test_defender_no_severity_alerts(self):
def test_defender_no_subscriptions(self):
defender_client = mock.MagicMock
defender_client.security_contacts = {}
@@ -95,3 +95,42 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
assert result[0].subscription == AZURE_SUBSCRIPTION
assert result[0].resource_name == "default"
assert result[0].resource_id == resource_id
def test_defender_default_security_contact_not_found(self):
defender_client = mock.MagicMock
defender_client.security_contacts = {
AZURE_SUBSCRIPTION: {
"default": SecurityContacts(
resource_id=f"/subscriptions/{AZURE_SUBSCRIPTION}/providers/Microsoft.Security/securityContacts/default",
emails="",
phone="",
alert_notifications_minimal_severity="",
alert_notifications_state="",
notified_roles=[""],
notified_roles_state="",
)
}
}
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_SUBSCRIPTION}."
)
assert result[0].subscription == AZURE_SUBSCRIPTION
assert result[0].resource_name == "default"
assert (
result[0].resource_id
== f"/subscriptions/{AZURE_SUBSCRIPTION}/providers/Microsoft.Security/securityContacts/default"
)

View File

@@ -6,7 +6,7 @@ from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_notify_emails_to_owners:
def test_defender_no_notify_emails(self):
def test_defender_no_subscriptions(self):
defender_client = mock.MagicMock
defender_client.security_contacts = {}
@@ -132,3 +132,42 @@ class Test_defender_ensure_notify_emails_to_owners:
assert result[0].subscription == AZURE_SUBSCRIPTION
assert result[0].resource_name == "default"
assert result[0].resource_id == resource_id
def test_defender_default_security_contact_not_found(self):
defender_client = mock.MagicMock
defender_client.security_contacts = {
AZURE_SUBSCRIPTION: {
"default": SecurityContacts(
resource_id=f"/subscriptions/{AZURE_SUBSCRIPTION}/providers/Microsoft.Security/securityContacts/default",
emails="",
phone="",
alert_notifications_minimal_severity="",
alert_notifications_state="",
notified_roles=[""],
notified_roles_state="",
)
}
}
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_SUBSCRIPTION}."
)
assert result[0].subscription == AZURE_SUBSCRIPTION
assert result[0].resource_name == "default"
assert (
result[0].resource_id
== f"/subscriptions/{AZURE_SUBSCRIPTION}/providers/Microsoft.Security/securityContacts/default"
)