From c23932d1d37fc4cdc8295d89cb2ad3d7425ada4d Mon Sep 17 00:00:00 2001 From: chaniglik <154279386+chaniglik@users.noreply.github.com> Date: Sun, 19 May 2024 09:02:22 +0300 Subject: [PATCH] feat(arm): MSSQLServerMinTLSVersion (#6245) * MSSQLServerMinTLSVersion * MSSQLServerMinTLSVersion * MSSQLServerMinTLSVersion * fix MSSQLServerMinTLSVersion * fix2 MSSQLServerMinTLSVersion --------- Co-authored-by: ChanochShayner <57212002+ChanochShayner@users.noreply.github.com> --- .../resource/MSSQLServerMinTLSVersion.py | 24 ++ .../fail.json | 246 ++++++++++++++++++ .../pass.json | 246 ++++++++++++++++++ .../resource/test_MSSQLServerMinTLSVersion.py | 42 +++ 4 files changed, 558 insertions(+) create mode 100644 checkov/arm/checks/resource/MSSQLServerMinTLSVersion.py create mode 100644 tests/arm/checks/resource/example_MSSQLServerMinTLSVersion/fail.json create mode 100644 tests/arm/checks/resource/example_MSSQLServerMinTLSVersion/pass.json create mode 100644 tests/arm/checks/resource/test_MSSQLServerMinTLSVersion.py diff --git a/checkov/arm/checks/resource/MSSQLServerMinTLSVersion.py b/checkov/arm/checks/resource/MSSQLServerMinTLSVersion.py new file mode 100644 index 00000000000..55669a57f29 --- /dev/null +++ b/checkov/arm/checks/resource/MSSQLServerMinTLSVersion.py @@ -0,0 +1,24 @@ +from checkov.common.models.enums import CheckCategories, CheckResult +from checkov.arm.base_resource_value_check import BaseResourceValueCheck + + +class MSSQLServerMinTLSVersion(BaseResourceValueCheck): + def __init__(self) -> None: + name = "Ensure MSSQL is using the latest version of TLS encryption" + id = "CKV_AZURE_52" + supported_resources = ("Microsoft.Sql/servers",) + categories = (CheckCategories.NETWORKING,) + super().__init__(name=name, + id=id, + categories=categories, + supported_resources=supported_resources, + missing_block_result=CheckResult.FAILED,) + + def get_inspected_key(self) -> str: + return "properties/minimalTlsVersion" + + def get_expected_value(self) -> str: + return "1.2" + + +check = MSSQLServerMinTLSVersion() diff --git a/tests/arm/checks/resource/example_MSSQLServerMinTLSVersion/fail.json b/tests/arm/checks/resource/example_MSSQLServerMinTLSVersion/fail.json new file mode 100644 index 00000000000..34dcc4540d4 --- /dev/null +++ b/tests/arm/checks/resource/example_MSSQLServerMinTLSVersion/fail.json @@ -0,0 +1,246 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "apiVersion": { + "type": "string", + "defaultValue": "2021-05-01" + }, + "administratorLogin": { + "type": "string" + }, + "administratorLoginPassword": { + "type": "securestring" + }, + "location": { + "type": "string" + }, + "serverName": { + "type": "string" + }, + "serverEdition": { + "type": "string" + }, + "vCores": { + "type": "int", + "defaultValue": 4 + }, + "storageSizeGB": { + "type": "int" + }, + "haEnabled": { + "type": "string", + "defaultValue": "Disabled" + }, + "availabilityZone": { + "type": "string", + "defaultValue": "" + }, + "standbyAvailabilityZone": { + "type": "string" + }, + "version": { + "type": "string" + }, + "tags": { + "type": "object", + "defaultValue": {} + }, + "firewallRules": { + "type": "object", + "defaultValue": {} + }, + "backupRetentionDays": { + "type": "int" + }, + "geoRedundantBackup": { + "type": "string" + }, + "vmName": { + "type": "string", + "defaultValue": "Standard_B1ms" + }, + "storageIops": { + "type": "int" + }, + "storageAutogrow": { + "type": "string", + "defaultValue": "Enabled" + }, + "autoIoScaling": { + "type": "string", + "defaultValue": "Disabled" + }, + "identityData": { + "type": "object", + "defaultValue": {} + }, + "dataEncryptionData": { + "type": "object", + "defaultValue": {} + }, + "serverParameters": { + "type": "array", + "defaultValue": [] + }, + "aadEnabled": { + "type": "bool", + "defaultValue": false + }, + "aadData": { + "type": "object", + "defaultValue": {} + }, + "guid": { + "type": "string", + "defaultValue": "[newGuid()]" + }, + "network": { + "type": "object", + "defaultValue": {} + }, + "firewallRulesAPIVersion": { + "type": "string", + "defaultValue": "2022-01-01" + } + }, + "variables": { + "api": "[parameters('apiVersion')]", + "firewallRules": "[parameters('firewallRules').rules]", + "serverParameters": "[parameters('serverParameters')]" + }, + "resources": [ + { + "type": "Microsoft.Sql/servers", + "apiVersion": "2023-05-01-preview", + "name": "fail", + "location": "string", + "tags": { + "tagName1": "tagValue1", + "tagName2": "tagValue2" + }, + "identity": { + "type": "string", + "userAssignedIdentities": { + "{customized property}": {} + } + }, + "properties": { + "administratorLogin": "string", + "administratorLoginPassword": "string", + "administrators": { + "administratorType": "ActiveDirectory", + "azureADOnlyAuthentication": "bool", + "login": "string", + "principalType": "string", + "sid": "string", + "tenantId": "string" + }, + "federatedClientId": "string", + "isIPv6Enabled": "string", + "keyId": "string", + "minimalTlsVersion": "1.1", + "primaryUserAssignedIdentityId": "string", + "publicNetworkAccess": "string", + "restrictOutboundNetworkAccess": "string", + "version": "string" + } + }, + { + "condition": "[greater(length(variables('firewallRules')), 0)]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-08-01", + "name": "[concat('firewallRules-', parameters('guid'), '-', copyIndex())]", + "copy": { + "count": "[if(greater(length(variables('firewallRules')), 0), length(variables('firewallRules')), 1)]", + "mode": "Serial", + "name": "firewallRulesIterator" + }, + "dependsOn": [ + "[concat('Microsoft.DBforMySQL/flexibleServers/', parameters('serverName'))]", + "[concat('Microsoft.Resources/deployments/addAdmins-', parameters('guid'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.DBforMySQL/flexibleServers/firewallRules", + "name": "[concat(parameters('serverName'),'/',variables('firewallRules')[copyIndex()].name)]", + "apiVersion": "[parameters('firewallRulesAPIVersion')]", + "properties": { + "StartIpAddress": "[variables('firewallRules')[copyIndex()].startIPAddress]", + "EndIpAddress": "[variables('firewallRules')[copyIndex()].endIPAddress]" + } + } + ] + } + } + }, + { + "condition": "[parameters('aadEnabled')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-08-01", + "name": "[concat('addAdmins-', parameters('guid'))]", + "dependsOn": [ + "[concat('Microsoft.DBforMySQL/flexibleServers/', parameters('serverName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.DBforMySQL/flexibleServers/administrators", + "name": "[concat(parameters('serverName'),'/ActiveDirectory')]", + "apiVersion": "[variables('api')]", + "properties": { + "administratorType": "[parameters('aadData').administratorType]", + "identityResourceId": "[parameters('aadData').identityResourceId]", + "login": "[parameters('aadData').login]", + "sid": "[parameters('aadData').sid]", + "tenantId": "[parameters('aadData').tenantId]" + } + } + ] + } + } + }, + { + "condition": "[and(greater(length(variables('serverParameters')), 0), parameters('aadEnabled'))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-08-01", + "copy": { + "count": "[if(greater(length(variables('serverParameters')), 0), length(variables('serverParameters')), 1)]", + "mode": "serial", + "name": "serverParametersIterator" + }, + "dependsOn": [ + "[concat('Microsoft.DBforMySQL/flexibleServers/', parameters('serverName'))]", + "[concat('Microsoft.Resources/deployments/addAdmins-', parameters('guid'))]" + ], + "name": "[concat('serverParameters-', copyIndex(), '-', parameters('guid'))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.DBforMySQL/flexibleServers/configurations", + "name": "[concat(parameters('serverName'),'/',variables('serverParameters')[copyIndex()].name)]", + "apiVersion": "[variables('api')]", + "properties": { + "value": "[variables('serverParameters')[copyIndex()].value]", + "source": "[variables('serverParameters')[copyIndex()].source]" + } + } + ] + } + } + } + ] +} diff --git a/tests/arm/checks/resource/example_MSSQLServerMinTLSVersion/pass.json b/tests/arm/checks/resource/example_MSSQLServerMinTLSVersion/pass.json new file mode 100644 index 00000000000..5244f95722e --- /dev/null +++ b/tests/arm/checks/resource/example_MSSQLServerMinTLSVersion/pass.json @@ -0,0 +1,246 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "apiVersion": { + "type": "string", + "defaultValue": "2021-05-01" + }, + "administratorLogin": { + "type": "string" + }, + "administratorLoginPassword": { + "type": "securestring" + }, + "location": { + "type": "string" + }, + "serverName": { + "type": "string" + }, + "serverEdition": { + "type": "string" + }, + "vCores": { + "type": "int", + "defaultValue": 4 + }, + "storageSizeGB": { + "type": "int" + }, + "haEnabled": { + "type": "string", + "defaultValue": "Disabled" + }, + "availabilityZone": { + "type": "string", + "defaultValue": "" + }, + "standbyAvailabilityZone": { + "type": "string" + }, + "version": { + "type": "string" + }, + "tags": { + "type": "object", + "defaultValue": {} + }, + "firewallRules": { + "type": "object", + "defaultValue": {} + }, + "backupRetentionDays": { + "type": "int" + }, + "geoRedundantBackup": { + "type": "string" + }, + "vmName": { + "type": "string", + "defaultValue": "Standard_B1ms" + }, + "storageIops": { + "type": "int" + }, + "storageAutogrow": { + "type": "string", + "defaultValue": "Enabled" + }, + "autoIoScaling": { + "type": "string", + "defaultValue": "Disabled" + }, + "identityData": { + "type": "object", + "defaultValue": {} + }, + "dataEncryptionData": { + "type": "object", + "defaultValue": {} + }, + "serverParameters": { + "type": "array", + "defaultValue": [] + }, + "aadEnabled": { + "type": "bool", + "defaultValue": false + }, + "aadData": { + "type": "object", + "defaultValue": {} + }, + "guid": { + "type": "string", + "defaultValue": "[newGuid()]" + }, + "network": { + "type": "object", + "defaultValue": {} + }, + "firewallRulesAPIVersion": { + "type": "string", + "defaultValue": "2022-01-01" + } + }, + "variables": { + "api": "[parameters('apiVersion')]", + "firewallRules": "[parameters('firewallRules').rules]", + "serverParameters": "[parameters('serverParameters')]" + }, + "resources": [ + { + "type": "Microsoft.Sql/servers", + "apiVersion": "2023-05-01-preview", + "name": "pass", + "location": "string", + "tags": { + "tagName1": "tagValue1", + "tagName2": "tagValue2" + }, + "identity": { + "type": "string", + "userAssignedIdentities": { + "{customized property}": {} + } + }, + "properties": { + "administratorLogin": "string", + "administratorLoginPassword": "string", + "administrators": { + "administratorType": "ActiveDirectory", + "azureADOnlyAuthentication": "bool", + "login": "string", + "principalType": "string", + "sid": "string", + "tenantId": "string" + }, + "federatedClientId": "string", + "isIPv6Enabled": "string", + "keyId": "string", + "minimalTlsVersion": "1.2", + "primaryUserAssignedIdentityId": "string", + "publicNetworkAccess": "string", + "restrictOutboundNetworkAccess": "string", + "version": "string" + } + }, + { + "condition": "[greater(length(variables('firewallRules')), 0)]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-08-01", + "name": "[concat('firewallRules-', parameters('guid'), '-', copyIndex())]", + "copy": { + "count": "[if(greater(length(variables('firewallRules')), 0), length(variables('firewallRules')), 1)]", + "mode": "Serial", + "name": "firewallRulesIterator" + }, + "dependsOn": [ + "[concat('Microsoft.DBforMySQL/flexibleServers/', parameters('serverName'))]", + "[concat('Microsoft.Resources/deployments/addAdmins-', parameters('guid'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.DBforMySQL/flexibleServers/firewallRules", + "name": "[concat(parameters('serverName'),'/',variables('firewallRules')[copyIndex()].name)]", + "apiVersion": "[parameters('firewallRulesAPIVersion')]", + "properties": { + "StartIpAddress": "[variables('firewallRules')[copyIndex()].startIPAddress]", + "EndIpAddress": "[variables('firewallRules')[copyIndex()].endIPAddress]" + } + } + ] + } + } + }, + { + "condition": "[parameters('aadEnabled')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-08-01", + "name": "[concat('addAdmins-', parameters('guid'))]", + "dependsOn": [ + "[concat('Microsoft.DBforMySQL/flexibleServers/', parameters('serverName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.DBforMySQL/flexibleServers/administrators", + "name": "[concat(parameters('serverName'),'/ActiveDirectory')]", + "apiVersion": "[variables('api')]", + "properties": { + "administratorType": "[parameters('aadData').administratorType]", + "identityResourceId": "[parameters('aadData').identityResourceId]", + "login": "[parameters('aadData').login]", + "sid": "[parameters('aadData').sid]", + "tenantId": "[parameters('aadData').tenantId]" + } + } + ] + } + } + }, + { + "condition": "[and(greater(length(variables('serverParameters')), 0), parameters('aadEnabled'))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-08-01", + "copy": { + "count": "[if(greater(length(variables('serverParameters')), 0), length(variables('serverParameters')), 1)]", + "mode": "serial", + "name": "serverParametersIterator" + }, + "dependsOn": [ + "[concat('Microsoft.DBforMySQL/flexibleServers/', parameters('serverName'))]", + "[concat('Microsoft.Resources/deployments/addAdmins-', parameters('guid'))]" + ], + "name": "[concat('serverParameters-', copyIndex(), '-', parameters('guid'))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.DBforMySQL/flexibleServers/configurations", + "name": "[concat(parameters('serverName'),'/',variables('serverParameters')[copyIndex()].name)]", + "apiVersion": "[variables('api')]", + "properties": { + "value": "[variables('serverParameters')[copyIndex()].value]", + "source": "[variables('serverParameters')[copyIndex()].source]" + } + } + ] + } + } + } + ] +} diff --git a/tests/arm/checks/resource/test_MSSQLServerMinTLSVersion.py b/tests/arm/checks/resource/test_MSSQLServerMinTLSVersion.py new file mode 100644 index 00000000000..724892efbf7 --- /dev/null +++ b/tests/arm/checks/resource/test_MSSQLServerMinTLSVersion.py @@ -0,0 +1,42 @@ +import unittest +from pathlib import Path + +from checkov.arm.checks.resource.MSSQLServerMinTLSVersion import check +from checkov.arm.runner import Runner +from checkov.runner_filter import RunnerFilter + + +class TestMSSQLServerMinTLSVersion(unittest.TestCase): + + def test_summary(self): + # given + test_files_dir = Path(__file__).parent / "example_MSSQLServerMinTLSVersion" + + # when + report = Runner().run(root_folder=str(test_files_dir), runner_filter=RunnerFilter(checks=[check.id])) + + # then + summary = report.get_summary() + + passing_resources = { + "Microsoft.Sql/servers.pass" + } + + failing_resources = { + "Microsoft.Sql/servers.fail" + } + + passed_check_resources = {c.resource for c in report.passed_checks} + failed_check_resources = {c.resource for c in report.failed_checks} + + self.assertEqual(summary["passed"], len(passing_resources)) + self.assertEqual(summary["failed"], len(failing_resources)) + self.assertEqual(summary["skipped"], 0) + self.assertEqual(summary["parsing_errors"], 0) + + self.assertSetEqual(passing_resources, passed_check_resources) + self.assertSetEqual(failing_resources, failed_check_resources) + + +if __name__ == "__main__": + unittest.main()