feat(azure): New check storage_ensure_soft_delete_is_enabled (#3334)

This commit is contained in:
Pedro Martín
2024-01-31 13:29:20 +01:00
committed by GitHub
parent 622bce9c52
commit 6e991107e7
16 changed files with 436 additions and 2 deletions

View File

@@ -54,6 +54,13 @@ expected_packages = [
name="prowler.providers.azure.services.storage.storage_ensure_private_endpoints_in_storage_accounts.storage_ensure_private_endpoints_in_storage_accounts",
ispkg=False,
),
ModuleInfo(
module_finder=FileFinder(
"/root_dir/prowler/providers/azure/services/storage/storage_ensure_soft_delete_is_enabled"
),
name="prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled",
ispkg=False,
),
ModuleInfo(
module_finder=FileFinder("/root_dir/prowler/providers/azure/services/storage"),
name="prowler.providers.azure.services.storage.storage_ensure_encryption_with_customer_managed_keys",
@@ -96,6 +103,13 @@ def mock_list_modules(*_):
name="prowler.providers.azure.services.storage.storage_ensure_private_endpoints_in_storage_accounts.storage_ensure_private_endpoints_in_storage_accounts",
ispkg=False,
),
ModuleInfo(
module_finder=FileFinder(
"/root_dir/prowler/providers/azure/services/storage/storage_ensure_soft_delete_is_enabled"
),
name="prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled",
ispkg=False,
),
ModuleInfo(
module_finder=FileFinder(
"/root_dir/prowler/providers/azure/services/storage"
@@ -483,6 +497,10 @@ class Test_Check:
"storage_ensure_private_endpoints_in_storage_accounts",
"/root_dir/prowler/providers/azure/services/storage/storage_ensure_private_endpoints_in_storage_accounts",
),
(
"storage_ensure_soft_delete_is_enabled",
"/root_dir/prowler/providers/azure/services/storage/storage_ensure_soft_delete_is_enabled",
),
(
"storage_ensure_encryption_with_customer_managed_keys",
"/root_dir/prowler/providers/azure/services/storage/storage_ensure_encryption_with_customer_managed_keys",

View File

@@ -32,6 +32,7 @@ class Test_storage_blob_public_access_level_is_disabled:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=True,
@@ -73,6 +74,7 @@ class Test_storage_blob_public_access_level_is_disabled:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=False,

View File

@@ -34,6 +34,7 @@ class Test_storage_default_network_access_rule_is_denied:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -75,6 +76,7 @@ class Test_storage_default_network_access_rule_is_denied:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,

View File

@@ -34,6 +34,7 @@ class Test_storage_ensure_azure_services_are_trusted_to_access_is_enabled:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -75,6 +76,7 @@ class Test_storage_ensure_azure_services_are_trusted_to_access_is_enabled:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,

View File

@@ -32,6 +32,7 @@ class Test_storage_ensure_encryption_with_customer_managed_keys:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -73,6 +74,7 @@ class Test_storage_ensure_encryption_with_customer_managed_keys:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,

View File

@@ -32,6 +32,7 @@ class Test_storage_ensure_minimum_tls_version_12:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -73,6 +74,7 @@ class Test_storage_ensure_minimum_tls_version_12:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,

View File

@@ -36,6 +36,7 @@ class Test_storage_ensure_private_endpoints_in_storage_accounts:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -79,6 +80,7 @@ class Test_storage_ensure_private_endpoints_in_storage_accounts:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,

View File

@@ -0,0 +1,169 @@
from unittest import mock
from uuid import uuid4
from azure.mgmt.storage.v2023_01_01.models import DeleteRetentionPolicy
from prowler.providers.azure.services.storage.storage_service import (
Blob_Properties,
Storage_Account,
)
AZURE_SUSCRIPTION = str(uuid4())
class Test_storage_ensure_soft_delete_is_enabled:
def test_storage_no_storage_accounts(self):
storage_client = mock.MagicMock
storage_client.storage_accounts = {}
with mock.patch(
"prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled.storage_client",
new=storage_client,
):
from prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled import (
storage_ensure_soft_delete_is_enabled,
)
check = storage_ensure_soft_delete_is_enabled()
result = check.execute()
assert len(result) == 0
def test_storage_no_blob_properties(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account"
storage_client = mock.MagicMock
storage_account_blob_properties = None
storage_client.storage_accounts = {
AZURE_SUSCRIPTION: [
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
network_rule_set=None,
encryption_type="None",
minimum_tls_version=None,
key_expiration_period_in_days=None,
private_endpoint_connections=None,
blob_properties=storage_account_blob_properties,
)
]
}
with mock.patch(
"prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled.storage_client",
new=storage_client,
):
from prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled import (
storage_ensure_soft_delete_is_enabled,
)
check = storage_ensure_soft_delete_is_enabled()
result = check.execute()
assert len(result) == 0
def test_storage_ensure_soft_delete_is_disabled(
self,
):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account"
storage_client = mock.MagicMock
storage_account_blob_properties = Blob_Properties(
id=None,
name=None,
type=None,
default_service_version=None,
container_delete_retention_policy=DeleteRetentionPolicy(enabled=False),
)
storage_client.storage_accounts = {
AZURE_SUSCRIPTION: [
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
network_rule_set=None,
encryption_type="None",
minimum_tls_version=None,
key_expiration_period_in_days=None,
private_endpoint_connections=None,
blob_properties=storage_account_blob_properties,
)
]
}
with mock.patch(
"prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled.storage_client",
new=storage_client,
):
from prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled import (
storage_ensure_soft_delete_is_enabled,
)
check = storage_ensure_soft_delete_is_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Storage account {storage_account_name} from subscription {AZURE_SUSCRIPTION} has soft delete disabled."
)
assert result[0].subscription == AZURE_SUSCRIPTION
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id
def test_storage_ensure_soft_delete_is_enabled(
self,
):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account"
storage_client = mock.MagicMock
storage_account_blob_properties = Blob_Properties(
id=None,
name=None,
type=None,
default_service_version=None,
container_delete_retention_policy=DeleteRetentionPolicy(enabled=True),
)
storage_client.storage_accounts = {
AZURE_SUSCRIPTION: [
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
network_rule_set=None,
encryption_type="None",
minimum_tls_version=None,
key_expiration_period_in_days=None,
private_endpoint_connections=None,
blob_properties=storage_account_blob_properties,
)
]
}
with mock.patch(
"prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled.storage_client",
new=storage_client,
):
from prowler.providers.azure.services.storage.storage_ensure_soft_delete_is_enabled.storage_ensure_soft_delete_is_enabled import (
storage_ensure_soft_delete_is_enabled,
)
check = storage_ensure_soft_delete_is_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Storage account {storage_account_name} from subscription {AZURE_SUSCRIPTION} has soft delete enabled."
)
assert result[0].subscription == AZURE_SUSCRIPTION
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id

View File

@@ -32,6 +32,7 @@ class Test_storage_infrastructure_encryption_is_enabled:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -73,6 +74,7 @@ class Test_storage_infrastructure_encryption_is_enabled:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=True,
allow_blob_public_access=None,

View File

@@ -32,6 +32,7 @@ class Test_storage_key_rotation_90_dayss:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -74,6 +75,7 @@ class Test_storage_key_rotation_90_dayss:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -115,6 +117,7 @@ class Test_storage_key_rotation_90_dayss:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,

View File

@@ -32,6 +32,7 @@ class Test_storage_secure_transfer_required_is_enabled:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
@@ -73,6 +74,7 @@ class Test_storage_secure_transfer_required_is_enabled:
Storage_Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name=None,
enable_https_traffic_only=True,
infrastructure_encryption=True,
allow_blob_public_access=None,

View File

@@ -0,0 +1,126 @@
from unittest.mock import patch
from prowler.providers.azure.services.storage.storage_service import (
Blob_Properties,
Storage,
Storage_Account,
)
from tests.providers.azure.azure_fixtures import (
AZURE_SUSCRIPTION,
set_mocked_azure_audit_info,
)
def mock_storage_get_storage_accounts(_):
blob_properties = Blob_Properties(
id="id",
name="name",
type="type",
default_service_version=None,
container_delete_retention_policy=None,
)
return {
AZURE_SUSCRIPTION: [
Storage_Account(
id="id",
name="name",
resouce_group_name=None,
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=None,
network_rule_set=None,
encryption_type="None",
minimum_tls_version=None,
key_expiration_period_in_days=None,
private_endpoint_connections=None,
blob_properties=blob_properties,
)
]
}
@patch(
"prowler.providers.azure.services.storage.storage_service.Storage.__get_storage_accounts__",
new=mock_storage_get_storage_accounts,
)
class Test_Storage_Service:
def test__get_client__(self):
storage = Storage(set_mocked_azure_audit_info())
assert (
storage.clients[AZURE_SUSCRIPTION].__class__.__name__
== "StorageManagementClient"
)
def test__get_storage_accounts__(self):
storage = Storage(set_mocked_azure_audit_info())
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].__class__.__name__
== "Storage_Account"
)
assert storage.storage_accounts[AZURE_SUSCRIPTION][0].id == "id"
assert storage.storage_accounts[AZURE_SUSCRIPTION][0].name == "name"
assert storage.storage_accounts[AZURE_SUSCRIPTION][0].resouce_group_name is None
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].enable_https_traffic_only
is False
)
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].infrastructure_encryption
is False
)
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].allow_blob_public_access
is None
)
assert storage.storage_accounts[AZURE_SUSCRIPTION][0].network_rule_set is None
assert storage.storage_accounts[AZURE_SUSCRIPTION][0].encryption_type == "None"
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].minimum_tls_version is None
)
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].key_expiration_period_in_days
is None
)
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].private_endpoint_connections
is None
)
assert storage.storage_accounts[AZURE_SUSCRIPTION][
0
].blob_properties == Blob_Properties(
id="id",
name="name",
type="type",
default_service_version=None,
container_delete_retention_policy=None,
)
def test__get_blob_properties__(self):
storage = Storage(set_mocked_azure_audit_info())
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][
0
].blob_properties.__class__.__name__
== "Blob_Properties"
)
assert storage.storage_accounts[AZURE_SUSCRIPTION][0].blob_properties.id == "id"
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].blob_properties.name
== "name"
)
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][0].blob_properties.type
== "type"
)
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][
0
].blob_properties.default_service_version
is None
)
assert (
storage.storage_accounts[AZURE_SUSCRIPTION][
0
].blob_properties.container_delete_retention_policy
is None
)