fix(storage): false positives in storage_geo_redundant_enabled (#8506)

Co-authored-by: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com>
This commit is contained in:
Prowler Bot
2025-08-12 12:38:41 +02:00
committed by GitHub
parent a2065bc80b
commit 496d3dbb15
5 changed files with 344 additions and 31 deletions
+1
View File
@@ -18,6 +18,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- Order requirements by ID in Prowler ThreatScore AWS compliance framework [(#8495)](https://github.com/prowler-cloud/prowler/pull/8495)
- Add explicit resource name to GCP and Azure Defender checks [(#8352)](https://github.com/prowler-cloud/prowler/pull/8352)
- Validation errors in Azure and M365 providers [(#8353)](https://github.com/prowler-cloud/prowler/pull/8353)
- Azure `storage_geo_redundant_enabled` check false positives [(#8504)](https://github.com/prowler-cloud/prowler/pull/8504)
---
@@ -1,6 +1,5 @@
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.storage.storage_client import storage_client
from prowler.providers.azure.services.storage.storage_service import ReplicationSettings
class storage_geo_redundant_enabled(Check):
@@ -27,14 +26,16 @@ class storage_geo_redundant_enabled(Check):
report.subscription = subscription
if (
storage_account.replication_settings
== ReplicationSettings.STANDARD_GRS
storage_account.replication_settings == "Standard_GRS"
or storage_account.replication_settings == "Standard_GZRS"
or storage_account.replication_settings == "Standard_RAGRS"
or storage_account.replication_settings == "Standard_RAGZRS"
):
report.status = "PASS"
report.status_extended = f"Storage account {storage_account.name} from subscription {subscription} has Geo-redundant storage (GRS) enabled."
report.status_extended = f"Storage account {storage_account.name} from subscription {subscription} has Geo-redundant storage {storage_account.replication_settings} enabled."
else:
report.status = "FAIL"
report.status_extended = f"Storage account {storage_account.name} from subscription {subscription} does not have Geo-redundant storage (GRS) enabled."
report.status_extended = f"Storage account {storage_account.name} from subscription {subscription} does not have Geo-redundant storage enabled, it has {storage_account.replication_settings} instead."
findings.append(report)
@@ -1,4 +1,3 @@
from enum import Enum
from typing import Optional
from azure.mgmt.storage import StorageManagementClient
@@ -35,7 +34,6 @@ class Storage(AzureService):
key_expiration_period_in_days = int(
storage_account.key_policy.key_expiration_period_in_days
)
replication_settings = ReplicationSettings(storage_account.sku.name)
storage_accounts[subscription].append(
Account(
id=storage_account.id,
@@ -84,7 +82,7 @@ class Storage(AzureService):
False,
)
),
replication_settings=replication_settings,
replication_settings=storage_account.sku.name,
allow_cross_tenant_replication=(
True
if getattr(
@@ -273,17 +271,6 @@ class PrivateEndpointConnection(BaseModel):
type: str
class ReplicationSettings(Enum):
STANDARD_LRS = "Standard_LRS"
STANDARD_GRS = "Standard_GRS"
STANDARD_RAGRS = "Standard_RAGRS"
STANDARD_ZRS = "Standard_ZRS"
PREMIUM_LRS = "Premium_LRS"
PREMIUM_ZRS = "Premium_ZRS"
STANDARD_GZRS = "Standard_GZRS"
STANDARD_RAGZRS = "Standard_RAGZRS"
class SMBProtocolSettings(BaseModel):
channel_encryption: list[str]
supported_versions: list[str]
@@ -310,7 +297,7 @@ class Account(BaseModel):
minimum_tls_version: str
private_endpoint_connections: list[PrivateEndpointConnection]
key_expiration_period_in_days: Optional[int] = None
replication_settings: ReplicationSettings = ReplicationSettings.STANDARD_LRS
replication_settings: str = "Standard_LRS"
allow_cross_tenant_replication: bool = True
allow_shared_key_access: bool = True
blob_properties: Optional[BlobProperties] = None
@@ -4,7 +4,6 @@ from uuid import uuid4
from prowler.providers.azure.services.storage.storage_service import (
Account,
NetworkRuleSet,
ReplicationSettings,
)
from tests.providers.azure.azure_fixtures import (
AZURE_SUBSCRIPTION_ID,
@@ -35,10 +34,11 @@ class Test_storage_geo_redundant_enabled:
result = check.execute()
assert len(result) == 0
def test_storage_geo_redundant_enabled(self):
def test_storage_account_standard_grs_enabled(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account GRS"
storage_client = mock.MagicMock()
replication_setting = "Standard_GRS"
storage_client.storage_accounts = {
AZURE_SUBSCRIPTION_ID: [
Account(
@@ -56,7 +56,7 @@ class Test_storage_geo_redundant_enabled:
private_endpoint_connections=[],
key_expiration_period_in_days=None,
location="westeurope",
replication_settings=ReplicationSettings.STANDARD_GRS,
replication_settings=replication_setting,
)
]
}
@@ -81,17 +81,18 @@ class Test_storage_geo_redundant_enabled:
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Storage account {storage_account_name} from subscription {AZURE_SUBSCRIPTION_ID} has Geo-redundant storage (GRS) enabled."
== f"Storage account {storage_account_name} from subscription {AZURE_SUBSCRIPTION_ID} has Geo-redundant storage {replication_setting} enabled."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id
assert result[0].location == "westeurope"
def test_storage_account_geo_redundant_disabled(self):
def test_storage_account_standard_ragrs_enabled(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account LRS"
storage_account_name = "Test Storage Account RAGRS"
storage_client = mock.MagicMock()
replication_setting = "Standard_RAGRS"
storage_client.storage_accounts = {
AZURE_SUBSCRIPTION_ID: [
Account(
@@ -109,7 +110,169 @@ class Test_storage_geo_redundant_enabled:
private_endpoint_connections=[],
key_expiration_period_in_days=None,
location="westeurope",
replication_settings=ReplicationSettings.STANDARD_LRS,
replication_settings=replication_setting,
)
]
}
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
),
mock.patch(
"prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled.storage_client",
new=storage_client,
),
):
from prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled import (
storage_geo_redundant_enabled,
)
check = storage_geo_redundant_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_SUBSCRIPTION_ID} has Geo-redundant storage {replication_setting} enabled."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id
assert result[0].location == "westeurope"
def test_storage_account_standard_gzrs_enabled(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account GZRS"
storage_client = mock.MagicMock()
replication_setting = "Standard_GZRS"
storage_client.storage_accounts = {
AZURE_SUBSCRIPTION_ID: [
Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name="rg",
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=False,
network_rule_set=NetworkRuleSet(
bypass="AzureServices", default_action="Allow"
),
encryption_type="None",
minimum_tls_version="TLS1_2",
private_endpoint_connections=[],
key_expiration_period_in_days=None,
location="westeurope",
replication_settings=replication_setting,
)
]
}
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
),
mock.patch(
"prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled.storage_client",
new=storage_client,
),
):
from prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled import (
storage_geo_redundant_enabled,
)
check = storage_geo_redundant_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_SUBSCRIPTION_ID} has Geo-redundant storage {replication_setting} enabled."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id
assert result[0].location == "westeurope"
def test_storage_account_standard_ragzrs_enabled(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account RAGZRS"
storage_client = mock.MagicMock()
replication_setting = "Standard_RAGZRS"
storage_client.storage_accounts = {
AZURE_SUBSCRIPTION_ID: [
Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name="rg",
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=False,
network_rule_set=NetworkRuleSet(
bypass="AzureServices", default_action="Allow"
),
encryption_type="None",
minimum_tls_version="TLS1_2",
private_endpoint_connections=[],
key_expiration_period_in_days=None,
location="westeurope",
replication_settings=replication_setting,
)
]
}
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
),
mock.patch(
"prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled.storage_client",
new=storage_client,
),
):
from prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled import (
storage_geo_redundant_enabled,
)
check = storage_geo_redundant_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_SUBSCRIPTION_ID} has Geo-redundant storage {replication_setting} enabled."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id
assert result[0].location == "westeurope"
def test_storage_account_standard_lrs_disabled(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account LRS"
storage_client = mock.MagicMock()
replication_setting = "Standard_LRS"
storage_client.storage_accounts = {
AZURE_SUBSCRIPTION_ID: [
Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name="rg",
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=False,
network_rule_set=NetworkRuleSet(
bypass="AzureServices", default_action="Allow"
),
encryption_type="None",
minimum_tls_version="TLS1_2",
private_endpoint_connections=[],
key_expiration_period_in_days=None,
location="westeurope",
replication_settings=replication_setting,
)
]
}
@@ -134,7 +297,169 @@ class Test_storage_geo_redundant_enabled:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Storage account {storage_account_name} from subscription {AZURE_SUBSCRIPTION_ID} does not have Geo-redundant storage (GRS) enabled."
== f"Storage account {storage_account_name} from subscription {AZURE_SUBSCRIPTION_ID} does not have Geo-redundant storage enabled, it has {replication_setting} instead."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id
assert result[0].location == "westeurope"
def test_storage_account_standard_zrs_disabled(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account ZRS"
storage_client = mock.MagicMock()
replication_setting = "Standard_ZRS"
storage_client.storage_accounts = {
AZURE_SUBSCRIPTION_ID: [
Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name="rg",
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=False,
network_rule_set=NetworkRuleSet(
bypass="AzureServices", default_action="Allow"
),
encryption_type="None",
minimum_tls_version="TLS1_2",
private_endpoint_connections=[],
key_expiration_period_in_days=None,
location="westeurope",
replication_settings=replication_setting,
)
]
}
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
),
mock.patch(
"prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled.storage_client",
new=storage_client,
),
):
from prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled import (
storage_geo_redundant_enabled,
)
check = storage_geo_redundant_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_SUBSCRIPTION_ID} does not have Geo-redundant storage enabled, it has {replication_setting} instead."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id
assert result[0].location == "westeurope"
def test_storage_account_premium_lrs_disabled(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account Premium LRS"
storage_client = mock.MagicMock()
replication_setting = "Premium_LRS"
storage_client.storage_accounts = {
AZURE_SUBSCRIPTION_ID: [
Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name="rg",
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=False,
network_rule_set=NetworkRuleSet(
bypass="AzureServices", default_action="Allow"
),
encryption_type="None",
minimum_tls_version="TLS1_2",
private_endpoint_connections=[],
key_expiration_period_in_days=None,
location="westeurope",
replication_settings=replication_setting,
)
]
}
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
),
mock.patch(
"prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled.storage_client",
new=storage_client,
),
):
from prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled import (
storage_geo_redundant_enabled,
)
check = storage_geo_redundant_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_SUBSCRIPTION_ID} does not have Geo-redundant storage enabled, it has {replication_setting} instead."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == storage_account_name
assert result[0].resource_id == storage_account_id
assert result[0].location == "westeurope"
def test_storage_account_premium_zrs_disabled(self):
storage_account_id = str(uuid4())
storage_account_name = "Test Storage Account Premium ZRS"
storage_client = mock.MagicMock()
replication_setting = "Premium_ZRS"
storage_client.storage_accounts = {
AZURE_SUBSCRIPTION_ID: [
Account(
id=storage_account_id,
name=storage_account_name,
resouce_group_name="rg",
enable_https_traffic_only=False,
infrastructure_encryption=False,
allow_blob_public_access=False,
network_rule_set=NetworkRuleSet(
bypass="AzureServices", default_action="Allow"
),
encryption_type="None",
minimum_tls_version="TLS1_2",
private_endpoint_connections=[],
key_expiration_period_in_days=None,
location="westeurope",
replication_settings=replication_setting,
)
]
}
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
),
mock.patch(
"prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled.storage_client",
new=storage_client,
),
):
from prowler.providers.azure.services.storage.storage_geo_redundant_enabled.storage_geo_redundant_enabled import (
storage_geo_redundant_enabled,
)
check = storage_geo_redundant_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_SUBSCRIPTION_ID} does not have Geo-redundant storage enabled, it has {replication_setting} instead."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == storage_account_name
@@ -6,7 +6,6 @@ from prowler.providers.azure.services.storage.storage_service import (
DeleteRetentionPolicy,
FileServiceProperties,
NetworkRuleSet,
ReplicationSettings,
SMBProtocolSettings,
Storage,
)
@@ -53,7 +52,7 @@ def mock_storage_get_storage_accounts(_):
location="westeurope",
blob_properties=blob_properties,
default_to_entra_authorization=True,
replication_settings=ReplicationSettings.STANDARD_LRS,
replication_settings="Standard_LRS",
allow_cross_tenant_replication=True,
allow_shared_key_access=True,
file_service_properties=file_service_properties,
@@ -150,7 +149,7 @@ class Test_Storage_Service:
].default_to_entra_authorization
assert (
storage.storage_accounts[AZURE_SUBSCRIPTION_ID][0].replication_settings
== ReplicationSettings.STANDARD_LRS
== "Standard_LRS"
)
assert (
storage.storage_accounts[AZURE_SUBSCRIPTION_ID][