diff --git a/checkov/arm/checks/resource/AzureDefenderOnStorage.py b/checkov/arm/checks/resource/AzureDefenderOnStorage.py new file mode 100644 index 00000000000..ebc2f4ba81a --- /dev/null +++ b/checkov/arm/checks/resource/AzureDefenderOnStorage.py @@ -0,0 +1,27 @@ +from typing import Any, Dict, List +from checkov.common.models.enums import CheckCategories, CheckResult +from checkov.arm.base_resource_check import BaseResourceCheck + + +class AzureDefenderOnStorage(BaseResourceCheck): + def __init__(self) -> None: + name = "Ensure that Azure Defender is set to On for Storage" + id = "CKV_AZURE_84" + supported_resources = ("Microsoft.Security/pricings",) + categories = (CheckCategories.GENERAL_SECURITY,) + super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources) + + def scan_resource_conf(self, conf: Dict[str, Any]) -> CheckResult: + properties: Dict[str, Any] = conf.get("properties", {}) + pricingTier = properties.get("pricingTier", "") + return ( + CheckResult.PASSED + if pricingTier == "Standard" + else CheckResult.FAILED + ) + + def get_evaluated_keys(self) -> List[str]: + return ["properties/pricingTier"] + + +check = AzureDefenderOnStorage() diff --git a/tests/arm/checks/resource/example_AzureDefenderOnStorage/fail.json b/tests/arm/checks/resource/example_AzureDefenderOnStorage/fail.json new file mode 100644 index 00000000000..d75a866210a --- /dev/null +++ b/tests/arm/checks/resource/example_AzureDefenderOnStorage/fail.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Security/pricings", + "apiVersion": "2018-06-01", + "name": "fail", + "properties": { + "pricingTier": "Free", + "resourceType": "Microsoft.Security/pricings" + } + } + ] +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_AzureDefenderOnStorage/pass.json b/tests/arm/checks/resource/example_AzureDefenderOnStorage/pass.json new file mode 100644 index 00000000000..e7cf4f13566 --- /dev/null +++ b/tests/arm/checks/resource/example_AzureDefenderOnStorage/pass.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Security/pricings", + "apiVersion": "2018-06-01", + "name": "pass", + "properties": { + "pricingTier": "Standard", + "resourceType": "Microsoft.Security/pricings" + } + } + ] +} \ No newline at end of file diff --git a/tests/arm/checks/resource/test_AzureDefenderOnStorage.py b/tests/arm/checks/resource/test_AzureDefenderOnStorage.py new file mode 100644 index 00000000000..015826b2750 --- /dev/null +++ b/tests/arm/checks/resource/test_AzureDefenderOnStorage.py @@ -0,0 +1,33 @@ +import unittest +from checkov.arm.checks.resource.AzureDefenderOnStorage import check +from pathlib import Path +from checkov.arm.runner import Runner +from checkov.runner_filter import RunnerFilter + + +class TestAzureDefenderOnStorage(unittest.TestCase): + def test_summary(self): + test_files_dir = Path(__file__).parent / "example_AzureDefenderOnStorage" + report = Runner().run(root_folder=str(test_files_dir), runner_filter=RunnerFilter(checks=[check.id])) + summary = report.get_summary() + passing_resources = { + "Microsoft.Security/pricings.pass", + } + failing_resources = { + "Microsoft.Security/pricings.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.assertEqual(passed_check_resources, passing_resources) + self.assertEqual(failed_check_resources, failing_resources) + + +if __name__ == '__main__': + unittest.main()