mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
fix(azure): require all SMB channel encryption algorithms to be secure (storage_smb_channel_encryption_with_secure_algorithm) (#11327)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
This commit is contained in:
1 parent
6ca8e726f7
commit
4c59af93eb
7 files changed
+184
-20
No files matched your search
@@ -91,6 +91,7 @@ The following list includes all the Azure checks with configurable variables tha
|
||||
| `sqlserver_recommended_minimal_tls_version` | `recommended_minimal_tls_versions` | List of Strings |
|
||||
| `vm_sufficient_daily_backup_retention_period` | `vm_backup_min_daily_retention_days` | Integer |
|
||||
| `vm_desired_sku_size` | `desired_vm_sku_sizes` | List of Strings |
|
||||
| `storage_smb_channel_encryption_with_secure_algorithm` | `recommended_smb_channel_encryption_algorithms` | List of Strings |
|
||||
| `defender_attack_path_notifications_properly_configured` | `defender_attack_path_minimal_risk_level` | String |
|
||||
| `apim_threat_detection_llm_jacking` | `apim_threat_detection_llm_jacking_threshold` | Float |
|
||||
| `apim_threat_detection_llm_jacking` | `apim_threat_detection_llm_jacking_minutes` | Integer |
|
||||
@@ -534,6 +535,18 @@ azure:
|
||||
"1.3"
|
||||
]
|
||||
|
||||
# Azure Storage
|
||||
# azure.storage_smb_channel_encryption_with_secure_algorithm
|
||||
# List of SMB channel encryption algorithms allowed on file shares. A storage
|
||||
# account passes only if every enabled algorithm is in this list. Defaults to
|
||||
# the value required by CIS (AES-256-GCM only, excluding weaker AES-128 ciphers).
|
||||
recommended_smb_channel_encryption_algorithms:
|
||||
[
|
||||
"AES-256-GCM",
|
||||
# "AES-128-CCM",
|
||||
# "AES-128-GCM",
|
||||
]
|
||||
|
||||
# Azure Virtual Machines
|
||||
# azure.vm_desired_sku_size
|
||||
# List of desired VM SKU sizes that are allowed in the organization
|
||||
|
||||
@@ -10,6 +10,14 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
|
||||
---
|
||||
|
||||
## [5.28.1] (Prowler v5.28.1)
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
- `storage_smb_channel_encryption_with_secure_algorithm` check for Azure provider no longer passes when a storage account allows a weak SMB channel encryption algorithm (e.g. `AES-128-CCM`/`AES-128-GCM`) alongside `AES-256-GCM`; it now requires every enabled algorithm to be in the recommended list, configurable via `azure.recommended_smb_channel_encryption_algorithms` (defaults to `AES-256-GCM` only, as required by CIS) [(#11327)](https://github.com/prowler-cloud/prowler/pull/11327)
|
||||
|
||||
---
|
||||
|
||||
## [5.28.0] (Prowler v5.28.0)
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
@@ -467,6 +467,18 @@ azure:
|
||||
"1.3",
|
||||
]
|
||||
|
||||
# Azure Storage
|
||||
# azure.storage_smb_channel_encryption_with_secure_algorithm
|
||||
# List of SMB channel encryption algorithms allowed on file shares. A storage
|
||||
# account passes only if every enabled algorithm is in this list. Defaults to
|
||||
# the value required by CIS (AES-256-GCM only, excluding weaker AES-128 ciphers).
|
||||
recommended_smb_channel_encryption_algorithms:
|
||||
[
|
||||
"AES-256-GCM",
|
||||
# "AES-128-CCM",
|
||||
# "AES-128-GCM",
|
||||
]
|
||||
|
||||
# Azure Virtual Machines
|
||||
# azure.vm_desired_sku_size
|
||||
# List of desired VM SKU sizes that are allowed in the organization
|
||||
|
||||
+1
-1
@@ -34,5 +34,5 @@
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "This check passes if SMB channel encryption is set to a secure algorithm."
|
||||
"Notes": "This check passes only if every SMB channel encryption algorithm allowed on the file shares is in the recommended list, which is configurable via azure.recommended_smb_channel_encryption_algorithms and defaults to AES-256-GCM only, as required by CIS."
|
||||
}
|
||||
+21
-17
@@ -1,32 +1,38 @@
|
||||
from prowler.lib.check.models import Check, Check_Report_Azure
|
||||
from prowler.providers.azure.services.storage.storage_client import storage_client
|
||||
|
||||
SECURE_ENCRYPTION_ALGORITHMS = ["AES-256-GCM"]
|
||||
DEFAULT_SECURE_ENCRYPTION_ALGORITHMS = ["AES-256-GCM"]
|
||||
|
||||
|
||||
class storage_smb_channel_encryption_with_secure_algorithm(Check):
|
||||
"""
|
||||
Ensure SMB channel encryption for file shares is set to the recommended algorithm (AES-256-GCM or higher).
|
||||
Ensure SMB channel encryption for file shares only allows secure algorithms (AES-256-GCM or higher by default).
|
||||
|
||||
The list of allowed algorithms is configurable via
|
||||
azure.recommended_smb_channel_encryption_algorithms in the Prowler configuration file.
|
||||
|
||||
This check evaluates whether SMB file shares are configured to use only the recommended SMB channel encryption algorithms.
|
||||
- PASS: Storage account has the recommended SMB channel encryption (AES-256-GCM or higher) enabled for file shares.
|
||||
- FAIL: Storage account does not have the recommended SMB channel encryption enabled for file shares or uses an unsupported algorithm.
|
||||
- PASS: Storage account only allows secure SMB channel encryption algorithms for file shares.
|
||||
- FAIL: Storage account does not have SMB channel encryption enabled, or it allows at least one algorithm that is not in the recommended list.
|
||||
"""
|
||||
|
||||
def execute(self) -> list[Check_Report_Azure]:
|
||||
findings = []
|
||||
secure_encryption_algorithms = storage_client.audit_config.get(
|
||||
"recommended_smb_channel_encryption_algorithms",
|
||||
DEFAULT_SECURE_ENCRYPTION_ALGORITHMS,
|
||||
)
|
||||
for subscription, storage_accounts in storage_client.storage_accounts.items():
|
||||
subscription_name = storage_client.subscriptions.get(
|
||||
subscription, subscription
|
||||
)
|
||||
for account in storage_accounts:
|
||||
if account.file_service_properties:
|
||||
channel_encryption = (
|
||||
account.file_service_properties.smb_protocol_settings.channel_encryption
|
||||
)
|
||||
pretty_current_algorithms = (
|
||||
", ".join(
|
||||
account.file_service_properties.smb_protocol_settings.channel_encryption
|
||||
)
|
||||
if account.file_service_properties.smb_protocol_settings.channel_encryption
|
||||
else "none"
|
||||
", ".join(channel_encryption) if channel_encryption else "none"
|
||||
)
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(),
|
||||
@@ -35,20 +41,18 @@ class storage_smb_channel_encryption_with_secure_algorithm(Check):
|
||||
report.subscription = subscription
|
||||
report.resource_name = account.name
|
||||
|
||||
if (
|
||||
not account.file_service_properties.smb_protocol_settings.channel_encryption
|
||||
):
|
||||
if not channel_encryption:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"Storage account {account.name} from subscription {subscription_name} ({subscription}) does not have SMB channel encryption enabled for file shares."
|
||||
elif any(
|
||||
algorithm in SECURE_ENCRYPTION_ALGORITHMS
|
||||
for algorithm in account.file_service_properties.smb_protocol_settings.channel_encryption
|
||||
elif all(
|
||||
algorithm in secure_encryption_algorithms
|
||||
for algorithm in channel_encryption
|
||||
):
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Storage account {account.name} from subscription {subscription_name} ({subscription}) has a secure algorithm for SMB channel encryption ({', '.join(SECURE_ENCRYPTION_ALGORITHMS)}) enabled for file shares since it supports {pretty_current_algorithms}."
|
||||
report.status_extended = f"Storage account {account.name} from subscription {subscription_name} ({subscription}) only allows secure algorithms for SMB channel encryption on file shares since it supports {pretty_current_algorithms}."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"Storage account {account.name} from subscription {subscription_name} ({subscription}) does not have SMB channel encryption with a secure algorithm for file shares since it supports {pretty_current_algorithms}."
|
||||
report.status_extended = f"Storage account {account.name} from subscription {subscription_name} ({subscription}) allows insecure algorithms for SMB channel encryption on file shares since it supports {pretty_current_algorithms} and only {', '.join(secure_encryption_algorithms)} is recommended."
|
||||
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -86,6 +86,7 @@ class TestAzureProvider:
|
||||
"python_latest_version": "3.12",
|
||||
"java_latest_version": "17",
|
||||
"recommended_minimal_tls_versions": ["1.2", "1.3"],
|
||||
"recommended_smb_channel_encryption_algorithms": ["AES-256-GCM"],
|
||||
"vm_backup_min_daily_retention_days": 7,
|
||||
"desired_vm_sku_sizes": [
|
||||
"Standard_A8_v2",
|
||||
|
||||
+128
-2
@@ -20,6 +20,7 @@ class Test_storage_smb_channel_encryption_with_secure_algorithm:
|
||||
def test_no_storage_accounts(self):
|
||||
storage_client = mock.MagicMock()
|
||||
storage_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
storage_client.audit_config = {}
|
||||
storage_client.storage_accounts = {}
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -44,6 +45,7 @@ class Test_storage_smb_channel_encryption_with_secure_algorithm:
|
||||
storage_account_name = "Test Storage Account"
|
||||
storage_client = mock.MagicMock()
|
||||
storage_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
storage_client.audit_config = {}
|
||||
storage_client.storage_accounts = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Account(
|
||||
@@ -97,6 +99,7 @@ class Test_storage_smb_channel_encryption_with_secure_algorithm:
|
||||
)
|
||||
storage_client = mock.MagicMock()
|
||||
storage_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
storage_client.audit_config = {}
|
||||
storage_client.storage_accounts = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Account(
|
||||
@@ -154,6 +157,7 @@ class Test_storage_smb_channel_encryption_with_secure_algorithm:
|
||||
)
|
||||
storage_client = mock.MagicMock()
|
||||
storage_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
storage_client.audit_config = {}
|
||||
storage_client.storage_accounts = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Account(
|
||||
@@ -194,7 +198,7 @@ class Test_storage_smb_channel_encryption_with_secure_algorithm:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == (
|
||||
f"Storage account {storage_account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have SMB channel encryption with a secure algorithm for file shares since it supports AES-128-GCM."
|
||||
f"Storage account {storage_account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} allows insecure algorithms for SMB channel encryption on file shares since it supports AES-128-GCM and only AES-256-GCM is recommended."
|
||||
)
|
||||
|
||||
def test_recommended_encryption(self):
|
||||
@@ -211,6 +215,7 @@ class Test_storage_smb_channel_encryption_with_secure_algorithm:
|
||||
)
|
||||
storage_client = mock.MagicMock()
|
||||
storage_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
storage_client.audit_config = {}
|
||||
storage_client.storage_accounts = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Account(
|
||||
@@ -251,5 +256,126 @@ class Test_storage_smb_channel_encryption_with_secure_algorithm:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"Storage account {storage_account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has a secure algorithm for SMB channel encryption (AES-256-GCM) enabled for file shares since it supports AES-256-GCM."
|
||||
f"Storage account {storage_account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} only allows secure algorithms for SMB channel encryption on file shares since it supports AES-256-GCM."
|
||||
)
|
||||
|
||||
def test_recommended_algorithm_mixed_with_weak_algorithm(self):
|
||||
storage_account_id = str(uuid4())
|
||||
storage_account_name = "Test Storage Account"
|
||||
file_service_properties = FileServiceProperties(
|
||||
id="id1",
|
||||
name="fs1",
|
||||
type="type1",
|
||||
share_delete_retention_policy=DeleteRetentionPolicy(enabled=True, days=7),
|
||||
smb_protocol_settings=SMBProtocolSettings(
|
||||
channel_encryption=["AES-128-CCM", "AES-256-GCM"], supported_versions=[]
|
||||
),
|
||||
)
|
||||
storage_client = mock.MagicMock()
|
||||
storage_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
storage_client.audit_config = {}
|
||||
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",
|
||||
key_expiration_period_in_days=None,
|
||||
location="westeurope",
|
||||
private_endpoint_connections=[],
|
||||
file_service_properties=file_service_properties,
|
||||
)
|
||||
]
|
||||
}
|
||||
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_smb_channel_encryption_with_secure_algorithm.storage_smb_channel_encryption_with_secure_algorithm.storage_client",
|
||||
new=storage_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.storage.storage_smb_channel_encryption_with_secure_algorithm.storage_smb_channel_encryption_with_secure_algorithm import (
|
||||
storage_smb_channel_encryption_with_secure_algorithm,
|
||||
)
|
||||
|
||||
check = storage_smb_channel_encryption_with_secure_algorithm()
|
||||
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_DISPLAY} allows insecure algorithms for SMB channel encryption on file shares since it supports AES-128-CCM, AES-256-GCM and only AES-256-GCM is recommended."
|
||||
)
|
||||
|
||||
def test_custom_recommended_algorithms_from_config(self):
|
||||
storage_account_id = str(uuid4())
|
||||
storage_account_name = "Test Storage Account"
|
||||
file_service_properties = FileServiceProperties(
|
||||
id="id1",
|
||||
name="fs1",
|
||||
type="type1",
|
||||
share_delete_retention_policy=DeleteRetentionPolicy(enabled=True, days=7),
|
||||
smb_protocol_settings=SMBProtocolSettings(
|
||||
channel_encryption=["AES-128-GCM", "AES-256-GCM"], supported_versions=[]
|
||||
),
|
||||
)
|
||||
storage_client = mock.MagicMock()
|
||||
storage_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
storage_client.audit_config = {
|
||||
"recommended_smb_channel_encryption_algorithms": [
|
||||
"AES-128-GCM",
|
||||
"AES-256-GCM",
|
||||
]
|
||||
}
|
||||
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",
|
||||
key_expiration_period_in_days=None,
|
||||
location="westeurope",
|
||||
private_endpoint_connections=[],
|
||||
file_service_properties=file_service_properties,
|
||||
)
|
||||
]
|
||||
}
|
||||
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_smb_channel_encryption_with_secure_algorithm.storage_smb_channel_encryption_with_secure_algorithm.storage_client",
|
||||
new=storage_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.storage.storage_smb_channel_encryption_with_secure_algorithm.storage_smb_channel_encryption_with_secure_algorithm import (
|
||||
storage_smb_channel_encryption_with_secure_algorithm,
|
||||
)
|
||||
|
||||
check = storage_smb_channel_encryption_with_secure_algorithm()
|
||||
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_DISPLAY} only allows secure algorithms for SMB channel encryption on file shares since it supports AES-128-GCM, AES-256-GCM."
|
||||
)
|
||||
Reference in new issue
Block a user