diff --git a/scanner/rules/az_stor_006.py b/scanner/rules/az_stor_006.py new file mode 100644 index 0000000..c8181a1 --- /dev/null +++ b/scanner/rules/az_stor_006.py @@ -0,0 +1,41 @@ +""" +Rule ID: AZ-STORAGE-HTTPS-001 +Title: Storage Account HTTPS Enforcement +Severity: HIGH +Category: Storage +Description: Detects Azure Storage Accounts that do not enforce HTTPS-only traffic. +""" + +def get_storage_accounts(subscription_id): + """ + Placeholder. The scanner engine will inject real storage accounts. + Tests will mock this function. + """ + raise NotImplementedError("Scanner engine must provide storage accounts") + +def scan(subscription_id): + """ + Scans all Storage Accounts in the given subscription + and returns those that do NOT enforce HTTPS-only. + """ + + storage_accounts = get_storage_accounts(subscription_id) + findings = [] + + for account in storage_accounts: + props = account.get("properties", {}) + https_only = props.get("supportsHttpsTrafficOnly", True) + + if not https_only: + findings.append({ + "id": "AZ-STORAGE-HTTPS-001", + "resource_id": account.get("id"), + "resource_name": account.get("name"), + "resource_group": account.get("resourceGroup"), + "subscription_id": subscription_id, + "severity": "HIGH", + "category": "Storage", + "description": "Storage Account does not enforce HTTPS-only traffic.", + }) + + return findings diff --git a/tests/test_az_stor_006.py b/tests/test_az_stor_006.py new file mode 100644 index 0000000..ea7ad1a --- /dev/null +++ b/tests/test_az_stor_006.py @@ -0,0 +1,49 @@ +import unittest +import scanner.rules.az_stor_006 as rule + +class TestStorageHttpsRule(unittest.TestCase): + + def test_storage_https_disabled(self): + # Mock storage accounts + def mock_list_storage_accounts(subscription_id): + return [ + { + "id": "/subscriptions/test-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/teststorage", + "name": "teststorage", + "resourceGroup": "rg", + "properties": { + "supportsHttpsTrafficOnly": False + } + } + ] + + # Patch the function inside the rule + rule.get_storage_accounts = mock_list_storage_accounts + + findings = rule.scan("test-sub") + + self.assertEqual(len(findings), 1) + self.assertEqual(findings[0]["id"], "AZ-STORAGE-HTTPS-001") + self.assertEqual(findings[0]["severity"], "HIGH") + + def test_storage_https_enabled(self): + def mock_list_storage_accounts(subscription_id): + return [ + { + "id": "/subscriptions/test-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/teststorage", + "name": "teststorage", + "resourceGroup": "rg", + "properties": { + "supportsHttpsTrafficOnly": True + } + } + ] + + rule.get_storage_accounts = mock_list_storage_accounts + + findings = rule.scan("test-sub") + + self.assertEqual(findings, []) + +if __name__ == "__main__": + unittest.main()