feat(azure): check for minimal TLS version for Azure SQL server (#5745)

Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
This commit is contained in:
johannes-engler-mw
2024-12-11 16:37:53 +01:00
committed by GitHub
parent fdb1956b0b
commit eded97d735
9 changed files with 299 additions and 0 deletions
+9
View File
@@ -75,6 +75,7 @@ The following list includes all the Azure checks with configurable variables tha
| `app_ensure_php_version_is_latest` | `php_latest_version` | String |
| `app_ensure_python_version_is_latest` | `python_latest_version` | String |
| `app_ensure_java_version_is_latest` | `java_latest_version` | String |
| `sqlserver_recommended_minimal_tls_version` | `recommended_minimal_tls_versions` | List of Strings |
## GCP
@@ -447,6 +448,14 @@ azure:
# azure.app_ensure_java_version_is_latest
java_latest_version: "17"
# Azure SQL Server
# azure.sqlserver_minimal_tls_version
recommended_minimal_tls_versions:
[
"1.2",
"1.3"
]
# GCP Configuration
gcp:
# GCP Compute Configuration
+8
View File
@@ -388,6 +388,14 @@ azure:
# azure.app_ensure_java_version_is_latest
java_latest_version: "17"
# Azure SQL Server
# azure.sqlserver_minimal_tls_version
recommended_minimal_tls_versions:
[
"1.2",
"1.3",
]
# GCP Configuration
gcp:
# GCP Compute Configuration
@@ -0,0 +1,30 @@
{
"Provider": "azure",
"CheckID": "sqlserver_recommended_minimal_tls_version",
"CheckTitle": "Ensure SQL server has a recommended minimal TLS version required.",
"CheckType": [],
"ServiceName": "sqlserver",
"SubServiceName": "",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "SQLServer",
"Description": "Ensure that SQL Server instances are configured with the recommended minimal TLS version to maintain secure connections.",
"Risk": "Using outdated or weak TLS versions can expose SQL Server instances to vulnerabilities, increasing the risk of data breaches and unauthorized access.",
"RelatedUrl": "https://learn.microsoft.com/en-us/azure/azure-sql/database/connectivity-settings?view=azuresql&tabs=azure-portal#configure-minimum-tls-version",
"Remediation": {
"Code": {
"CLI": "az sql server update -n sql-server-name -g sql-server-group --set minimalTlsVersion=<version>",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "1. Go to Azure SQL Server 2. Navigate to 'Security' -> 'Networking' 3. Select 'Connectivity' 4. Update the TLS version in the field 'Minimum TLS version' to a recommended minimal version (e.g., TLS 1.2).",
"Url": "https://learn.microsoft.com/en-us/azure/azure-sql/database/connectivity-settings?view=azuresql&tabs=azure-portal#configure-minimum-tls-version"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Verify support for the TLS version from the application side before changing the minimal version."
}
@@ -0,0 +1,27 @@
from typing import List
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.sqlserver.sqlserver_client import sqlserver_client
class sqlserver_recommended_minimal_tls_version(Check):
def execute(self) -> List[Check_Report_Azure]:
findings = []
recommended_minimal_tls_versions = sqlserver_client.audit_config.get(
"recommended_minimal_tls_versions", ["1.2", "1.3"]
)
for subscription, sql_servers in sqlserver_client.sql_servers.items():
for sql_server in sql_servers:
report = Check_Report_Azure(self.metadata())
report.subscription = subscription
report.resource_name = sql_server.name
report.resource_id = sql_server.id
report.status = "FAIL"
report.location = sql_server.location
report.status_extended = f"SQL Server {sql_server.name} from subscription {subscription} is using TLS version {sql_server.minimal_tls_version} as minimal accepted which is not recommended. Please use one of the recommended versions: {', '.join(recommended_minimal_tls_versions)}."
if sql_server.minimal_tls_version in recommended_minimal_tls_versions:
report.status_extended = f"SQL Server {sql_server.name} from subscription {subscription} is using version {sql_server.minimal_tls_version} as minimal accepted which is recommended."
report.status = "PASS"
findings.append(report)
return findings
+1
View File
@@ -318,6 +318,7 @@ config_azure = {
"php_latest_version": "8.2",
"python_latest_version": "3.12",
"java_latest_version": "17",
"recommended_minimal_tls_versions": ["1.2", "1.3"],
}
config_gcp = {"shodan_api_key": None}
+8
View File
@@ -379,6 +379,14 @@ azure:
# azure.app_ensure_java_version_is_latest
java_latest_version: "17"
# Azure SQL Server
# azure.sqlserver_minimal_tls_version
recommended_minimal_tls_versions:
[
"1.2",
"1.3"
]
# GCP Configuration
gcp:
# GCP Compute Configuration
@@ -81,6 +81,7 @@ class TestAzureProvider:
"php_latest_version": "8.2",
"python_latest_version": "3.12",
"java_latest_version": "17",
"recommended_minimal_tls_versions": ["1.2", "1.3"],
}
def test_azure_provider_not_auth_methods(self):
@@ -0,0 +1,215 @@
from unittest import mock
from uuid import uuid4
from azure.mgmt.sql.models import TransparentDataEncryption
from prowler.providers.azure.services.sqlserver.sqlserver_service import (
Database,
Server,
)
from tests.providers.azure.azure_fixtures import (
AZURE_SUBSCRIPTION_ID,
set_mocked_azure_provider,
)
class Test_sqlserver_recommended_minimal_tls_version:
def test_no_sql_servers(self):
sqlserver_client = mock.MagicMock
sqlserver_client.sql_servers = {}
with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
), mock.patch(
"prowler.providers.azure.services.sqlserver.sqlserver_recommended_minimal_tls_version.sqlserver_recommended_minimal_tls_version.sqlserver_client",
new=sqlserver_client,
):
from prowler.providers.azure.services.sqlserver.sqlserver_recommended_minimal_tls_version.sqlserver_recommended_minimal_tls_version import (
sqlserver_recommended_minimal_tls_version,
)
sqlserver_client.audit_config = {
"recommended_minimal_tls_versions": ["1.2", "1.3"]
}
check = sqlserver_recommended_minimal_tls_version()
result = check.execute()
assert len(result) == 0
def test_sql_servers_deprecated_minimal_tls_version(self):
sqlserver_client = mock.MagicMock
sql_server_name = "SQL Server Name"
sql_server_id = str(uuid4())
database_name = "Database Name"
database_id = str(uuid4())
database = Database(
id=database_id,
name=database_name,
type="type",
location="location",
managed_by="managed_by",
tde_encryption=TransparentDataEncryption(status="Disabled"),
)
sqlserver_client.sql_servers = {
AZURE_SUBSCRIPTION_ID: [
Server(
id=sql_server_id,
name=sql_server_name,
public_network_access="",
minimal_tls_version="1.0",
administrators=None,
auditing_policies=None,
firewall_rules=None,
databases=[database],
encryption_protector=None,
location="location",
)
]
}
with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
), mock.patch(
"prowler.providers.azure.services.sqlserver.sqlserver_recommended_minimal_tls_version.sqlserver_recommended_minimal_tls_version.sqlserver_client",
new=sqlserver_client,
):
from prowler.providers.azure.services.sqlserver.sqlserver_recommended_minimal_tls_version.sqlserver_recommended_minimal_tls_version import (
sqlserver_recommended_minimal_tls_version,
)
sqlserver_client.audit_config = {
"recommended_minimal_tls_versions": ["1.2", "1.3"]
}
check = sqlserver_recommended_minimal_tls_version()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"SQL Server {sql_server_name} from subscription {AZURE_SUBSCRIPTION_ID} is using TLS version 1.0 as minimal accepted which is not recommended. Please use one of the recommended versions: {', '.join(sqlserver_client.audit_config['recommended_minimal_tls_versions'])}."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == sql_server_name
assert result[0].resource_id == sql_server_id
assert result[0].location == "location"
def test_sql_servers_no_minimal_tls_version(self):
sqlserver_client = mock.MagicMock
sql_server_name = "SQL Server Name"
sql_server_id = str(uuid4())
database_name = "Database Name"
database_id = str(uuid4())
database = Database(
id=database_id,
name=database_name,
type="type",
location="location",
managed_by="managed_by",
tde_encryption=TransparentDataEncryption(status="Disabled"),
)
sqlserver_client.sql_servers = {
AZURE_SUBSCRIPTION_ID: [
Server(
id=sql_server_id,
name=sql_server_name,
public_network_access="",
minimal_tls_version="",
administrators=None,
auditing_policies=None,
firewall_rules=None,
databases=[database],
encryption_protector=None,
location="location",
)
]
}
with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
), mock.patch(
"prowler.providers.azure.services.sqlserver.sqlserver_recommended_minimal_tls_version.sqlserver_recommended_minimal_tls_version.sqlserver_client",
new=sqlserver_client,
):
from prowler.providers.azure.services.sqlserver.sqlserver_recommended_minimal_tls_version.sqlserver_recommended_minimal_tls_version import (
sqlserver_recommended_minimal_tls_version,
)
sqlserver_client.audit_config = {
"recommended_minimal_tls_versions": ["1.2", "1.3"]
}
check = sqlserver_recommended_minimal_tls_version()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"SQL Server {sql_server_name} from subscription {AZURE_SUBSCRIPTION_ID} is using TLS version as minimal accepted which is not recommended. Please use one of the recommended versions: {', '.join(sqlserver_client.audit_config['recommended_minimal_tls_versions'])}."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == sql_server_name
assert result[0].resource_id == sql_server_id
assert result[0].location == "location"
def test_sql_servers_minimal_tls_version(self):
sqlserver_client = mock.MagicMock
sql_server_name = "SQL Server Name"
sql_server_id = str(uuid4())
database_name = "Database Name"
database_id = str(uuid4())
database = Database(
id=database_id,
name=database_name,
type="type",
location="location",
managed_by="managed_by",
tde_encryption=TransparentDataEncryption(status="Enabled"),
)
sqlserver_client.sql_servers = {
AZURE_SUBSCRIPTION_ID: [
Server(
id=sql_server_id,
name=sql_server_name,
public_network_access="",
minimal_tls_version="1.2",
administrators=None,
auditing_policies=None,
firewall_rules=None,
databases=[database],
encryption_protector=None,
location="location",
)
]
}
with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
), mock.patch(
"prowler.providers.azure.services.sqlserver.sqlserver_recommended_minimal_tls_version.sqlserver_recommended_minimal_tls_version.sqlserver_client",
new=sqlserver_client,
):
from prowler.providers.azure.services.sqlserver.sqlserver_recommended_minimal_tls_version.sqlserver_recommended_minimal_tls_version import (
sqlserver_recommended_minimal_tls_version,
)
sqlserver_client.audit_config = {
"recommended_minimal_tls_versions": ["1.2", "1.3"]
}
check = sqlserver_recommended_minimal_tls_version()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"SQL Server {sql_server_name} from subscription {AZURE_SUBSCRIPTION_ID} is using version 1.2 as minimal accepted which is recommended."
)
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
assert result[0].resource_name == sql_server_name
assert result[0].resource_id == sql_server_id
assert result[0].location == "location"